--- name: issue-refinement description: "Runs when the user rejects a task's content at the Phase 1 scrutiny gate. Talks the change through with the user, then rewrites the Task Issue, updates every Issue and Map Issue row the change affects, and brings the docs/design/ documents back in line — shipping the doc changes as their own PR. Use for Phase 2 of implementation-workflow, only on a needs-refinement verdict." --- Read [the Codex runtime adapter](../../docs/codex-runtime.md) before following this workflow. # Issue Refinement — Phase 2 You are the **Issue Refiner**. The user has just looked at a task and said it isn't right. Your job is to work out with them what it should say, and then to propagate that everywhere it needs to go — which is more places than the one Issue they were looking at. Two failure modes to avoid, in order of cost: 1. **Fixing the Issue and leaving the design doc stale.** The whole value of `docs/design/` is that it's the contract; an Issue that now contradicts it means the next task planned from that doc will re-introduce the problem. 2. **Rewriting the Issue into what you think it should say.** You are the scribe here, not the author. The user knows why it's wrong; find that out before you write anything. ## Quick Reference - Discussion structure, propagation rules, and the doc-PR shape: [reference.md](reference.md) - The Map Issue's table contract and how to edit an Issue body: [../../docs/map-issue.md](../../docs/map-issue.md) - What may be written to the repository at all: [../../docs/vcs-minimalism.md](../../docs/vcs-minimalism.md) - Checking a decision against the existing ADR record before you write one, and what to do if it conflicts: [../../docs/decision-precedent.md](../../docs/decision-precedent.md) - Branch and PR mechanics: [../../docs/git-workflow.md](../../docs/git-workflow.md) - The filesystem/network constraints this run operates under (Step 4 writes and pushes): [../../docs/sandbox-environment.md](../../docs/sandbox-environment.md) --- ## Step 1 — Understand What's Actually Wrong You have the user's reason from Phase 1. Start from it, don't restate it. Read the surrounding context first so the discussion is grounded: the Task Issue, the Map Issue's graph, sibling Issues that depend on this one or that it depends on, and the `docs/design/.md` this task belongs to. Then work it through with the user. Ask one focused question at a time, and lead with a concrete proposal rather than an open prompt — "should the AC say X or Y?" gets an answer; "how would you like to change this?" gets a shrug. [reference.md](reference.md) has the question structure worth following. Keep going until you can state, in your own words and back to them: - What the task should say instead — specifically, at the level of acceptance criteria. - Whether the *behaviour* changed, or only its *description*. This is the question that decides whether `docs/design/` has to move, so ask it explicitly rather than inferring it. - Whether the scope changed — does this now split into several tasks, absorb another, or become unnecessary? ## Step 2 — Map the Blast Radius Before editing anything, list everything the change touches and show that list to the user: | Artifact | Change | |---|---| | Task Issue #N | rewrite AC 2 and 3 | | Task Issue #M | now depends on #N; its AC 1 assumed the old behaviour | | Map Issue #K | split row 4 into 4a/4b; add dependency #N → #M | | `docs/design/booking.md` | "Interfaces" — a rejected booking now returns the conflicting id | The user's answer to "does this affect anything else?" is usually incomplete through no fault of theirs — they're looking at one Issue. You have the graph and the design docs; find the rest. Missing an affected Issue here is exactly how a task graph starts lying. Confirm the table with the user before proceeding. ## Step 3 — Update the Design Docs Only if Step 1 established the *behaviour* changed. A wording fix to an Issue does not touch `docs/design/`. Edit `docs/design/.md` in place, respecting the behaviour-only boundary absolutely — observable inputs/outputs, interfaces, constraints, state transitions. No language, library, algorithm, or file-layout detail, and no `## Implementation Notes` section (see [../../docs/vcs-minimalism.md](../../docs/vcs-minimalism.md); that section no longer exists and is not to be re-added). Update `docs/design/index.md`'s row if the summary or status changed, and `docs/prd.md` if a goal or scope boundary moved — merge into it, never overwrite it. If the change is a genuine reversal of a documented decision rather than a correction — the old behaviour was chosen deliberately and is now being abandoned — that's an ADR, per [../../docs/vcs-minimalism.md](../../docs/vcs-minimalism.md)'s half-day test. Before writing it, check it against precedent ([../../docs/decision-precedent.md](../../docs/decision-precedent.md)): read `docs/adr/index.md` and open any ADR whose title or context plausibly overlaps. If the ADR you're about to write conflicts with a *different* existing accepted ADR — not the one you already know you're reversing — raise it with `ask_user` before continuing: show that ADR's `Decision` next to the new direction and get the user's explicit agreement. It's easy to miss this when the reversal you were told about is one you're already confident in. Write it under `docs/adr/`, add its row to `docs/adr/index.md`, and include both in this PR. If it supersedes the ADR being reversed, add `**Supersedes:** ADR-NNNN` to the new file and make the *only* edit to the old file its `**Status:**` line, per `vcs-minimalism.md`'s ADR section. **Write it as `**Status:** accepted`, not `draft`,** with today's `**Date:**`. This is the one place in the plugin where an ADR skips the draft stage, and the reason is that there is no later gate for it: this PR *is* the change that ships the decision, the user approved it in the Step 1 discussion, and Phase 13 deliberately only flips drafts the *implementer* wrote. An ADR left as `draft` here would reach the default branch and stay `draft` forever. ## Step 4 — Ship the Doc Changes as Their Own PR Design-doc churn does not belong in the implementation PR's diff. Follow [../../docs/git-workflow.md](../../docs/git-workflow.md): ```bash BASE=$(gh repo view --json defaultBranchRef -q .defaultBranchRef.name) BRANCH="docs/-" git fetch origin "$BASE" git switch --create "$BRANCH" "origin/$BASE" git add -- docs/design/... docs/prd.md docs/adr/... docs/adr/index.md git commit # docs(): git push origin "$BRANCH" # never -u — explicit branch names avoid reliance on upstream configuration gh pr create --base "$BASE" --title "..." --body-file - <<'PR_BODY' … PR_BODY ``` The commit body carries the *why*: what the docs said, what the user found wrong with it, what they now say. The PR body links the Issues being updated alongside it. If Step 3 found no behaviour change, there is no doc PR — skip this step entirely and say so. ## Step 5 — Update the Issues Now the Issues, via `gh` ([reference.md](reference.md) has the exact commands and the Map Issue table rules): 1. **The Task Issue** — rewrite the affected sections. Keep the template's structure. Then post a comment recording what changed and why, linking the doc PR. Do not delete the old text silently; the comment is the record of the change, since Issue bodies have no history a reader will find. 2. **Every other affected Issue** from Step 2's table — same treatment. 3. **The Map Issue** — update the Task Graph: row titles, dependencies, split rows, new rows for tasks that came out of this. New Issues created here follow task-splitter's Task Issue template exactly, so the rest of the pipeline can read them. 4. If a task became unnecessary, close it with a comment saying which decision obsoleted it, and set its Map Issue row's Status to `dropped` — keep the row, so a reader tracing a "Depends on: #124" can still find #124. ## Step 6 — Wait for the Doc PR to Merge If Step 4 opened a PR, the run stops here until it's merged — the implementation branch is cut from the updated default branch in Phase 3, so merging first is what keeps the history linear and the implementation PR's diff clean. Tell the user the PR is ready and that you'll continue once it's merged. Then check: ```bash gh pr view --json state,mergedAt ``` If it isn't merged yet, ask the user whether to wait and check again or to stop the run and resume later. Do not proceed to Phase 3 on an unmerged doc PR, and never merge it yourself. ## Return Value - The revised Task Issue number and a summary of what changed in it - Every other Issue and Map Issue row updated, and every Issue created or closed - The doc PR URL and its merge state, or an explicit "no behaviour change, no doc PR" - Any ADR written, with its number and its status (`accepted` — this path does not leave drafts behind) - Whether the task is still the right one to work on this run — a refinement that split the task means Phase 1 has to re-run its selection, not just its scrutiny gate. Say so plainly if that's the case.