sb-debug · git:20261015.0b6c394 · 2026-10-15 · sha256 7fc6ce53949da399
sb-debug git:20261015.0b6c394A
Immutable. This exact content never changes and is served at /api/v1/blob/7fc6ce53949da399.
--- name: sb-debug description: Use directly when the user asks why a Task or Direct item failed or cannot be implemented. Establish the root cause, categorize it, and return a next action. Read-only; never starts implementation or applies the fix. argument-hint: "<failure>" --- # Diagnose one failure The **diagnosis is the deliverable**. Someone else applies the fix, from a context that did not watch this failure happen. ## Final response contract — before any investigation Your final response is incomplete unless it ends with this exact parseable shape. Reserve it now and fill it from the evidence: ```text ## Diagnosis - CATEGORY: IMPLEMENTATION | REVIEW | PLAN | ARTIFACT | ENVIRONMENT | UNDETERMINED - CAUSE: <what diverges, and where> - NEXT_ACTION: <for whoever owns that category> - UNCERTAIN: <what remains open, or none> ``` Naming a category in prose does not satisfy this contract. Do not rename the heading, omit a field, or return only a narrative diagnosis. ## Apply project language style Before authoring any artifact or user-facing prose, read: ```sh specbind rule read language-style --for consume ``` Apply returned policy only to natural-language prose. `NO_CHANGE RULE_ABSENT` means no additional project preference; any `ERROR` line stops the workflow. ```sh specbind protocol read debug ``` ## Resolve the subject Use the explicit failure, Spec, and Task identity supplied by the caller. When a bare diagnosis request omits them, do not infer identity from a repository path or from whichever Task you notice first. ### Explicit Direct item An explicitly identified Direct-item failure uses the debug protocol's Direct input branch: ```sh specbind milestone scope --include-body specbind contract shared read specbind steering list ``` Identify the exact item and read every listed Steering document with `specbind steering read <selector> --for consume`. Apply shared Contract entries that govern the changed paths or behavior; `OK SHARED_CONTRACT_ABSENT` is a complete answer. A failed required read is `UNDETERMINED`, not evidence that no shared constraint applies. Use the summary, done condition, current change and checks instead of Spec/Task reads. The done condition and checks are evidence from the request, implementation handoff and repository, not required Roadmap fields. Derive a condition only when the summary determines it; otherwise report the missing fact. A Direct item can remain pending after a failed attempt: reproduce or locate the named failure in the supplied revision or current files without inventing Task state. Do not invent a Spec identity or treat absent Spec artifacts as a failure. ### Spec-backed Task ```sh specbind milestone status specbind tasks list <spec> ``` List Tasks for every active Spec in implementation. For a request that says a Task failed or cannot be implemented, candidates are blocked Tasks and pending actionable Tasks. Continue only when exactly one candidate exists across the active milestone. Otherwise present the canonical candidates and ask the user which failure to diagnose. The request is not evidence that an arbitrary candidate failed. ## Change nothing Read-only means read-only. You may run commands that reproduce or observe the failure; you may **not** modify any tracked file, and you may not apply the fix you find. This is evidentiary, not procedural. A repository you have already edited leaves the next agent unable to tell which state your reasoning describes, and destroys the evidence a second round would need. ## When the context is not fresh You work best dispatched into a clean context, given the failure and the inputs and **not** the history of attempts that failed. That omission is the mechanism: a retry that inherits the reasoning which just failed reliably reproduces it. **If you were invoked inside the session that already failed, say so.** Then: - name what you are deliberately setting aside — the conclusions this session already reached, the theories it already committed to; - re-derive from the evidence in front of you rather than from where the session had got to; - when the failure has already survived several attempts here, say plainly that a fresh session would produce a more trustworthy diagnosis. Running as though the context were clean is the failure mode this skill exists to break. ## Establish the cause Read what the system was supposed to do, not only what it did: For a Spec-backed Task, establish the following inputs. A Direct subject keeps the input branch resolved above. ```sh specbind spec status <spec> specbind tasks show <spec> <task-id> specbind artifact list <spec> specbind artifact read <spec> requirements --for consume specbind artifact read <spec> contract --for consume specbind steering list ``` The inventory names split Designs and every `implementation-notes/<artifact-id>` selector. Read all that govern the failure: ```sh specbind artifact read <spec> design/<artifact-id> --for consume specbind artifact read <spec> implementation-notes/<artifact-id> --for consume ``` Steering has no relevance metadata. Read every selector the listing returns: ```sh specbind steering read <selector> --for consume ``` Zero Steering documents is a complete answer. If the artifact inventory, Contract read, Steering listing, or any Steering read fails, do not infer the missing content. Return `UNDETERMINED` and make the failed read the evidence step that must succeed before the cause can be owned. An inventory with no notes is a complete answer. When notes exist, a recorded trap is often exactly the cause. The cause is where actual behavior **first diverges** from what the approved artifacts require. Everything after that point is consequence, and the error message names where something surfaced, not where it went wrong. If two causes remain possible, say both and say what would distinguish them. A confident single answer that is wrong costs more than an honest fork. ## Return the diagnosis End with the exact block reserved above: ```text ## Diagnosis - CATEGORY: IMPLEMENTATION | REVIEW | PLAN | ARTIFACT | ENVIRONMENT | UNDETERMINED - CAUSE: <what diverges, and where> - NEXT_ACTION: <for whoever owns that category> - UNCERTAIN: <what remains open, or none> ``` The category decides who fixes it, and misrouting is expensive: - **IMPLEMENTATION** — the code does not do what the design requires. Back to the task. - **REVIEW** — a blocking finding requires work outside this Task's approved scope, that work belongs to another Task, Spec, or later lifecycle boundary, and no current approved input must change. Back to a fresh independent review of the exact current-Task subject. Uncertain ownership is `UNDETERMINED`, not `REVIEW`. - **PLAN** — the task, its ordering, or its prerequisites are wrong. Back to the task plan. - **ARTIFACT** — the requirements or design specify something unworkable, or contradict each other. **No amount of implementation effort fixes this**, and handing it back as an implementation defect produces repeated attempts at work that cannot succeed. - **ENVIRONMENT** — the system is not in the state the work assumes. Usually outside the change entirely. - **UNDETERMINED** — the evidence does not yet establish an owner. Name the evidence-gathering step that would distinguish the remaining possibilities. Describe what must become true rather than dictating a diff, unless the exact edit is itself the finding. The implementer has context you do not. **Say when you cannot diagnose it.** Report what you ruled out and what evidence would be needed. That is a useful result; a guess presented as a cause sends the next round in a direction chosen by nothing, and looks exactly like a real finding until it fails. ## Boundaries - Write nothing. No fix, no implementation notes, no task state, no gate. - Diagnose one failure and return. Counting rounds belongs to the run that dispatched you. - Report in the project's language, with the block above intact.