Skip to content

Decompose a Capability

bob decompose takes one approved parent (a cap or a use-case) and files its child requirements through six phases. Every phase has a gate, and the run only moves on when the gate passes. It writes issues, never files, so you can run it while a warp-drive session is working in the same checkout. For why it is built this way, see The decomposition machine.

  • The parent is open and labelled approved. bob decompose refuses anything else.
  • You are in the project’s checkout. The run’s state lives in .claude/.decompose-state.json.
  1. Start the run. It reads the parent and runs the sourcing gate:

    Terminal window
    bob decompose 2973

    Exit 0 means the run is now in drafting. Exit 3 means the gate refused: the message names the reason (missing, closed, not-approved, not-a-parent), and bob decompose status shows it again.

  2. Draft the children. Follow the /capability (or /use-case) decomposition guidance: carve by slice, not by layer — the first child is a thin end-to-end path and each later child extends it with another behaviour, never “schema / API / UI” (#2739). Write the draft as JSON. Each child is a full requirement body with ## Acceptance Criteria checkboxes, a req label, and Part of #N (or Realizes #N for a use case) in its Notes:

    {"children": [
    {"title": "…", "labels": ["req", "p2-high"],
    "body": "## Description\n\n…\n\n## Acceptance Criteria\n\n- [ ] The CLI prints … when …\n\n## Notes\n\nPart of #2973\n"}
    ]}
    Terminal window
    bob decompose transition drafted --file draft.json

    Nothing is filed yet. Each child picks up the parent’s area:* label, and the tracer label when the parent has it (#2739).

  3. Clear duplicates. Every candidate is checked against the open backlog:

    Terminal window
    bob decompose transition deduped

    When a candidate duplicates an existing issue, the refusal names it. Drop the candidate, or merge it into the existing issue. A merge posts one comment on that issue with the candidate’s criteria:

    Terminal window
    bob decompose transition deduped --data '{"resolve":{"c2":"merge #2681"}}'
  4. Pass the testability gate. Every acceptance criterion must be observable: an actor, an action and a result someone can check. The Docs criterion /requirement prescribes passes by rule, and the judge asks about each distinct criterion text once per run, so the same sentence gets the same verdict in every child (#3579).

    Terminal window
    bob decompose transition judged

    A refused criterion is named with its child and number. Reword it (bob decompose transition redraft, then draft again), or have a person override it. The override is written onto the child with who and why:

    Terminal window
    bob decompose transition judged --data '{"override":{"child":"c1","n":2,"by":"<your login>","why":"<reason>"}}'

    If the judge had no opinion, the child is not blocked. It is filed with a visible <!-- decide:abstained decompose-testability --> marker instead.

  5. File and trace. This files every child, adds each one to the parent’s Requirements (or Decomposition) checklist, and then reads everything back from GitHub:

    Terminal window
    bob decompose transition filed

    Exit 0 means the run is filed. Every child exists, carries req, the parent’s area label and its tracer label when it has one, and links the parent, and the parent lists every child. If a read-back check fails, the run stays in tracing and the check is named. Fix it on GitHub and run the same command again. Children that are already filed are never filed a second time.

Terminal window
bob decompose status # phase, the last refusal, the children and their numbers
bob decompose stop # end the run; anything already filed stays filed

Add --json to any command for a bob-decompose/1 document.

It never writes a chunk or session report, makes a commit, or touches a branch. The filed issues are the whole artifact.