Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
bump: patch
---

### Changed

- `/planning:interview` and `/planning:wayfind`: reworded phrases the interview text shared with an upstream skill set. The confirmation gate now opens with Step 3's stop wording ("no question is left to ask"), and "the frontier is empty" now reads "no open question remains on the frontier" (or "the frontier holds no item" in wayfind) across the skill bodies, the assumption sweep, the checklist template and the evals. No rule changed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
bump: patch
---

### Changed

- The interview round's closing probe is now worded "something else", never "anything else": "Is there something else that would change these recommendations?" The eval case `interview-closing-probe-something-else` grades the wording.
7 changes: 7 additions & 0 deletions .changes/planning/work-resolve-issue-issue-11187-5b1d0e7a.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
bump: patch
---

### Fixed

- `/planning:interview` in the terminal now reads back an answer that departs from the recommendation, or that arrives dictated or unclear, in its own words and keeps the question open until the user confirms or corrects it. An answer that accepts the recommendation still resolves at once.
7 changes: 7 additions & 0 deletions .changes/planning/work-resolve-issue-issue-11189-4b7e2d91.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
bump: patch
---

### Fixed

- When every answer was accepted as recommended or confirmed after its read-back, `/planning:interview`'s final confirmation no longer re-lists the unchanged accepted answers, even at the first confirmation. A recap saved once each round's read-backs are confirmed lets the pasted `--changed` recap list only the answers changed since, and the restatement adds the intent, the hedged answers and the assumptions the user has not seen. A host run of the `interview-final-brief-changes-only` eval case on 2026-10-30 scored 0 of 3 with-plugin runs on its changes-only and omits-unchanged graders before this rule.
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ expected_outcome: "The restatement ends by asking the user to confirm, or to nam

/planning:interview Add CSV export to the admin orders page.

Where we are: rounds 1 and 2 are answered. Q1 export the filtered rows. Q2 columns as shown in the table. Q3 timestamps in UTC. Q4 a cap of 50,000 rows. Q5 file name orders-YYYY-MM-DD.csv. The frontier is empty and the assumption sweep added no open row. Restate the contract and ask me to confirm it.
Where we are: rounds 1 and 2 are answered. Q1 export the filtered rows. Q2 columns as shown in the table. Q3 timestamps in UTC. Q4 a cap of 50,000 rows. Q5 file name orders-YYYY-MM-DD.csv. No open question remains on the frontier and the assumption sweep added no open row. Restate the contract and ask me to confirm it.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
description: "Contract case for the wayfind map-closure hand-off when the decision map is closed, the frontier is empty and the destination is a PLAN. Why hard: the reflex is to restart charting, or to go back to an interview, instead of handing the destination to the planning step."
description: "Contract case for the wayfind map-closure hand-off when the decision map is closed, the frontier holds no item and the destination is a PLAN. Why hard: the reflex is to restart charting, or to go back to an interview, instead of handing the destination to the planning step."
tags: [wayfind, handoff]
runs: 3
max_turns: 12
Expand All @@ -8,4 +8,4 @@ allowed_tools: [Read, Glob, Grep, Skill]
expected_outcome: "The user is told to produce the implementation plan next, directly or with the design step ahead of it, since the map has done its job and its destination is a plan, with no further charting or interviewing"
---

Use the wayfind skill. The tracker is unreachable from here, so work from the map state I describe and do not look for files. Our decision map for migrating the billing service to a new message broker is fully closed: the frontier is empty, every decision item is closed, and the map's destination is an implementation PLAN, not a Brief or a PRD. Hand off: what should I run next?
Use the wayfind skill. The tracker is unreachable from here, so work from the map state I describe and do not look for files. Our decision map for migrating the billing service to a new message broker is fully closed: the frontier holds no item, every decision item is closed, and the map's destination is an implementation PLAN, not a Brief or a PRD. Hand off: what should I run next?
12 changes: 6 additions & 6 deletions plugins/planning/skills/interview/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ Every other skill the interview hands to or detours through: [`context/compositi

**Open with the problem when the request has none.** When the request names no problem (an idea, or a solution with no stated why), round 1's first question asks what problem it solves and why the user wants it solved; keep that answer in the user's words for the Goal's Intent line.

A new effort starts here, however big. When the interview shows the effort is too big to hold in one session AND still too foggy to phrase as sharp questions, the user can't yet list the decisions, let alone lock them. Name `/planning:wayfind` to the user (it charts the fog as a decision map and works the frontier down decision by decision, graduating to a Brief once it clears); recommend, never auto-switch. The user can run it in this same session: its chart step reads this topic's ledger, so settled answers become decisions so far and open questions become decision items.
A new effort starts here, however big. When the interview shows the effort will outrun a single session AND is still too foggy to phrase as sharp questions, the user can't yet list the decisions, let alone lock them. Name `/planning:wayfind` to the user (it charts the fog as a decision map and works the frontier down decision by decision, graduating to a Brief once it clears); recommend, never auto-switch. The user can run it in this same session: its chart step reads this topic's ledger, so settled answers become decisions so far and open questions become decision items.

**Question budget scales with what's already settled.** Upstream artifacts, research findings, exploration output, a PRD, a design resolution, count as settled prerequisites: an interview invoked after them starts with a smaller tree and fewer rounds; never re-ask what an artifact already answers. There is no numeric question cap, but a frontier that keeps *ballooning* (each round opens more branches than it closes) is the wayfind signal above, not a license for a marathon session. Surface the routing recommendation instead of grinding on.

Expand Down Expand Up @@ -154,7 +154,7 @@ Alternatives to consider:
- (c) <option> — <one-line tradeoff>
```

`Q<N>` numbering runs continuously across rounds (Q1…Q4 in round one, Q5… in round two; visible depth). Close the round with one probe inviting a constraint that breaks the recommendations, and the note that the user may answer in any order. Wait for the answers before computing the next round. The recommendation+basis discipline holds per question. Inline prose carries the recommendation, its reasoning, AND the probe in one readable block; a card cannot.
`Q<N>` numbering runs continuously across rounds (Q1…Q4 in round one, Q5… in round two; visible depth). Close the round with one probe inviting a constraint that breaks the recommendations, worded "something else", never "anything else": "Is there something else that would change these recommendations?" (eval case `interview-closing-probe-something-else`). Add the note that the user may answer in any order. Wait for the answers before computing the next round. The recommendation+basis discipline holds per question. Inline prose carries the recommendation, its reasoning, AND the probe in one readable block; a card cannot.

**One verdict marker, at most one context line.** The `My recommendation:` line is the *single* verdict marker for the question. Never stack a second one: no standalone `**(RECOMMENDED)**` badge line above it, and no `(recommended)` tag repeated in the Alternatives list; the recommended answer is named once, on that line. The alternatives exclude the recommendation: none restates it. Per-question context is at most ONE line and usually absent. The round-header restate carries shared context, so add a line only when it doesn't reach this question or the session just resumed after a gap.

Expand Down Expand Up @@ -274,7 +274,7 @@ On the page surface, Step 3's confirmation gate runs on the page: post the resta

**What, not how: the mechanism tripwire.** "Does not plan implementation" has a trigger. When a question or its recommendation names a mechanism (a tool, an API, a credential or token scope, a runtime, a platform per step), ask once whether the user wants mechanism-level decisions settled now or at planning. Ask it in the same round as the first mechanism-naming question and register it like any other question; until it is answered, recommendations carry no mechanism part. When the answer is "at planning", no later recommendation fixes a mechanism, and every still-`open` mechanism row, commitment rows included, becomes `deferred`: carried to the Brief's `### Deferred questions` under the arbiter rule in an engineering session, listed as deferred in the shared-understanding summary in a general one. When the answer is "now", write `C<N> | confirmed | mechanism decisions settled in this interview | user, round <N>` at once, and the Brief's Constraints records that this topic overrides "does not plan implementation".

**Sweep for assumptions before Step 3.** In `me` and `auto` with a register, including the `auto` Mixed path after its residue round, the loop ends with a fresh-context assumption sweep. Once the frontier is empty, and before the Step 3 register gate and confirmation gate, dispatch a non-fork sub-agent to inventory undecided details, hidden defaults, contradictions, and hedged or free-text rows across the ledger, the recommendations, and any composed artifacts. You turn each item into a register row at the next contiguous `Q<N>`, a stated fact, or, for hedged rows, a line in the confirmation restate. Any `open` row it adds returns the run to Step 2, and the next sweep covers only what the new answers changed; Step 3 is reached when a sweep adds no `open` row. A run that asked no question skips it, and so does `lock`; unattended, an item that is the user's decision is `blocked`. The acceptance-criteria coverage prompt is never a sweep item ([`context/coverage-prompt.md`](context/coverage-prompt.md)). Scope, item shape, and disposition: [`context/assumption-sweep.md`](context/assumption-sweep.md).
**Sweep for assumptions before Step 3.** In `me` and `auto` with a register, including the `auto` Mixed path after its residue round, the loop ends with a fresh-context assumption sweep. Once no open question remains on the frontier, and before the Step 3 register gate and confirmation gate, dispatch a non-fork sub-agent to inventory undecided details, hidden defaults, contradictions, and hedged or free-text rows across the ledger, the recommendations, and any composed artifacts. You turn each item into a register row at the next contiguous `Q<N>`, a stated fact, or, for hedged rows, a line in the confirmation restate. Any `open` row it adds returns the run to Step 2, and the next sweep covers only what the new answers changed; Step 3 is reached when a sweep adds no `open` row. A run that asked no question skips it, and so does `lock`; unattended, an item that is the user's decision is `blocked`. The acceptance-criteria coverage prompt is never a sweep item ([`context/coverage-prompt.md`](context/coverage-prompt.md)). Scope, item shape, and disposition: [`context/assumption-sweep.md`](context/assumption-sweep.md).

### Step 3. Recognize the stop condition

Expand All @@ -289,11 +289,11 @@ bash "${CLAUDE_PLUGIN_ROOT}/scripts/check-open-questions.sh" \

Exit 1 (a row is `open` or `superseded-by-plan`) and exit 2 (ungradeable) both HALT. Resolve or explicitly retire an `open` row and re-run; a `superseded-by-plan` row leaves only on the user's reply to it ([`context/loop.md`](context/loop.md) "Superseded by plan"). Never lock a contract over a non-zero exit; that is the reported failure restated. **A run that asked no question wrote no register, has nothing to gate, and skips this**: `auto` routing to synthesize-directly with no open decision. `lock` always writes its problem row, so its register gates. The carve-out is about the absence of questions, never about which action produced it: the moment ANY question exists. Asked, surfaced mid-synthesis, or blocked unattended. A register exists and the gate applies. The `--brief` cross-check runs in Step 4, once there is a Brief to cross-check against; it also exits 1 with `brief=unconfirmed` while the Brief is stamped `Restatement: UNCONFIRMED`. The gate reads only that stamp, so it cannot see a Brief edited after a Confirm: after such an edit, post a new `restate`, get a fresh Confirm and export again.

**The acceptance-criteria coverage prompt is not a question for this purpose**: it writes no register row and does not by itself bring this gate into scope, and no other question in the same round or session shares that exemption ([`context/coverage-prompt.md`](context/coverage-prompt.md)).
**The acceptance-criteria coverage prompt is not a question for this purpose**: it writes no register row and does not by itself bring this gate into scope, and no other question, whether asked beside it or later in the session, shares that exemption ([`context/coverage-prompt.md`](context/coverage-prompt.md)).

**Confirmation gate (`me` and `auto`):** an empty frontier is necessary but not sufficient. Before persisting the contract or handing off, restate the shared understanding, opening with the one-line problem, and get the user's explicit confirmation that it is reached. Do not act on the interview's output until they confirm. `lock` confirms the problem with one question, registered like any row; its invocation confirms the rest (its STOP-on-gap rule still applies).
**Confirmation gate (`me` and `auto`):** that no question is left to ask does not end the interview on its own. Before persisting the contract or handing off, restate the shared understanding, opening with the one-line problem, and get the user's explicit confirmation that it is reached. Do not act on the interview's output until they confirm. `lock` confirms the problem with one question, registered like any row; its invocation confirms the rest (its STOP-on-gap rule still applies).

**Recap and procedure check (`me` and `auto`).** Before asking for confirmation, the restatement carries a Q&A recap: one line per `Q<N>` in the ledger's `## Open-question register`, shaped `Q<N> <status>: <question text> (<resolution>)`, generated from the register on disk, never from the transcript, so it survives a compaction. Generate it with `bash "${CLAUDE_PLUGIN_ROOT}/surface/round.sh" export-ledger --recap --ledger <memory_dir>/<topic-slug>/interview-checklist.md --out <memory_dir>/<topic-slug>/recap.md`, which reads the ledger alone, so the terminal lane, with no page data, passes no `--dir`. Paste the contents of `recap.md` verbatim in place of a recap of your own: no paraphrased or hand-shortened line, and no HTML or collapsible block, which the terminal shows as raw tags. Each recap saves its rows beside the ledger (`interview-checklist.last-recap.json`, overwritten each time). After the first confirmation, add `--changed`: the recap then lists only the rows changed since the last recap, plus one line counting the rest by status. The page lane's `restate` keeps the full recap ([`context/surface.md`](context/surface.md) "Confirmation gate"). Then run the procedure check beside the register gate, ledger only, and cite its exit code and `procedure=` field as the evidence that the procedure ran, never your own account of it:
**Recap and procedure check (`me` and `auto`).** Before asking for confirmation, the restatement carries a Q&A recap: one line per `Q<N>` in the ledger's `## Open-question register`, shaped `Q<N> <status>: <question text> (<resolution>)`, generated from the register on disk, never from the transcript, so it survives a compaction. Generate it with `bash "${CLAUDE_PLUGIN_ROOT}/surface/round.sh" export-ledger --recap --ledger <memory_dir>/<topic-slug>/interview-checklist.md --out <memory_dir>/<topic-slug>/recap.md`, which reads the ledger alone, so the terminal lane, with no page data, passes no `--dir`. Paste the contents of `recap.md` verbatim in place of a recap of your own: no paraphrased or hand-shortened line, and no HTML or collapsible block, which the terminal shows as raw tags. Each recap saves its rows beside the ledger (`interview-checklist.last-recap.json`, overwritten each time). After the first confirmation, add `--changed`: the recap then lists only the rows changed since the last recap, plus one line counting the rest by status. The page lane's `restate` keeps the full recap ([`context/surface.md`](context/surface.md) "Confirmation gate"). **When every answer was accepted as recommended or confirmed after its read-back** ([`context/loop.md`](context/loop.md) "Drift check"), save a recap with the command above once each round's read-backs are confirmed, without pasting it, so the first confirmation pastes the `--changed` recap too: it lists only the answers changed since, with one line counting the rest. The restatement adds the intent, each `hedged:` row ([`context/loop.md`](context/loop.md) "Hedged flag") and each stated assumption the user has not yet seen, and does not re-list the unchanged accepted answers (eval evidence: `interview-final-brief-changes-only`). Then run the procedure check beside the register gate, ledger only, and cite its exit code and `procedure=` field as the evidence that the procedure ran, never your own account of it:

```bash
bash "${CLAUDE_PLUGIN_ROOT}/scripts/check-open-questions.sh" \
Expand Down
6 changes: 3 additions & 3 deletions plugins/planning/skills/interview/context/assumption-sweep.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ is asked, stated, or blocked before the confirmation gate.

## When

- `me` and `auto` runs with a register, once the frontier is empty and before the Step 3 register
gate and confirmation gate. The `auto` Mixed path runs it after its residue round.
- `me` and `auto` runs with a register, once no open question remains on the frontier and before
the Step 3 register gate and confirmation gate. The `auto` Mixed path runs it after its residue round.
- Skipped when the run asked no question (no register exists) and in `lock`.
- After the answers to sweep rows land, sweep again over what those answers changed. Step 3 starts
when a sweep adds no `open` row.
Expand Down Expand Up @@ -162,7 +162,7 @@ rather than at the next sweep.
- **Scope:** only the **Contradictions** category of "What it looks for", read with the draft
round's recommendations standing in for answers: a recommendation that cannot hold beside an
`answered` row or a `confirmed` constraint. No other category runs here; the sweep still runs
once the frontier is empty.
once no open question remains on the frontier.
- **Return:** one line per conflict in the "Item shape" above, category `contradiction`, with the
draft question and the earlier row as its dependencies; nothing when there is none.
- **Disposition:** fix each in the draft before posting. A conflict with a `confirmed` constraint
Expand Down
Loading
Loading