Skip to content

T-913K-friction-incident-log-infrastructure

Status: closed/superseded · Impact: medium · Complexity: large

The SDLC protocol’s friction-tracking story today is “post-mortems in task files.” That captures per-task friction beautifully but makes cross-task patterns invisible: when something fails for the third time in a row, we have to spelunk three post-mortems by hand to notice. The proposed remedy is a structured incident log — every time a /sdlc:task-work, /sdlc:task-close-out, /sdlc:pr-respond, or other lifecycle skill hits a known failure mode (API socket close, lease conflict, quality-gate false positive, worktree path mismatch, etc.), a record gets written to .sdlc/incidents/. The log is queryable: “show me every API-socket-close in the last 30 days” becomes one command, not a manual diff across post-mortems. Future task-spawning decisions reach for data instead of vibes — the threshold for “this is worth fixing” moves from “I noticed it once” to “this is the N-th occurrence in M runs.”

The triggering moment was T-JXBQ-task-work-warns-on-long-sub-agent-prompt: one sub-agent crashed with API Error: socket connection closed unexpectedly, and the spawned-task proposed adding a prompt-length warning. The user pushed back: with one data point, we can’t tell whether prompt length was the cause vs. flaky API vs. model timeout. Without evidence, the fix is speculation. This task builds the substrate that makes evidence available.

LocationRole today
.sdlc/incidents/Does not exist.
apps/sdlc/skills/*/SKILL.md post-mortem sectionThe only friction-capture mechanism today. Captures per-task; cross-task patterns are invisible.
apps/sdlc/lib/services/lease/reconcile.tsDetects active anomalies in current state (dangling leases, missing PRs, etc.). Doesn’t capture historical friction — it’s a snapshot, not a timeseries.
apps/sdlc/skills/task-work/SKILL.md failure pathsWhen a sub-agent crashes, lease transition fails, quality gate hits false positives, etc., the skill surfaces the error to the user but doesn’t write any structured record.

A new shared incident-logging substrate at apps/sdlc/lib/services/incidents/ (library) and .sdlc/incidents/ (per-project storage). Each incident is a structured record (YAML or JSON) capturing:

  • Timestamp (UTC, ISO 8601)
  • Class (one of an enumerated taxonomy — see below)
  • Context (task ID, skill name, git SHA, free-form details)
  • Resolution (if known at capture time — “user retried”, “fixed by re-baseline”, “wontdo”, etc.)

Auto-capture from skill failure paths where feasible. The operator can also record incidents manually via a /sdlc:incident skill for things the protocol didn’t auto-catch.

A surface for querying — a registry op with subcommands (list, summary, class <name>), under its own noun or an existing one per D-H7FS-op-substrate-surface, or growth in the lease reconcile reporter to include “incidents this period” alongside its anomaly views.

Initial taxonomy (to be refined during research):

  • api-socket-close — sub-agent or skill dispatch died with a socket-close error
  • subagent-crash — sub-agent returned an error verdict
  • lease-conflict — Step 2a’s acquire lost the CAS race
  • lease-stolen — reacquire took an expired lease
  • quality-gate-false-positive — gate fired on baseline-shift summary lines
  • worktree-path-mismatch — script wrote to or read from the wrong .sdlc/ directory
  • start-task-cache-miss — historical; obsoleted by the lease-cache drop
  • spec-pr-blocks-impl — historical; obsoleted by the Step 2 branch-prefix fix
  • manual — operator-recorded, no automated class fits

The taxonomy grows as patterns emerge. The schema should make adding new classes cheap.

(High-level — this is the design-needed task.)

  1. Inventory current failure modes. Walk the SKILL.md failure paths across task-work, task-close-out, pr-respond, orchestrate. List the distinct failure modes that today surface to the user without leaving a record. That list seeds the taxonomy.
  2. Design the record schema. Decide on YAML vs JSON, file-per-incident vs append-only log, per-project location, what fields are required vs optional. Settle on an apps/sdlc/lib/model/entities/incident/schema.ts if going the entity route — that wires into existing entity-audit machinery.
  3. Build the library + query op. apps/sdlc/lib/services/incidents/ exposes recordIncident({ class, context, ...fields }). A registry op lists / summarises / filters.
  4. Auto-capture instrumentation. Add recordIncident calls in the most common failure paths: lease conflict, sub-agent verdict-error, quality-gate false positive (where detectable), worktree path mismatch (now closed but worth instrumenting for future analogues).
  5. Surface in reconcile or new skill. Either extend the lease reconcile reporter with an “incidents (last N days)” view, or build a dedicated /sdlc:incidents skill. Pick during design.
  6. Manual-entry skill. /sdlc:incident <class> <message> for incidents the protocol didn’t auto-catch.
  7. Documentation. A short convention doc at apps/sdlc/conventions/incident-log.md describing the schema, the taxonomy, and when to record manually.
LocationKindChange
apps/sdlc/lib/services/incidents/newLibrary exposing recordIncident() and friends.
apps/sdlc/lib/services/incidents/tests/newUnit tests.
apps/sdlc/lib/model/entities/incident/schema.tsnewIf incidents become an entity type.
apps/sdlc/lib/services/incidents/ops/newRegistry ops: list, summary, filter.
apps/sdlc/skills/incidents/ (or extend reconcile)newSkill surface for the operator.
apps/sdlc/skills/task-work/SKILL.mdmodifyAdd recordIncident calls in failure paths.
apps/sdlc/skills/task-close-out/SKILL.mdmodifySame.
apps/sdlc/skills/pr-respond/SKILL.mdmodifySame.
apps/sdlc/skills/orchestrate/SKILL.mdmodifySame.
apps/sdlc/conventions/incident-log.mdnewConvention doc.

(These will tighten during the design pass — this is a backlog task pending research.)

  • AC-1: recordIncident({ class, context, ...fields }) in apps/sdlc/lib/services/incidents/ writes a structured record to <project-root>/.sdlc/incidents/<YYYY-MM-DD-HHMMSS>-<class>.yaml (or whatever shape the design pass settles on).
  • AC-2: At least three failure paths in apps/sdlc/skills/ write incidents automatically — covering at minimum lease conflict, sub-agent verdict error, and a third class to be chosen during design.
  • AC-3: An incidents summary op (e.g. sdlc incidents summary --last 30d; final path per the design pass) produces a digest like api-socket-close: 3, lease-conflict: 1, ... so the operator can see frequency at a glance.
  • AC-4: An operator manually records an incident via /sdlc:incident <class> "<message>" and it shows up in the next summary digest.
  • AC-5: Auto-captured incidents include enough context (task ID, skill name, SHA, error class) that a follow-up task can be opened with concrete evidence rather than vibes.
  • AC-6: All existing tests pass; project quality checks pass.
  • A web dashboard for incidents. Plain CLI output is fine; consumers can build their own dashboards.
  • Cross-project incident aggregation (incidents from multiple repos in one view). Per-project for now.
  • Telemetry or remote logging. The log lives in the project’s working tree; never leaves the operator’s machine.
  • Auto-spawning follow-up tasks when an incident class crosses a threshold. Tempting but premature — let the operator decide based on the digest.
  • none

User feedback on 2026-05-27 during slice-4 friction triage: “I’d like to start somehow capturing classes of errors numerically — you say it has shown up before in the wild, do you have records of that? Without direct evidence it was prompt length that caused problem the fix is just a guess.”

The triggering moment was T-JXBQ-task-work-warns-on-long-sub-agent-prompt — proposed in a post-mortem with one observation, dropped as cargo-culting. The reframed direction: build the substrate that makes decisions like that data-driven, then reopen the original task only when evidence supports it.

This task is intentionally planning/backlog until a design pass settles the record schema, auto-capture surface area, and the taxonomy. The user described it as “a backlog item” specifically — not urgent, but the foundation for better friction-task triage going forward.


← Back to Tasks