--- name: design-behavior description: "Turn a requirements report into a behavior-only design doc under docs/design/, updating docs/design/index.md and merging into docs/prd.md. Reads existing design docs to flag (not auto-resolve) conflicts. Use for Phase 2 of task-splitter, after understand-requirements has written requirements-report.md." --- Read [the Codex runtime adapter](../../docs/codex-runtime.md) before following this workflow. # Design Behavior — Phase 2 You are the **Behavior Designer**. You translate requirements into a design doc that describes *what* the system does, observable from the outside — not *how* it's built. That boundary matters: it's what keeps `docs/design/` usable across reimplementations and what `plan-tasks` and `implementation-workflow` both depend on being stable. This skill runs in the orchestrator's **`design` mode only**. In `split` mode the design doc already exists and is not this run's to rewrite. ## Quick Reference - For the behavior/implementation boundary and NG examples, see [reference.md](reference.md) - For which artifact each piece of content belongs in — design doc, Issue, ADR, or nowhere — and why this doc has no `## Implementation Notes` section, see [../../docs/vcs-minimalism.md](../../docs/vcs-minimalism.md) §2 - For when a design decision needs an ADR, see that document's §3 — and Step 5 below, which is the phase where this actually comes up - For checking a decision against the existing ADR record before you write — and what to do if it conflicts with or contradicts one — see [../../docs/decision-precedent.md](../../docs/decision-precedent.md) - For the environment every file write here happens in, see [../../docs/sandbox-environment.md](../../docs/sandbox-environment.md) --- ## Workflow ### Step 1 — Read Inputs Read `.codex/workflow-runs/task-splitter//requirements-report.md`. ### Step 2 — Light Existing-Implementation Check Use `rg`/`rg --files`/the file reader to get a rough sense of what already exists in the codebase that's relevant to this feature (existing modules, similar features, naming conventions). This is a light pass, not a full investigation — deep codebase investigation is `implementation-workflow`'s job later. If `docs/tool.md` exists and documents a project-specific code-search MCP tool, you may `discover_tools` for it and prefer it over raw `rg`/`rg --files`. If `docs/tool.md` doesn't exist or doesn't mention one, `rg`/`rg --files`/the file reader are sufficient — don't block on this. ### Step 3 — Check for Conflicts Read `docs/design/index.md` and `docs/prd.md` if they exist. Look for overlapping or contradictory existing design docs. **If a conflict or duplicate is found:** flag it to the user with the specific existing content vs. the new content, and ask how to proceed. Do NOT silently merge or overwrite — surface and let the user decide. ### Step 4 — Write the Design Doc Write `docs/design/.md` (slug = kebab-case feature name). Follow the behavior-only boundary in [reference.md](reference.md) strictly: observable inputs/outputs, interfaces, constraints, state transitions. No language, library, algorithm, or file-layout detail. ```markdown # **Status:** draft **Source epic:** ## Overview ## Interfaces ## Constraints ## State Transitions ``` **The doc ends there.** Do not add an `## Implementation Notes` section, or any other section for technical decisions, snags, or learnings — that content is *how*, and it belongs to the PR and the Issue, not to the repository (see [../../docs/vcs-minimalism.md](../../docs/vcs-minimalism.md)). A design doc that accumulates implementation detail stops being a stable contract, which is the one thing it exists to be. ### Step 5 — Write an ADR for Each Decision the Doc States as a Fact **Do this pass every time. It is the step most often skipped, and skipping it is how a design doc ends up asserting things nobody can justify.** A design doc states outcomes: "a session expires after an hour of inactivity", "the import rejects the whole file on the first bad row". Written down, each reads as a fact about the system. But you just *chose* it, over alternatives that were live a minute ago, for reasons that are in your working context and nowhere else. The behaviour-only boundary that keeps this doc stable is exactly what strips the reasoning out of it — so the reasoning has to land somewhere, and [../../docs/vcs-minimalism.md](../../docs/vcs-minimalism.md) §3 says where. Go back through the doc you just wrote, line by line, and for each statement ask: **was this contested?** If yes, apply the half-day test. If reversing it would cost a human half a day or more, write an ADR. **Before writing it, check for precedent.** Read `docs/adr/index.md` and open any ADR whose title or context plausibly overlaps this decision — [../../docs/decision-precedent.md](../../docs/decision-precedent.md) has the full check. If an existing **accepted** ADR already settled this the same way, cite it (`Refs: ADR-NNNN`) instead of writing a new one. If it settled it the *opposite* way, or its `Alternatives Considered` already rejected the direction you're about to take, do not write past it silently: raise it with `ask_user` — show the existing ADR's `Decision` (or the rejected alternative) next to what you're about to decide — and get the user's explicit agreement before continuing. Only write a new ADR after that agreement, and write it as a supersession per [../../docs/vcs-minimalism.md](../../docs/vcs-minimalism.md) §4. You have no source comments and no multi-file commit to fall back on — this plugin writes documents, not code — so at planning time the routing collapses to "ADR, or the reasoning is lost". That asymmetry is why this phase should produce ADRs far more often than it has been. The §3 table lists the signals; the ones that come up here most are a public contract others will write against, a compatibility boundary, a data shape that outlives the epic, and a behaviour deliberately excluded in a way that will later look like an oversight. Write each as `docs/adr/NNNN-.md` with `**Status:** accepted` — not `draft`, because the Phase 4 PR *is* the change that ships the decision and has no later gate (vcs-minimalism §6) — and add its row to `docs/adr/index.md`. Number from the highest existing ADR + 1; create `docs/adr/` if it doesn't exist. Two rules that keep these honest: - **`## Alternatives Considered` is where the value is.** The alternative you rejected, and the specific reason it lost, is the part nobody can reconstruct from the design doc. An ADR without it is barely worth the file. - **Don't restate the design doc in the ADR.** The doc says what the system does; the ADR says why it was decided to do that. If your `## Decision` reads like a paragraph of the design doc, you've written the wrong document. If nothing in the doc was genuinely contested — a small epic extending an established pattern — write no ADR and say so in your return value. An empty pass that was actually performed is a fine outcome; one that was silently skipped is not. ### Step 6 — Update the Index and PRD - Add a row to `docs/design/index.md` (title, status `draft`, one-line summary, link). - Merge (don't overwrite) into `docs/prd.md`: add a line under "Design Docs" linking to the new doc; add to "Goals"/"Scope Boundaries" only if the epic introduces something not already captured there. ## Return Value Return the design doc path and a one-sentence summary of what it covers — enough for `plan-tasks` to know where to read from and for the orchestrator to log progress. List every ADR you wrote (number, title, path), or state explicitly that Step 5 found nothing contested — the orchestrator shows any ADR to the user in full at the confirm gate and stages it in the Phase 4 commit, so an unreported one never ships. If you flagged a conflict, include that too, so the orchestrator can surface it prominently.