@ritualai/cli 0.11.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/dist/commands/doctor.js +59 -23
  2. package/dist/commands/doctor.js.map +1 -1
  3. package/dist/commands/init.js +35 -0
  4. package/dist/commands/init.js.map +1 -1
  5. package/dist/commands/uninstall.js +114 -0
  6. package/dist/commands/uninstall.js.map +1 -0
  7. package/dist/index.js +10 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/lib/agents/providers.js +44 -4
  10. package/dist/lib/agents/providers.js.map +1 -1
  11. package/dist/lib/memory-update.js +158 -0
  12. package/dist/lib/memory-update.js.map +1 -0
  13. package/dist/lib/uninstall-plan.js +102 -0
  14. package/dist/lib/uninstall-plan.js.map +1 -0
  15. package/package.json +1 -1
  16. package/skills/claude-code/ritual/.ritual-bundle.json +2 -2
  17. package/skills/claude-code/ritual/SKILL.md +14 -11
  18. package/skills/claude-code/ritual/manifest.json +0 -5
  19. package/skills/claude-code/ritual/references/async-polling.md +5 -5
  20. package/skills/claude-code/ritual/references/brief-verification-checklist.md +12 -6
  21. package/skills/claude-code/ritual/references/build-flow.md +569 -581
  22. package/skills/claude-code/ritual/references/change-preflight.md +81 -0
  23. package/skills/claude-code/ritual/references/cli-output-contract.md +44 -28
  24. package/skills/claude-code/ritual/references/context-pulse-flow.md +0 -1
  25. package/skills/claude-code/ritual/references/lite-flow.md +2750 -0
  26. package/skills/claude-code/ritual/references/resume-flow.md +1 -1
  27. package/skills/claude-code/ritual/references/scoring-fallback.md +1 -1
  28. package/skills/codex/ritual/.ritual-bundle.json +2 -2
  29. package/skills/codex/ritual/SKILL.md +14 -11
  30. package/skills/codex/ritual/manifest.json +0 -5
  31. package/skills/codex/ritual/references/async-polling.md +5 -5
  32. package/skills/codex/ritual/references/brief-verification-checklist.md +12 -6
  33. package/skills/codex/ritual/references/build-flow.md +569 -581
  34. package/skills/codex/ritual/references/change-preflight.md +81 -0
  35. package/skills/codex/ritual/references/cli-output-contract.md +44 -28
  36. package/skills/codex/ritual/references/context-pulse-flow.md +0 -1
  37. package/skills/codex/ritual/references/lite-flow.md +2750 -0
  38. package/skills/codex/ritual/references/resume-flow.md +1 -1
  39. package/skills/codex/ritual/references/scoring-fallback.md +1 -1
  40. package/skills/cursor/ritual/.ritual-bundle.json +2 -2
  41. package/skills/cursor/ritual/SKILL.md +14 -11
  42. package/skills/cursor/ritual/manifest.json +0 -5
  43. package/skills/cursor/ritual/references/async-polling.md +5 -5
  44. package/skills/cursor/ritual/references/brief-verification-checklist.md +12 -6
  45. package/skills/cursor/ritual/references/build-flow.md +569 -581
  46. package/skills/cursor/ritual/references/change-preflight.md +81 -0
  47. package/skills/cursor/ritual/references/cli-output-contract.md +44 -28
  48. package/skills/cursor/ritual/references/context-pulse-flow.md +0 -1
  49. package/skills/cursor/ritual/references/lite-flow.md +2750 -0
  50. package/skills/cursor/ritual/references/resume-flow.md +1 -1
  51. package/skills/cursor/ritual/references/scoring-fallback.md +1 -1
  52. package/skills/gemini/ritual/.ritual-bundle.json +2 -2
  53. package/skills/gemini/ritual/SKILL.md +14 -11
  54. package/skills/gemini/ritual/manifest.json +0 -5
  55. package/skills/gemini/ritual/references/async-polling.md +5 -5
  56. package/skills/gemini/ritual/references/brief-verification-checklist.md +12 -6
  57. package/skills/gemini/ritual/references/build-flow.md +569 -581
  58. package/skills/gemini/ritual/references/change-preflight.md +81 -0
  59. package/skills/gemini/ritual/references/cli-output-contract.md +44 -28
  60. package/skills/gemini/ritual/references/context-pulse-flow.md +0 -1
  61. package/skills/gemini/ritual/references/lite-flow.md +2750 -0
  62. package/skills/gemini/ritual/references/resume-flow.md +1 -1
  63. package/skills/gemini/ritual/references/scoring-fallback.md +1 -1
  64. package/skills/kiro/ritual/.ritual-bundle.json +2 -2
  65. package/skills/kiro/ritual/SKILL.md +14 -11
  66. package/skills/kiro/ritual/manifest.json +0 -5
  67. package/skills/kiro/ritual/references/async-polling.md +5 -5
  68. package/skills/kiro/ritual/references/brief-verification-checklist.md +12 -6
  69. package/skills/kiro/ritual/references/build-flow.md +569 -581
  70. package/skills/kiro/ritual/references/change-preflight.md +81 -0
  71. package/skills/kiro/ritual/references/cli-output-contract.md +44 -28
  72. package/skills/kiro/ritual/references/context-pulse-flow.md +0 -1
  73. package/skills/kiro/ritual/references/lite-flow.md +2750 -0
  74. package/skills/kiro/ritual/references/resume-flow.md +1 -1
  75. package/skills/kiro/ritual/references/scoring-fallback.md +1 -1
  76. package/skills/vscode/ritual/.ritual-bundle.json +2 -2
  77. package/skills/vscode/ritual/SKILL.md +14 -11
  78. package/skills/vscode/ritual/manifest.json +0 -5
  79. package/skills/vscode/ritual/references/async-polling.md +5 -5
  80. package/skills/vscode/ritual/references/brief-verification-checklist.md +12 -6
  81. package/skills/vscode/ritual/references/build-flow.md +569 -581
  82. package/skills/vscode/ritual/references/change-preflight.md +81 -0
  83. package/skills/vscode/ritual/references/cli-output-contract.md +44 -28
  84. package/skills/vscode/ritual/references/context-pulse-flow.md +0 -1
  85. package/skills/vscode/ritual/references/lite-flow.md +2750 -0
  86. package/skills/vscode/ritual/references/resume-flow.md +1 -1
  87. package/skills/vscode/ritual/references/scoring-fallback.md +1 -1
  88. package/skills/claude-code/ritual/references/discovery-classification.md +0 -175
  89. package/skills/codex/ritual/references/discovery-classification.md +0 -175
  90. package/skills/cursor/ritual/references/discovery-classification.md +0 -175
  91. package/skills/gemini/ritual/references/discovery-classification.md +0 -175
  92. package/skills/kiro/ritual/references/discovery-classification.md +0 -175
  93. package/skills/vscode/ritual/references/discovery-classification.md +0 -175
@@ -27,7 +27,7 @@ Before running this flow, apply `references/cli-output-contract.md` and `referen
27
27
 
28
28
  **Build rail is load-bearing.** Every top-level user-facing message below MUST begin with the 6-stage build rail per `references/cli-output-contract.md` § Build progress anchor. Examples in this file show the rail in context; the canonical stage table + `progressHeader(stage)` spec lives in the output contract. Do not drop the rail to save space.
29
29
 
30
- For narrow/mobile chat surfaces, use the **compact progress anchor** defined in `references/cli-output-contract.md` § Build progress anchor (the `Ritual build · 2/6 Scope` chip) instead of forcing the full six-stage rail to wrap. Same contract, different rendering.
30
+ For narrow/mobile chat surfaces, use the **compact progress anchor** defined in `references/cli-output-contract.md` § Build progress anchor (the `Ritual build · 1/5 Scope` chip) instead of forcing the full five-stage rail to wrap. Same contract, different rendering.
31
31
 
32
32
  ### When to use
33
33
 
@@ -51,7 +51,7 @@ Use explicit **[USER PAUSE]** only at decision gates. Pause when the user must c
51
51
 
52
52
  ### CLI and async guardrails
53
53
 
54
- Follow `references/cli-output-contract.md` for terminal output, dense-list formatting, user-facing vocabulary, and the no-internal-step-label rule. Follow `references/async-polling.md` for every long-running server operation.
54
+ Follow `references/cli-output-contract.md` for terminal output, dense-list formatting, user-facing vocabulary, and the no-internal-step-label rule. Follow `references/async-polling.md` for every long-running server operation. Whenever the user asks to **change or add** something via free text (refine sub-problems, reframe scope, add an anti-goal), follow `references/change-preflight.md` — restate the request and show the exact instruction before calling the mutating tool, and wait for confirmation. It is a hard pause even in auto-mode.
55
55
 
56
56
  #### Step 0 — Auto-mode heads-up (informational, NOT a pause)
57
57
 
@@ -107,6 +107,17 @@ Persist `auditMode` to `Exploration.metadata.auditMode` at `create_exploration`
107
107
 
108
108
  #### Step 1 — Pick a workspace
109
109
 
110
+ <!-- skill-options:no-gate-change: connection-freshness ping check is a non-interactive warn, adds no user-facing gate or option -->
111
+ **Connection freshness check (one-time, warn-only) — fire on your FIRST MCP call this session.** Alongside the first `list_workspaces` call below, call `mcp__ritual__ping` **once** and inspect the returned identity:
112
+
113
+ - If the response is **missing `gitSha` or `toolContractHash`**, or reports **`version: "1.0.0"`** (the legacy hardcoded value), the user is connected to an **outdated / legacy Ritual MCP** — emit exactly ONE line, then continue normally (warn-only, never block):
114
+
115
+ `⚠ Connected to an outdated Ritual MCP (no build identity) — some build features may be unavailable. Run \`ritual doctor\` to check, then \`ritual init\` if it flags a refresh.`
116
+
117
+ - Otherwise (identity present and not legacy), say nothing and proceed.
118
+
119
+ Do this **at most once per session** — don't re-ping on later steps.
120
+
110
121
  Resolution order:
111
122
 
112
123
  1. **Project-bound workspace (preferred).** Check for a `.ritual/config.json` at the project root (you can use the Read tool — the file is a small JSON with `workspaceId` + `workspaceName`). If it exists, that's the workspace this repo is bound to. Use it without pausing.
@@ -168,7 +179,7 @@ If there are **zero existing explorations** and `raw_input = null`, do not say "
168
179
 
169
180
  ```text
170
181
  Ritual build
171
- Context ○ Scope ○ Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
182
+ ● Scope ○ Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
172
183
 
173
184
  Heads-up: Ritual's build flow needs ~5 real decisions from you (workspace,
174
185
  scope, discovery picks, rec acceptance, implementation approval). If your
@@ -278,7 +289,7 @@ Steps:
278
289
  - Use the state badge to decide which step to jump to (see "Suggested next action" column above).
279
290
  - Skip ahead in this skill — don't re-run Steps 2-9 for an exploration that already has them done.
280
291
  - For `ready` or `in_flight` states, jump directly to Step 10 (build brief generation).
281
- - For `awaiting_admin`, jump to Step 9 (review + accept). Only an admin can move it forward; collaborators see the recs and proceed only if they're explicitly authorized to implement ahead.
292
+ - For `awaiting_admin`, jump to Step 9 (review + `proceed`). Only an admin can move it forward; collaborators see the recs and proceed only if they're explicitly authorized to implement ahead.
282
293
  - For `implemented_ahead`, surface the situation to the user and ask what to do — typically the admin reconciles by either approving the recs post-hoc (no code change needed) or updating the recs to match shipped reality.
283
294
  - **For `done` or `in_flight` — branch-existence sanity check FIRST.** *(CLI Tenet #9 — sanity-check the world before trusting the database.)* The state badge is computed from `ImplementationRecord` rows in the KG. If the KG was seeded from synthetic/bootstrap data (a common state in early pilot deployments), the record can assert a PR/branch that doesn't exist in this repo. Before treating the exploration as ✓ shipped, verify:
284
295
 
@@ -564,11 +575,15 @@ If no seed file is found, OR the seed's `## The ask` doesn't match the current `
564
575
  - use neutral labels like `agent_observed_scope_pressure` or `candidate_scope_pressure`, not `priority_considerations`
565
576
  - never present the packet as authoritative; MCP/tooling decides final sub-problems, recommendations, and scope
566
577
 
567
- C. `recon_digest` — user-visible, compact
568
- - 3–6 bullets max
569
- - key surfaces, hard constraints, scope corrections, and next action
570
- - avoid quoting code comments unless they are load-bearing
571
- - avoid listing every file read
578
+ C. `recon_digest` — **internal-only by default; NOT surfaced to the user.** Recon
579
+ is silent plumbing inside Scope: we do NOT dump repo signals / constraints /
580
+ a recon summary back to the user. Keep a compact digest in working memory for
581
+ your own use (and to render ONLY if the user explicitly asks "what did you
582
+ find?"), but by default show nothing — the user's first gate is the explore
583
+ picker (§ 3.2, only when recon is genuinely ambiguous) or the problem frame
584
+ (Step 5). The `codebase_context_packet` still feeds Step 4 silently.
585
+ - keep it tight if ever shown: key surfaces, hard constraints, scope corrections
586
+ - never list every file read; never quote non-load-bearing comments
572
587
 
573
588
  `codebase_context_packet` structure:
574
589
 
@@ -642,32 +657,15 @@ If no seed file is found, OR the seed's `## The ask` doesn't match the current `
642
657
  Next: attach PRDs/tickets if they should shape scope, or `proceed` to continue.
643
658
  ```
644
659
 
645
- Example `recon_digest`ambiguity case (multiple plausible interpretations):
660
+ **Explore-directions pickerthe ONLY user-visible recon output, and only when recon is genuinely ambiguous.**
646
661
 
647
- When recon surfaces two materially different product/implementation paths for the same ask, name them both, **mark one as recommended with a one-line reason**, and pause with a concrete reply syntax. Do not expose raw tier labels (use the translations from `references/cli-output-contract.md`).
662
+ When (and ONLY when) recon surfaces two+ materially different directions for the same ask, present them as a **pick-one** headed **"What would you like to explore?"** — mark one recommended with a one-line reason, and pause with a concrete reply syntax. Do NOT preface it with a "Repo signals / Constraint" dump (recon is silent), and do NOT justify why the choice matters (no "picking the wrong one wastes scope" — just ask). Do not expose raw tier labels (use the translations from `references/cli-output-contract.md`).
648
663
 
649
664
  ```text
650
- Code recon
651
-
652
- Repo signals:
653
- - `GatewayForm` already supports "create account before checkout," but
654
- redirects away from checkout to `customer:register`. There is no inline
655
- or post-order account path today.
656
- - Guest checkout is already wired through order placement:
657
- `CheckoutSessionData.set_guest_email()`, `AbstractOrder.guest_email`, and
658
- `build_submission()` preserve guest identity.
659
- - `RegisterUserMixin` is the reusable account-creation surface:
660
- user creation, `user_registered`, login, and registration email.
661
- - `OrderPlacementMixin` and `post_checkout` are the clean hooks for
662
- creating or claiming an account at order placement.
663
-
664
- Constraint:
665
- - Oscar's dynamic class loading via `get_class()` is the extension
666
- pattern here. Implement with subclass-overridable views/mixins, not
667
- monkey-patches.
665
+ Ritual build
666
+ ● Scope ○ Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
668
667
 
669
- Ambiguity to resolve:
670
- "Join while booking" maps to two plausible features.
668
+ What would you like to explore?
671
669
 
672
670
  1. Inline registration at checkout
673
671
  Let new customers register on the checkout page itself instead of
@@ -684,15 +682,17 @@ If no seed file is found, OR the seed's `## The ask` doesn't match the current `
684
682
  registration, or describe a different intent. Reply `pause` to stop here.
685
683
  ```
686
684
 
687
- Notes on the ambiguity-case shape:
688
- - **"Repo signals"** (not "Found" or "Key surfaces") signals these are the evidence behind the recommendation.
689
- - **Recommendation goes after the option name on the SAME line**, with a single concise reason on the line below. This keeps the options scannable in a decision moment.
685
+ Notes on the explore-directions shape:
686
+ - **Header is "What would you like to explore?"** an invitation to pick a direction, NOT "Ambiguity to resolve." No preamble dump of repo signals/constraints; recon stays silent.
687
+ - **No editorializing** about why the choice matters (no "wastes scope" / "picking wrong is costly"). The options + the recommendation carry the signal; just ask.
688
+ - **Recommendation goes after the option name on the SAME line**, with a single concise reason on the line below. Keeps the options scannable.
690
689
  - **`Next:` is a single line** ending in a concrete reply syntax (`reply N`), not an open-ended question. Lead with the recommended default; the escape hatch comes last.
691
690
  - **The pulse line uses the user-facing label**, never the raw tier identifier.
691
+ - On pick, feed the chosen direction + the `codebase_context_packet` into Step 4's `generate_considerations`.
692
692
 
693
- Example `recon_digest` — Capability Boundary Check (feature spans systems not in this repo):
693
+ Capability Boundary Check (feature spans systems not in this repo) — **internal/packet-only; NOT displayed:**
694
694
 
695
- When the user's ask requires capabilities that aren't present in this repo (frontend-only repo asked for full-stack feature, mobile repo with no API contract, etc.), surface the boundary as a normal architecture fact and name the three scoping options as **informational** context. **Do not pause on this.** The boundary information is folded into the `codebase_context_packet` so the downstream `generate_considerations` call produces boundary-aware sub-problems against the repo's actual capability surface. The user's first real gate is the problem statement in Step 5 they can reshape scope there if the default narrowing was wrong. NEVER continue as if the repo can implement the missing half; NEVER invent the missing systems.
695
+ When the user's ask requires capabilities that aren't present in this repo (frontend-only repo asked for full-stack feature, mobile repo with no API contract, etc.), capture the boundary + the inferred default scope **into the `codebase_context_packet` only** do **NOT** render it to the user (recon is silent). **Do not pause on this.** The packet drives `generate_considerations` to produce boundary-aware sub-problems against the repo's actual capability surface; the user's first real gate is the problem statement in Step 5, where they reshape scope if the default narrowing was wrong. NEVER continue as if the repo can implement the missing half; NEVER invent the missing systems. The block below is a **reference for what to capture in the packet**, not something to print.
696
696
 
697
697
  ```text
698
698
  Code recon
@@ -743,19 +743,17 @@ If no seed file is found, OR the seed's `## The ask` doesn't match the current `
743
743
  - **The pulse line stays parenthetical** with a user-facing reason (`repo boundary unresolved`), per the Pulse tier labels rule in `references/cli-output-contract.md`.
744
744
  - **Internal classification (not user-facing):** track each candidate piece against the boundary as `in_repo_buildable`, `external_dependency_known`, `external_dependency_unknown`, `needs_additional_repo`, or `contract_first_candidate`. These shape how downstream scoring + build-brief generation handle the missing half. Stamp the inferred default scope as `inferred_scope` in the packet so `generate_considerations` / `generate_problem_statement` see it. None of these labels should appear in user-facing copy.
745
745
 
746
- ##### 3.2 — Surface the digest and continue
746
+ ##### 3.2 — Recon is silent; surface nothing unless ambiguous
747
+
748
+ **Recon runs silently.** Do NOT surface the recon digest, repo signals, constraints, or the `codebase_context_packet` to the user by default — recon is plumbing inside Scope. The packet feeds Step 4; the user sees nothing here.
747
749
 
748
- Surface only `recon_digest` by default. Do **not** dump `raw_recon_notes` or the full `codebase_context_packet` to the CLI unless the user asks for detail.
750
+ **The ONLY user-visible recon output is the explore-directions picker (§ 3.1), and ONLY when recon is genuinely ambiguous** two+ materially different directions for the same ask. Then render **"What would you like to explore?"** and pause for the pick. Do NOT justify why the pick matters (no "wastes scope").
749
751
 
750
- Pause only if:
751
- - recon contradicts the user's stated scope,
752
- - there are multiple plausible implementation areas and choosing wrong would waste work (use the ambiguity-case `recon_digest` shape above),
753
- - a legal/product/business constraint is required before generation,
754
- - the user explicitly asked to review recon before continuing.
752
+ For a crisp, single-direction ask: **render nothing** — go straight to sub-problem generation (Step 4) with the packet. The user's first gate is the problem frame (Step 5), where they reshape scope in plain English if the default was wrong.
755
753
 
756
- **Capability boundary detection does NOT pause.** When recon shows the feature spans systems not in this repo, render the Capability Boundary Check digest from § 3.1 (it's informational), pick the default scope per the "Default narrowing logic" rule, and proceed to Step 3.5. The user reshapes scope at Step 5 (problem-statement gate) if the default narrowing was wrong.
754
+ **Capability boundary detection does NOT pause and is NOT displayed.** When recon shows the feature spans systems not in this repo, fold the boundary + the inferred default scope into the `codebase_context_packet` (silent — see § 3.1 internal classification), pick the default scope per the "Default narrowing logic" rule, and proceed. The user reshapes scope at Step 5 if needed.
757
755
 
758
- If no pause is needed, proceed to Step 3.5. The user still has a cheap escape hatch: `recon: detail`, `recon: refresh`, or a correction in plain English.
756
+ If the user explicitly asks "what did you find?", you may show a tight digest then otherwise stay silent.
759
757
 
760
758
  **Pulse (Step 3 done):** Emit a pulse line — repo grounding just moved meaningfully (sources collected, agent inspected files, possibly KG hits). Compute per `/ritual context-pulse` § Step CP3 and render compact unless this is the FIRST pulse of the build flow, in which case use full.
761
759
 
@@ -778,36 +776,11 @@ Keep the list focused. 5–10 is the sweet spot; >20 dilutes the KG signal.
778
776
 
779
777
  The codebase recon you just did handles the *code* grounding. Most real features ALSO have non-code context — PRDs, Jira/Linear tickets, design specs, meeting transcripts, Slack threads, customer-research notes — that get paraphrased into the problem statement and lose detail. Step 3.5 ingests those as first-class **knowledge sources** attached to the exploration BEFORE generating sub-problems, so the priorContext you'll see in Step 4 (`generate_considerations`) and downstream is grounded in what the user actually brought, not the paraphrase.
780
778
 
781
- ##### 3.5.1 — Prompt the user only when useful
779
+ ##### 3.5.1 — Reactive only do NOT prompt for non-code context
782
780
 
783
- Knowledge sources are a feature multiplier, not a mandatory gate. Ask for PRDs/tickets/designs/transcripts only when at least one of these is true:
781
+ **Do NOT proactively ask the user to attach PRDs/tickets/designs/transcripts.** This is a pure capability, not a gate surfacing an "Optional: add non-code context" prompt before the user has even framed the problem is front-of-flow friction we deliberately removed (it also tends to over-justify *why* it matters, which is internal reasoning the user doesn't need). There is **no pause here.**
784
782
 
785
- - the ask is ambiguous or cross-functional,
786
- - context-pulse / Reference Grounding is low,
787
- - the user mentioned a PRD, ticket, design, chat, customer request, or meeting,
788
- - the feature has legal, privacy, billing, permissions, enterprise, analytics, migration, or compliance constraints,
789
- - code recon found implementation surfaces but not product intent.
790
-
791
- When triggered, frame references as an optional booster, not a mandatory phase. The happy path is to continue. Keep the prompt tight — the user's decision here is simply "attach context or continue":
792
-
793
- ```text
794
- Optional: add non-code context before scope generation.
795
-
796
- Because this touches {constraint}, PRDs, tickets, designs, incidents, or
797
- customer requests may change what we prioritize.
798
-
799
- Reply `go` to continue with code context only.
800
- Or paste files/text/URLs to attach context first.
801
- Reply `pause` to stop here.
802
- ```
803
-
804
- Accept (alias) `go`, `g`, `generate`, `continue`, `skip`, `next`, or `none` as proceed. Per `references/cli-output-contract.md` § Surface-aware continuation prompts, do NOT treat empty input as proceed inside agent chat — chat surfaces can't reliably observe an empty message. Wait only if the user provides refs, asks a question, or types `pause` / `stop`.
805
-
806
- Process language like *"Next: we'll generate a list of suggested problems to pick from"* used to live here — removed because the decision at this moment is "attach context or continue," not a preview of what comes next. The follow-up step's framing belongs in the follow-up step, not stacked on this prompt.
807
-
808
- If none of the triggers apply, do **not** block. Print a non-blocking line and proceed:
809
-
810
- > Proceeding with codebase context only. Paste a PRD/ticket anytime before discovery if it should shape the scope.
783
+ Handle knowledge sources **only reactively**: if the user *spontaneously* pastes a file/URL/text or says "use this PRD/ticket," ingest it via 3.5.2–3.5.4 below. Otherwise say nothing and proceed silently to Step 4 with code context only. The user can always attach context later via `/ritual context-pulse <exploration>` or by dragging refs in mid-flow.
811
784
 
812
785
  ##### 3.5.2 — Read the content
813
786
 
@@ -885,6 +858,55 @@ If the user says "skip" / "none" / "later", proceed silently to Step 4. Do NOT p
885
858
 
886
859
  The user can always come back later with `/ritual context-pulse <exploration>` to see the current Reference Grounding score, OR drag refs in mid-flow (e.g. at Step 8 if the agentic run surfaces a question that a PRD would have answered).
887
860
 
861
+ #### Step 3.9 — Classify the work item + pick the lead persona
862
+
863
+ Before generating sub-problems, settle **what job this is** and **whose lens leads it** — both shape
864
+ everything downstream, so they come first. **You** classify the job (you have the repo open — you're the
865
+ best-informed classifier, and doing it here saves a backend LLM call); the server returns the lenses.
866
+
867
+ 1. **Classify the request** into ONE development work-item slug, using the user's raw ask + your code
868
+ recon:
869
+
870
+ ```text
871
+ understand-codebase-area · design-technical-approach · create-implementation-plan ·
872
+ build-frontend-feature · build-backend-service · integrate-api · create-docs-site ·
873
+ refactor-code · debug-production-issue · improve-performance · add-tests · prepare-release
874
+ ```
875
+
876
+ (Use `build-feature` only when the ask is a generic build that none of the specific jobs fit.) Pick the
877
+ single best match — e.g. "add OAuth to the dashboard" → `build-backend-service`; "the checkout page is
878
+ slow" → `improve-performance`; "clean up the payments module" → `refactor-code`.
879
+
880
+ 2. **Call `mcp__ritual__work_item`** with that `jtbd` (and `entry_use_case` if known). It returns
881
+ `{ workItemLabel, deliverableTemplate, recommended, options: [{ persona, label, whenToChoose }] }` —
882
+ deterministic, no LLM, already biased by the user's `ritual init` persona.
883
+
884
+ 3. **Present the work item + lens options** as a `(label + description)` bottom-drawer choice picker
885
+ (same shape as discovery picks, per `references/cli-output-contract.md`), recommended lens first and
886
+ marked:
887
+
888
+ ```text
889
+ This looks like: Build backend service / API → Service Build Brief
890
+ Who's leading it? (recommended: Backend Developer)
891
+
892
+ 1. Backend Developer — Best when you care about API contracts, data, transactions, scaling. ← recommended
893
+ 2. Developer — Best when you care about feasibility, implementation correctness, shippability.
894
+ 3. Eng Lead — Best when you care about technical approach, risk, sequencing, review.
895
+
896
+ Reply `use` to lead as Backend Developer, a number to switch, or name a lens.
897
+ ```
898
+
899
+ 4. **Default = the recommended lens.** An ambiguous reply (`use`/`ok`/`go`) accepts it. If the user says
900
+ the *work item* is wrong ("no, this is a refactor"), re-classify and call `work_item` again. If they
901
+ switch the *lens*, that's a change → run the change pre-flight (`references/change-preflight.md`) to
902
+ confirm before adopting it.
903
+
904
+ 5. **Remember the chosen `persona` slug** — you pass it through to `create_exploration` as `lead_persona`
905
+ at Step 6. (It also carries into the generation prompts once persona-aware generation ships; for now
906
+ it's persisted + surfaced.)
907
+
908
+ Keep this light — one drawer, recommended pre-selected; most users accept. Don't belabour it.
909
+
888
910
  #### Step 4 — Generate sub-problems
889
911
 
890
912
  ##### 4.1 First draft
@@ -916,7 +938,7 @@ If `implementationCount === 0`: don't mention the KG check (silent — would jus
916
938
 
917
939
  ```text
918
940
  Ritual build
919
- ✓ Context ● Scope ○ Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
941
+ ● Scope ○ Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
920
942
 
921
943
  Solving for these sub-problems
922
944
 
@@ -938,6 +960,8 @@ Only the title line gets the number. Put a blank line between candidates. Do not
938
960
 
939
961
  The user may, at the Step 5 problem-statement gate, say something like "rethink the sub-problems" or "the framing is off — show me other angles." When that happens, call `mcp__ritual__refine_considerations` and re-render the sub-problem set + a fresh problem statement. In the default flow this path is unreachable; it exists for the explicit "rethink scope" escape hatch.
940
962
 
963
+ **Pre-flight (mandatory):** before calling `refine_considerations`, run the change pre-flight in `references/change-preflight.md` — restate the change in the user's terms, show the exact `change_prompt` you're about to send, and wait for `yes`. This is a hard pause (even in auto-mode) and fires on every such request, including one-word ones. Do not call the tool until the user confirms.
964
+
941
965
  Call `mcp__ritual__refine_considerations` with:
942
966
  - `workspace_id`, `raw_input`, `sources` — unchanged from the generate call. Critical: pass the SAME `sources` array each iteration so the KG-injected priorContext stays consistent.
943
967
  - `template_id` — same rule as Step 4: omit unless the user explicitly overrode it. If you passed `template_id` to the original `generate_considerations` call, pass the same value here for symmetry; otherwise leave it off and let server-side resolution stay consistent across iterations.
@@ -1006,6 +1030,8 @@ Rules:
1006
1030
 
1007
1031
  If the user asks for a refinement:
1008
1032
 
1033
+ **Pre-flight (mandatory):** before calling `refine_problem_statement`, run the change pre-flight in `references/change-preflight.md` — restate the change in the user's terms, show the exact `change_prompt` you're about to send, and wait for `yes`. This is a hard pause (even in auto-mode) and fires on every refinement request, including a one-word `tighten`/`broaden`. Do not call the tool until the user confirms.
1034
+
1009
1035
  Call `mcp__ritual__refine_problem_statement` with:
1010
1036
  - `workspace_id`, `raw_input`, `considerations`, `sources` — unchanged. (Same `sources` as the original generate call — keeps the KG anchor stable.)
1011
1037
  - `template_id` — same rule as Step 4 / Step 5.1: omit unless the user explicitly overrode; if you passed it to the original `generate_problem_statement` call, pass the same value here for symmetry.
@@ -1026,7 +1052,7 @@ When the user locks the frame, store the final text as `problem_statement` for S
1026
1052
 
1027
1053
  Generate a short name (≤60 chars) from the scope — typically the noun phrase, not the full HMW. E.g. "Reduce T2 customer churn in Q3" → name `T2 churn reduction (Q3)`.
1028
1054
 
1029
- Do not add another confirmation if the user just accepted the problem frame. Create the exploration immediately after the user replies `use`/`proceed`. If a name is ambiguous, **choose the shortest clear noun phrase and continue without pausing** — the name is editable later and shouldn't become a decision gate. Do NOT rely on "proceed on Enter" or empty input in agent chat (see `references/cli-output-contract.md` § Surface-aware continuation prompts).
1055
+ Create the exploration immediately once the frame is locked the work item + lead persona were already settled at Step 3.9, so do not add a *further* confirmation here. If a name is ambiguous, **choose the shortest clear noun phrase and continue without pausing** — the name is editable later and shouldn't become a decision gate. Do NOT rely on "proceed on Enter" or empty input in agent chat (see `references/cli-output-contract.md` § Surface-aware continuation prompts).
1030
1056
 
1031
1057
  User-visible before the call, if needed:
1032
1058
 
@@ -1040,14 +1066,16 @@ Call `mcp__ritual__create_exploration` with:
1040
1066
  - `problem_statement` (the scope from Step 5)
1041
1067
  - `template_id` — **OPTIONAL.** Per Step 2, omit by default. The server resolves from `explicit dto.templateId → workspace.defaultTemplateId → user.persona → first SYSTEM template`, then forks the resolved template into a per-exploration Template row atomically inside this same `create_exploration` request. Pass `template_id` ONLY when the user explicitly overrides on the CLI (`/ritual build --template-id <id>`). If you passed `template_id` to Step 4's `generate_considerations`, pass the same value here so the LLM prompt context the considerations were generated under matches the exploration's stamped template. Do NOT read `.ritual/config.json` or invent a `template_id` from persona — the server does the resolution.
1042
1068
  - `agentic: false` — **do NOT** pass `agentic: true`. We want explicit per-step control so the user gets to pick discovery questions in Step 7. Auto-agentic skips that.
1069
+ - `jtbd` — **REQUIRED for `/ritual build`.** The work-item slug you classified at **Step 3.9** (e.g. `'build-backend-service'`, `'refactor-code'`, or `'build-feature'` for a generic build). Tags the exploration's job-to-be-done so the workflow surfaces the build-brief → code-plan → implement → PR deliverable phase across every surface (the Spark panel, etc.), not the generic produce-deliverable flow. Omit only if this is a non-build exploration (defaults to `produce-deliverable`).
1070
+ - `lead_persona` — the lens slug the user chose at **Step 3.9** (e.g. `'backend-developer'`). Pass the chosen `persona` from `work_item`. Omit only if Step 3.9 was skipped — the server then resolves the jtbd's canonical lens. Unknown slugs are ignored server-side.
1043
1071
 
1044
1072
  Store `exploration_id`. Move the progress header from Scope to Discovery:
1045
1073
 
1046
1074
  ```text
1047
1075
  Ritual build
1048
- Context ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
1076
+ ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
1049
1077
 
1050
- Exploration created. Track progress at https://app.ritualapp.cloud/e/{exploration_id}
1078
+ Exploration created.
1051
1079
 
1052
1080
  Next: generate discovery questions to resolve the implementation trade-offs.
1053
1081
  ```
@@ -1097,6 +1125,7 @@ Surface a single compact summary after all registrations resolve:
1097
1125
 
1098
1126
  **Why this lives at 6.2, not inside `create_exploration`:** sources are deliberately decoupled from the exploration row so a partial source-registration failure doesn't block exploration creation. Step 6 must always succeed if the underlying validation passes; Step 6.2 is best-effort on top.
1099
1127
 
1128
+ <!-- lite:skip-start reason="unpicked-consideration preservation is not part of lite" -->
1100
1129
  #### Step 6.5 — Preserve unpicked considerations without cluttering the workspace
1101
1130
 
1102
1131
  Unpicked or dismissed considerations are useful signal, but automatically creating sibling explorations can clutter the workspace. Do **not** fork sibling explorations by default.
@@ -1123,6 +1152,7 @@ If sibling creation is confirmed, call:
1123
1152
 
1124
1153
  Then summarize the created siblings in the dense-list format. Do not pause after creation; return to the primary build flow.
1125
1154
 
1155
+ <!-- lite:skip-end -->
1126
1156
  #### Step 7 — Discovery questions
1127
1157
 
1128
1158
  Longest phase because generation is async + the user picks per-Area. (Internally the API field is `matter_id`; user-facing copy always says Area.)
@@ -1131,16 +1161,22 @@ Longest phase because generation is async + the user picks per-Area. (Internally
1131
1161
 
1132
1162
  1. Call `mcp__ritual__suggest_discovery_questions(exploration_id)` (Step 7.1) — no user input needed; just kick it off.
1133
1163
  2. Poll `mcp__ritual__get_discovery_state(exploration_id)` until `ready: true` (Step 7.2).
1134
- 3. Render the Areas index per § 7.3.1 (NOT a free-form listsee § 7.3.1 rendering anti-pattern below).
1135
- 4. `[USER PAUSE]` — the user picks Areas + questions, or types `accept shortlist` / `skip discovery`.
1136
- 5. Call `mcp__ritual__accept_discovery_questions` for each picked Area (Step 7.4).
1137
- 6. Evaluate Step 7.4.5 triggers; render the scope-classification gate if any fire.
1138
- 7. ONLY THEN proceed to Step 8 and render the *"Reply `run` to continue"* CTA.
1164
+ 3. Render the **Area rail + Area 1's questions together** and walk Area-by-Area per § 7.3.1 (the rail orients; a rail with NO questions under it a bare index is the failure mode).
1165
+ 4. `[USER PAUSE]` — the user picks questions across Areas (**floor: 6 to run; aim for 15–20; no cap**), or types `accept shortlist`.
1166
+ 5. Commit all picked Areas in ONE `mcp__ritual__accept_discovery_questions_batch` call (Step 7.4) — never one parallel call per Area.
1167
+ 6. Optionally capture anti-goals (Step 7.5), then proceed to Step 8 and render the *"Reply `run` to continue"* CTA.
1168
+
1169
+ **Picking is a deliberate step-through, not a bulk action (load-bearing):** the user going Area by Area and choosing the questions that matter IS the value of discovery — that per-question judgment shapes the whole downstream chain. So **nudge the user to step through and pick**; don't lead with bulk shortcuts.
1170
+ - **Nudge to step through.** Walk the user Area-by-Area (drop into Area 1, `next`/`prev`) and invite deliberate picks per Area, with `show more` to expand an Area. The framing is "which of these should we dig into?", not "want all of them?".
1171
+ - **Floor (HARD): at least 6 questions** across any Areas — below this, do NOT commit or proceed (tell them how many more to pick and keep them in the picker). There is NO "skip discovery" path — the agentic run needs a real question set to develop answers against. **Good coverage (SOFT): 15–20 questions** — nudge toward it on the Summary, but never block once ≥6. **No upper cap** — picking many (or all) is a legitimate explicit choice, never a default or fallback. (Uncovered scope is handled downstream when recommendations + requirements are generated and audited, so a thin set is the failure mode to prevent.)
1172
+ - **The default is the shortlist, never "all."** For a user who doesn't want to step through every Area, **`accept shortlist` (the 6–10 highest-leverage questions)** is the convenience default. An ambiguous reply (`proceed`, `go`, `ok`) at this gate means **accept the shortlist** — never silently accept everything.
1173
+ - **Taking all IS allowed — but only as an explicit user choice, never the default or a fallback.** If the user genuinely says "take all" / "all of them", honor it and commit them; that's a legitimate choice, not an error. Just never *offer* "I'll take all" as the default, and never auto-fall-back to it. (Worth mentioning once, not as a gate: every accepted question is answered individually in the agentic run, so accepting all of them across every Area means many more questions to answer and a much longer run — but it's the user's call.)
1139
1174
 
1140
1175
  **Forbidden behaviors:**
1141
1176
 
1142
- - Calling `start_agentic_run` before `accept_discovery_questions` has been called at least once for this exploration. (`skip discovery` is the explicit exception it intentionally takes the no-picks path through 7.4.5.)
1177
+ - Calling `start_agentic_run` before at least 6 discovery picks have been committed for this exploration (via `accept_discovery_questions_batch`, or `accept_discovery_questions`). There is no skip-discovery exception.
1143
1178
  - Silently auto-picking all generated questions and proceeding to Step 8 — observed in agent output 2026-05-15 as "the engineering-mode default is to run, which skips the per-question picker." There is no such default; the picker is mandatory.
1179
+ - **Offering "or I'll default to taking all of them" (or any accept-all fallback), then committing the full set on an ambiguous reply** — observed 2026-06-05 (a `proceed` at this gate → `accept_discovery_questions_batch` with all 68 questions → a ~25-min run the user never chose). Accept-all is a legitimate choice **only when the user explicitly asks for it** — it is NEVER the default you offer, and NEVER the fallback. The default you offer + fall back to is always **`accept shortlist`** (6–10). An ambiguous reply (`proceed`/`go`/`ok`) at the pick gate means **accept the shortlist**, not the full set. Lead by nudging the user to step through Areas and pick deliberately.
1144
1180
  - Rendering "Next: run discovery through recommendations / Reply `run` to continue" anywhere in the chat before Step 7.4 has completed.
1145
1181
 
1146
1182
  The picker is **not** a UI suggestion — it's the load-bearing decision gate where the user expresses what to investigate. Skipping it converts the agentic run into an automated "answer everything" pass and erases the user's judgment.
@@ -1151,7 +1187,7 @@ Call `mcp__ritual__suggest_discovery_questions(exploration_id)`. Returns immedia
1151
1187
 
1152
1188
  ```text
1153
1189
  Ritual build
1154
- Context ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
1190
+ ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
1155
1191
 
1156
1192
  Generating discovery questions for each area…
1157
1193
  ```
@@ -1160,29 +1196,40 @@ Generating discovery questions for each area…
1160
1196
 
1161
1197
  Loop:
1162
1198
  - Call `mcp__ritual__get_discovery_state(exploration_id)`
1163
- - If `ready: false`, wait 5 seconds, poll again
1199
+ - If `ready: false`, wait 10 seconds, poll again
1164
1200
  - If `ready: true`, exit loop
1165
1201
 
1166
- Don't poll faster than every 5 seconds. Follow the global polling rule above: single `Bash sleep 5` per iteration and a one-line update every ~3 polls (~15s). Polling heartbeats are exempt from the Build rail rule per `references/cli-output-contract.md` § Build progress anchor — does NOT apply to.
1202
+ Don't poll faster than every 10 seconds (matches the Spark UI's 10s discovery cadence). Follow the global polling rule above: single `Bash sleep 10` per iteration and a one-line update every ~2 polls (~20s). Polling heartbeats are exempt from the Build rail rule per `references/cli-output-contract.md` § Build progress anchor — does NOT apply to.
1167
1203
 
1168
- ##### 7.3 — Area-first picker (Areas index drill into an Area return to index)
1204
+ ##### 7.3 — Matter-walk picker (Area rail + selected Area's questionswalk with `next`/`prev` → Summary)
1169
1205
 
1170
1206
  The state contains `matters[]`, each with `id`, `name`, and `questions[]`. Internally these are `matter`s; user-facing copy ALWAYS calls them **Areas**.
1171
1207
 
1172
- DO NOT lead with a curated cross-area question list. It reads as the agent having pre-selected the answer and asking the user to rubber-stamp; the user's job at this moment is scanning the space and picking where to spend investigation. Use a two-level picker: Areas index first, then per-Area question detail, then back to the index with status markers.
1208
+ This MIRRORS the Spark `/discover` picker exactly: Spark shows a **tab bar of all Areas with one tab selected AND that tab's questions already rendered below it**. The CLI does the same in text — every render shows a compact **Area rail** (all Areas, the current one marked, with running picked counts) **and, directly beneath it, the current Area's questions**. The user picks questions, then moves between Areas with `next`/`prev`, and finally lands on a **Summary** grouped by Area before committing. Seeing each Area's questions and choosing deliberately IS the value of discovery.
1209
+
1210
+ The two failure modes this contract prevents:
1211
+ - **A bare Area index** — the rail (or a "pick an Area" menu) with **no questions under it**. The rail without its current Area's questions is exactly the removed model; always render the questions inline. (This is the failure d3 caught on 2026-06-07: the agent rendered the Area list alone.)
1212
+ - **A full dump** — every Area's questions in one message. Only the **current** Area's questions render per turn.
1213
+
1214
+ **Turn boundaries (load-bearing — this is a multi-turn walk, not a one-shot render).** Render the rail + **exactly ONE Area's questions per turn**. After rendering, **STOP and end your turn** — wait for the user's reply (`numbers` / `next` / `prev` / `skip` / `done`). Each of `next` / `prev` / `done` produces the **next render in a NEW turn**, never appended to the current message. You already hold every Area's questions from `get_discovery_state` — that is NOT license to render the whole walk or multiple Areas' questions in a single message. The rail lists Area *names + counts* (cheap orientation); only the current Area's *questions* render. One Area → STOP → reply → next Area. The Summary (§ 7.3.3) is likewise its own turn.
1173
1215
 
1174
1216
  ###### 7.3.0 — Compute per-Area recommendations + the global shortlist (internal, not user-facing)
1175
1217
 
1176
- Two computations happen before the index renders. Both stay internal — they show up as counts on the index, not as auto-applied picks.
1218
+ Three things surface, **none auto-applied**:
1219
+ - **(a) The Area rail** — every Area's name + its running picked count. Cheap orientation (names + counts, NOT their questions), shown above the current Area's questions from the very first render. This is the legitimate, always-visible "tab bar" — it is NOT the forbidden bare index, *because the current Area's questions always render beneath it*.
1220
+ - **(b) The per-Area ★ recommended set** (3–4 questions) — computed for the Area you are currently showing.
1221
+ - **(c) The global shortlist** (6–10 across all Areas) — computed only when the user types `accept shortlist`.
1177
1222
 
1178
- **Per-Area recommended counts** (what to suggest when the user drills into an Area):
1223
+ The user always picks; nothing is auto-committed.
1224
+
1225
+ **Per-Area recommended set** (the ★ set, for the Area currently shown):
1179
1226
 
1180
1227
  - Pick the top 3–4 questions per Area most likely to shape the recommendations, based on the problem statement, locked sub-problems from Step 4, and the codebase recon context from Step 3. Bias toward questions whose absence would force later stages to invent consequential facts.
1181
1228
  - Area has **< 4 questions**: all are recommended.
1182
1229
  - Area has **4–7 questions**: top 3 are recommended.
1183
1230
  - Area has **8+ questions**: top 4 are recommended.
1184
1231
 
1185
- **Global shortlist** (what `accept shortlist` accepts when used from the index):
1232
+ **Global shortlist** (what `accept shortlist` accepts available from any Area or the Summary):
1186
1233
 
1187
1234
  - Pick **6–10 questions TOTAL across all Areas**, biased toward questions most likely to change recommendations.
1188
1235
  - Preserve Area diversity by default — at least one question from each Area where the per-Area recommended set was non-empty, unless the scope is clearly concentrated (e.g. one Area dominates the recon evidence).
@@ -1191,246 +1238,197 @@ Two computations happen before the index renders. Both stay internal — they sh
1191
1238
 
1192
1239
  Neither set is auto-applied. The user still picks per Area, or uses `accept shortlist` as a power path that bypasses the area-by-area drill.
1193
1240
 
1194
- ###### 7.3.1 — Areas index (landing)
1241
+ ###### 7.3.1 — First render: Area rail + Area 1's questions (the walk begins)
1195
1242
 
1196
- Full rail + intro + numbered Areas list with `{recommended} recommended · {total} total` per Area. NO question text on this screen just the surface map. This is the first message of the picker; the rail has already been emitted, so subsequent area-detail messages use the in-phase chip.
1243
+ Open ON Area 1 with the **rail above and Area 1's questions below it** never the rail alone. The rail lists every Area (current one marked, picked count per Area); the questions are Area 1's recommended set. Full phase rail on this first message (we just entered Discovery); subsequent Area messages use the in-phase chip.
1197
1244
 
1198
1245
  ```text
1199
1246
  Ritual build
1200
- Context ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
1201
-
1202
- Question picking
1203
-
1204
- Ritual generated questions across {N} areas for the {M} locked sub-problems:
1205
- {first sub-problem name} + {second sub-problem name}.
1206
-
1207
- Pick an Area to review. I'll show the 3–4 questions most likely to change
1208
- the implementation plan.
1209
-
1210
- Areas:
1211
-
1212
- 1. {Area name 1} {N} recommended · {N} total
1213
- 2. {Area name 2} {N} recommended · {N} total
1214
- 3. {Area name 3} {N} recommended · {N} total
1215
- ...
1216
-
1217
- Reply with an Area number, `accept shortlist`, or `skip discovery`.
1218
- Inside an Area, use `show more` to see the rest.
1219
- ```
1247
+ ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
1220
1248
 
1221
- Number alignment: right-pad the Area name to a consistent column so the counts line up vertically. Drop the `accept shortlist` token when no Area has recommendations (rare; just show the area-number + `skip discovery` CTAs).
1249
+ Question picking · Area 1 of {N} · {Area name} picked so far: 0
1222
1250
 
1223
- **Rendering anti-pattern (load-bearing) the Areas index renders ONLY area names + counts. Observed violations 2026-05-15:**
1251
+ Areas ● {Area name 1} ○ {Area name 2} ○ {Area name 3} ○ {Area name 4} ○ {Area name 5}
1252
+ ● current · ✓N after a name = picked in that Area · move with `next` / `prev`
1224
1253
 
1225
- - Question previews under each area:
1226
- ```text
1227
- 1. Wishlist Visibility Contract (10 qs)
1254
+ Ritual generated questions across {N} areas for {M} locked sub-problems.
1255
+ I'll walk you through each — aim for 15–20 total (6 minimum to run, no cap).
1228
1256
 
1229
- 1. How PUBLIC/SHARED behave across owner controls...
1230
- 2. Shared Wishlist Surfaces (8 qs)
1257
+ Showing the {k} most likely to change the plan ({total} in this Area):
1231
1258
 
1232
- 2. Which entry points light up first...
1233
- ```
1234
- No. This invents question previews the SKILL never asked for, AND uses overlapping numbering (`1. {area}` and `1. {question preview}`) that creates ambiguity — when the user replies `5`, neither side can tell what they meant. Single numbering stream: areas only.
1235
-
1236
- - ❌ Free-form bullet lists, "for your convenience" question summaries, or any text under the area line beyond `{N} recommended · {N} total`.
1237
-
1238
- - ❌ Adding a "TL;DR" / "highlights" section above or below the Areas list.
1239
-
1240
- **The correct shape is exactly** (no exceptions):
1259
+ 1. {recommended question 1, wrapped readably}
1260
+ 2. {recommended question 2, wrapped readably}
1261
+ 3. {recommended question 3, wrapped readably}
1241
1262
 
1242
- ```
1243
- Areas:
1244
-
1245
- 1. {Area name} {N} recommended · {N} total
1246
- 2. {Area name} {N} recommended · {N} total
1247
- ...
1263
+ pick numbers (e.g. `1,3`) · `suggested` (these ★) · `add <your question>` · `show more` ({total−k} more)
1264
+ walk `next` · `prev` · `skip` · `done` (≥6) · `accept shortlist`
1248
1265
  ```
1249
1266
 
1250
- If the user wants to see questions, they pick an Area number that's what § 7.3.2 (Area detail) is for. **Do not pre-empt their drill choice with question previews.** Same rule as Step 9.1's "use server preview verbatim, do not free-form-summarize on top."
1267
+ **Single numbering stream — number the QUESTIONS only; the rail Areas are NOT numbered.** The 2026-05-15 failure numbered Areas AND question previews in one view, so a reply of `5` was ambiguous. Here the rail uses `●`/`○` markers + names (no numbers) and you move it with `next`/`prev` — the only numbered list is the current Area's questions, so a bare number is never ambiguous. Wrap long question text readably. The `picked so far` count, the rail markers/`✓N` counts, and the `Area i of N` breadcrumb all update on every render of the walk.
1251
1268
 
1252
- **Why `accept shortlist`, not `accept recommended`:**
1269
+ **Why `accept shortlist`, not `accept recommended`:** "recommended" is ambiguous (per-Area? global?). The picker uses **shortlist** for the global 6–10 power path (§ 7.3.0), keeping a clean vocabulary split: **discovery = `accept shortlist`** (questions), **recommendation review = `proceed`** (Step 9). The ★ marks the per-Area recommended set; `suggested` picks it.
1253
1270
 
1254
- - "Recommended" is ambiguous (recommended per Area? globally? by category? recommended *recs* later in the flow?). The discovery picker uses **shortlist** explicitly because the shortlist is global (6–10 questions across all Areas, computed in § 7.3.0)distinct from per-Area recommended counts shown alongside each Area, and distinct from the later `accept recommended` action that accepts implementation themes in Step 9.
1255
- - This creates a clean vocabulary split: **discovery = `accept shortlist`** (questions), **recommendations = `accept recommended`** (themes).
1271
+ ###### 7.3.2Within an Area (pick, then move)
1256
1272
 
1257
- **Don't advertise global `show all` at the index.** Showing every question across every Area can be a screen-flooding wall. The escape hatch the user actually needs is **`show more` inside an Area** (lazy expansion per Area), not a global dump. Accept `show all` as a reply but don't list it as a visible CTA on the index.
1273
+ **Every render in this section keeps the `Areas …` rail line on top** (current Area marked, `✓N` counts updated) it's omitted from the snippets below only for brevity. Never re-render an Area's questions without the rail above them.
1258
1274
 
1259
- ###### 7.3.2 Area detail (one Area's questions)
1260
-
1261
- When the user picks an Area number, show that Area's **top recommended questions** by default. Hold the rest behind `show more`. In-phase chip, NOT full rail (rail was emitted on the index).
1275
+ - **`numbers`** (e.g. `1,3` or `1,2,5`): add those questions to the picked set, re-render this Area (rail + questions) with `✓` on the picked rows + the updated `picked so far`, then prompt `next` / `prev` / `done`.
1276
+ - **`suggested`**: pick this Area's recommended (★) set in one go.
1277
+ - **`show more`**: reveal the rest, grouped Recommended / More (lazy per-Area expansion never a global dump):
1262
1278
 
1263
1279
  ```text
1264
- Question picking · {Area name}
1265
-
1266
- Showing {N} recommended questions out of {total}.
1267
-
1268
- 1. {question 1, wrapped readably}
1269
-
1270
- 2. {question 2, wrapped readably}
1271
-
1272
- 3. {question 3, wrapped readably}
1273
-
1274
- Reply with numbers like `1,2` to pick, `show more` to see all {total},
1275
- or `skip` to leave this Area without picks.
1276
- ```
1277
-
1278
- `show more` reveals the rest of the questions, formatted in two groups (Recommended / More):
1279
-
1280
- ```text
1281
- Question picking · {Area name}
1280
+ Question picking · {Area name} picked so far: {T}
1282
1281
 
1283
1282
  Recommended:
1284
-
1285
- 1. {recommended question 1}
1283
+ 1. {recommended question 1} ✓
1286
1284
  2. {recommended question 2}
1287
1285
  3. {recommended question 3}
1288
1286
 
1289
1287
  More questions:
1290
-
1291
1288
  4. {non-recommended question 1}
1292
1289
  5. {non-recommended question 2}
1293
- 6. {non-recommended question 3}
1294
- 7. {non-recommended question 4}
1295
1290
  ...
1296
1291
 
1297
- Reply with numbers like `1,2,5`, or `skip`.
1292
+ Reply numbers (e.g. `1,4`), `next`, `prev`, or `skip`.
1298
1293
  ```
1299
1294
 
1300
- ###### 7.3.3 Return to Areas index with status markers
1301
-
1302
- After the user picks for an Area (or skips), return to the Areas index with status markers reflecting what's been resolved. Use `✓` for picked, `–` for skipped, `□` for not-yet-touched. NEVER use strikethrough — it renders inconsistently across terminals.
1295
+ - **`next` / `prev`**: move to the next / previous Area (picks preserved). At the last Area, `next` goes to the Summary 7.3.3).
1296
+ - **`skip`**: leave this Area with no picks, advance to `next`.
1297
+ - **`done`**: jump straight to the Summary (allowed from any Area).
1298
+ - **`pause`**: stop here — state is saved, nothing committed.
1299
+ - **`show all`**: accepted as a reply (expands every Area's questions into one long list) but NOT advertised on the CTA line — per-Area `show more` is the default, not a global wall.
1300
+ - **`add <your question>`** (e.g. `add How should we handle partial refunds?`): add a USER-AUTHORED question to THIS Area. **Pre-flight format-validate it locally first:** it must read as a single, clear question (non-empty, interrogative or ends with `?`, ≤ ~200 chars). If it's malformed (a statement, a fragment, multiple questions, too long), say what's off and ask them to rephrase — do NOT hold a malformed one. When valid, **hold it locally** for this Area and re-render the Area (rail + questions) with it shown as `+ (your) {text}` beneath the questions, `picked so far` incremented. It counts toward the floor/target like any pick. It is NOT written to the server yet — every custom question is persisted in ONE batch at `commit` (§ 7.4).
1303
1301
 
1304
- ```text
1305
- Question picking
1302
+ ###### 7.3.3 — Summary (after the last Area, or on `done`) — the review-before-commit gate
1306
1303
 
1307
- Areas:
1304
+ Render all picks grouped by Area. This MIRRORS Spark's Summary tab and is the gate where the user confirms before the run. Use `✓` picked / `—` none / `□` untouched. NEVER strikethrough (renders inconsistently across terminals).
1308
1305
 
1309
- ✓ 1. {Area name 1} {N} picked
1310
- 2. {Area name 2} {N} recommended · {N} total
1311
- □ 3. {Area name 3} {N} recommended · {N} total
1312
- 4. {Area name 4} skipped
1306
+ ```text
1307
+ Question picking · Summary {T} picked
1308
+
1309
+ 1. {Area name 1} {n} picked
1310
+ – {picked question}
1311
+ – {picked question}
1312
+ — 2. {Area name 2} none picked
1313
+ ✓ 3. {Area name 3} {n} picked
1314
+ – {picked question}
1313
1315
  ...
1314
1316
 
1315
- Reply with another Area number, or `done` to investigate the {total picked}
1316
- picked questions. Reply `pause` to stop here.
1317
+ {if T < 15} A good set is usually 15–20 you've picked {T}. Reply an Area
1318
+ number to add more, `more` to suggest new Areas, or `commit`.
1319
+ {if T ≥ 15} Reply `commit` to run discovery on these {T} questions, an Area
1320
+ number to adjust, `more` for new Areas, or `pause` to stop.
1317
1321
  ```
1318
1322
 
1319
- When EVERY Area has been resolved (picked or skipped), shift the CTA from "another Area number" to:
1323
+ **The minimum model floor 6 HARD, good 15–20 SOFT, no cap:**
1320
1324
 
1321
- ```text
1322
- All Areas reviewed. Reply `done` to investigate the {total picked}
1323
- picked questions. Reply `pause` to stop here.
1324
- ```
1325
+ - **`commit` with T < 6** → REFUSE (hard floor). *"Pick at least 6 to run discovery — you have {T}, choose {6−T} more,"* then return to the Summary (or the Area they were on). No skip path; do NOT call `accept_discovery_questions_batch` or `start_agentic_run`.
1326
+ - **`commit` with 6 ≤ T < 15** → allowed. Proceed to § 7.4 after the one-line "good is 15–20" nudge — do NOT re-nag or block.
1327
+ - **`commit` with T ≥ 15** → proceed to § 7.4.
1328
+ - **An Area number** at the Summary → re-open that Area's questions (picks preserved), then return here.
1325
1329
 
1326
- ###### 7.3.4 Power paths from the index
1330
+ **Held custom questions + pending new Areas render in the Summary** so the user reviews everything before `commit`: a held custom question shows under its Area as `+ (your) {text}`; a pending agent-suggested new Area shows at the bottom as `+ (new) {name} {n} questions`. They count toward `{T}`. All are persisted at `commit` (§ 7.4).
1327
1331
 
1328
- - **`accept shortlist`** (from the index, before picking any Area): accept the 610-question global shortlist computed in § 7.3.0. Group those by their owning Area, then call `accept_discovery_questions` once per Area (in parallel per § 7.4) with the shortlisted IDs for that Area. Skip straight to Step 7.4 commit + Step 7.4.5 classification. This is intentionally NOT "top 3–4 of every Area" that would scale to 24–32 picks on a wide exploration and reintroduce the "no triage signal" problem the area-first picker exists to fix.
1329
- - `show all` (from the index): accepted as a reply but NOT advertised on the CTA line. Expands into a single long list view across all Areas. Use only when the user explicitly asks — the area-first index is the default.
1330
- - `skip discovery` (from the index, before any picks): treat ALL Areas as skipped. The classification check in Step 7.4.5 will surface this as a deliberate choice.
1332
+ - **`more`** at the Summary the user wants broader coverage. **Suggest 23 NEW candidate Areas inline yourself** — each a short name + 3–4 questions authored from the problem statement, the locked scope, and the Areas already shown, chosen to fill **gaps** the current Areas miss. Label the candidates with **LETTERS (`A`, `B`, `C`) not numbers** — to avoid colliding with the question-number stream, and ask which to add (`letters`, e.g. `A` or `A,C`, or `none`). Picked candidates become **pending new Areas held locally** (persisted at `commit`). Do NOT call a server "generate-more" endpoint you have the context, so propose directly (it's faster). **Never auto-add the user picks.**
1333
+
1334
+ ###### 7.3.4 Power paths (available from any Area or the Summary)
1335
+
1336
+ - **`accept shortlist`**: accept the 6–10-question global shortlist computed in § 7.3.0 — the fast path for a user who doesn't want to walk every Area. Group those by their owning Area, commit them in ONE `accept_discovery_questions_batch` call (§ 7.4 — one entry per Area), and proceed to Step 7.5. Intentionally NOT "top 3–4 of every Area" (which would scale to 24–32 picks and reintroduce the "no triage signal" problem). The shortlist is the quick minimal set; the walk is how a user reaches the 15–20 good-coverage range.
1337
+ - **`show all`**: accepted as a reply but NOT advertised on the CTA line. Expands every Area's questions into one long list. Use only when the user explicitly asks — the per-Area `show more` is the default.
1338
+ - **`done`**: jump to the Summary from any Area to review + `commit`.
1339
+ - **Below the floor** (fewer than 6 picked on `commit`): do NOT proceed. Reply with how many more are needed and return to the Summary — e.g. *"Pick at least 6 to run discovery — you've picked 3, choose 3 more."* There is no skip path. (6–14 is allowed with the soft nudge; ≥15 is the good-coverage target — see § 7.3.3.)
1331
1340
 
1332
1341
  ###### 7.3.5 — What NOT to say
1333
1342
 
1334
1343
  - DO NOT add machinery copy like *"The answer engine will then investigate them via codebase recon and surface clarifying questions for you to review."* The user only needs to know that picking them triggers investigation.
1335
1344
  - DO NOT use `Press Enter` anywhere in this picker (see § Surface-aware continuation prompts).
1336
- - DO NOT say `lock` for the picking confirmation; use `done` from the index.
1337
- - DO NOT show full question text in the indexonly Area names + counts.
1345
+ - DO NOT say `lock` for the picking confirmation; use `done` (to the Summary) then `commit`.
1346
+ - DO NOT number Areas and questions in the same view one numbering stream (the current Area's questions). The breadcrumb `Area i of N` carries position; it is not a pickable number.
1338
1347
 
1339
1348
  ###### Legacy alias notes
1340
1349
 
1341
- - `suggest` (legacy per-Area shortcut) is now the implicit per-Area recommendation the index already shows recommended counts and `accept shortlist` is the global power path. If a user still types `suggest` inside an Area, treat it as "pick the recommended set for this Area."
1342
- - `accept recommended` (legacy global shortcut): if a user types this, treat it as `accept shortlist`. Surface a one-line note that the discovery-stage token is `accept shortlist` (questions); `accept recommended` is reserved for Step 9's theme acceptance.
1350
+ - `suggest` (legacy per-Area shortcut) is now spelled **`suggested`** picks the current Area's recommended (★) set. If a user types `suggest` inside an Area, treat it the same.
1351
+ - `accept recommended` (legacy global shortcut): at the DISCOVERY stage, if a user types this, treat it as `accept shortlist` and surface a one-line note that the discovery-stage token is `accept shortlist` (questions). (At Step 9 the recommendation-review CTA is `proceed`, not `accept recommended`.)
1343
1352
  - `all` (legacy fourth option) remains removed (see § Removed below).
1344
1353
 
1345
1354
  ###### Removed: `all` (the old fourth option)
1346
1355
 
1347
1356
  The legacy `all` shortcut was removed because in practice it produced low-signal selections — picking everything is indistinguishable from not discriminating, which makes Reasoning Readiness scoring less meaningful at the boundary and pushes recommendation generation against a noisy answer set. Users who really did mean "everything" can still type the full number list (e.g. `1,2,3,4,5`) — but that requires conscious intent rather than a one-keystroke default. If you see a SKILL or external reference still mentioning `all`, it's stale.
1348
1357
 
1349
- ##### 7.4 — Commit picks (one call per Area, dispatched in parallel)
1358
+ ##### 7.4 — Commit picks (ONE batch call across all Areas)
1350
1359
 
1351
- For each Area where the user picked at least one question, call `mcp__ritual__accept_discovery_questions` with:
1352
- - `state_id` (from the discovery state)
1353
- - `matter_id` (the API field; user-facing this is the Area)
1354
- - `question_ids[]` (the picks for THIS Area)
1360
+ **load-bearing forbidden behavior:** do NOT fan out one
1361
+ `accept_discovery_questions` call per Area in parallel. Each per-Area call
1362
+ does several DB round-trips; firing them concurrently exhausts the server's
1363
+ connection pool and returns 503s on the later Areas (observed in prod). The
1364
+ batch endpoint exists precisely to avoid this — use it.
1355
1365
 
1356
- The API enforces per-matter atomicity — there is no cross-matter batch endpoint today (filed as backlog: `accept_discovery_questions_batch`). To minimize wall-clock latency when the user picked across many Areas, **dispatch the per-Area calls in parallel** with `Promise.all` rather than awaiting each one sequentially:
1366
+ Call `mcp__ritual__accept_discovery_questions_batch` **once** with every
1367
+ Area's picks in a single atomic request:
1368
+ - `state_id` (from the discovery state)
1369
+ - `picks[]` — one entry per Area the user picked in, each `{ matter_id, question_ids[] }`
1357
1370
 
1358
1371
  ```ts
1359
- // Parallel, NOT sequential.
1360
- await Promise.all(
1361
- pickedAreas.map((area) =>
1362
- accept_discovery_questions(state_id, area.matter_id, area.question_ids),
1363
- ),
1364
- );
1372
+ // ONE call. All Areas, one atomic transaction, one successor state.
1373
+ await accept_discovery_questions_batch(state_id, [
1374
+ { matter_id: areaA.matter_id, question_ids: areaA.question_ids },
1375
+ { matter_id: areaB.matter_id, question_ids: areaB.question_ids },
1376
+ // …one entry per Area with at least one pick
1377
+ ]);
1365
1378
  ```
1366
1379
 
1380
+ Use the single-Area `accept_discovery_questions` ONLY when the user picked in
1381
+ exactly one Area. If for some reason you must use it across several Areas
1382
+ (e.g. the batch tool is unavailable), call it **sequentially** (`await` each
1383
+ in turn) — never in parallel.
1384
+
1367
1385
  User-facing: emit ONE status line for the whole commit, not one per Area:
1368
1386
 
1369
1387
  ```text
1370
1388
  Saving picks across {N} Areas…
1371
1389
  ```
1372
1390
 
1373
- If any individual call fails, log the Area name + error inline and continue with the rest partial success is acceptable here. The next step's classification check will surface anything that didn't land.
1374
-
1375
- ##### 7.4.5 Classify unpicked areas when the signal warrants it
1376
-
1377
- After question picking, check for scope mismatch only when one of these triggers fires:
1391
+ The batch call is all-or-nothing validation fails the whole request if any
1392
+ pick is malformed, so there's no partial-success state to reconcile. Areas the
1393
+ user chose not to pick from are simply left unpicked.
1378
1394
 
1379
- - Pick-rate < 40%
1380
- - Matter coverage <= 50%
1381
- - Pick-rate = 100%
1382
- - Picks concentrate heavily in one matter while the scope spans several concerns
1395
+ **If there are NO held custom questions or pending new Areas, proceed to anti-goals.**
1383
1396
 
1384
- If no trigger fires, proceed silently to anti-goals.
1397
+ ###### 7.4.1 Persist held custom questions + new Areas (only if any were held)
1385
1398
 
1386
- **Fire-on-trigger anti-pattern (load-bearing):** after `accept_discovery_questions` returns, you MUST evaluate the four trigger conditions before proceeding to Step 8. If ANY trigger matches, you MUST render the scope-classification gate. Skipping the gate when a trigger fires — including the "the picks look reasonable to me" / "the user seems decisive" / "they probably know what they're doing" judgment call — is a SKILL violation. The decision signal is the user's **actual pick distribution**, not the agent's confidence in it.
1399
+ Custom questions (`add`, § 7.3.2) and pending new Areas (`more`, § 7.3.3) were held
1400
+ LOCALLY during the walk because `add_discovery_question` needs a **workspace** matter id,
1401
+ which only exists after the batch above materialized the picked Areas. Persist them now,
1402
+ AFTER the batch call:
1387
1403
 
1388
- Concretely: at 5 picks out of 70 total questions = 7.1% pick-rate, the < 40% trigger fires. The gate MUST be rendered. Observed violation 2026-05-15: agent proceeded directly to Step 8 after a 5/70 acceptance, never showed the scope-classification gate — silently locking the user into a broad scope while their actual investigation was tightly focused on 5 questions.
1404
+ 1. **Resolve workspace matter ids.** Call `mcp__ritual__get_exploration(exploration_id)` and
1405
+ map each Area **name** → its workspace `matters[i].id`. (The batch only materialized Areas
1406
+ the user picked AI questions in.)
1407
+ 2. **For each Area that has held custom questions:**
1408
+ - if a workspace matter for that name exists → use its id;
1409
+ - if not (a custom-only Area, or a pending new Area) → `mcp__ritual__create_discovery_matter(exploration_id, name)` first, use the returned id.
1410
+ - then call `mcp__ritual__add_discovery_question(exploration_id, matter_id, text)` for each held question — **SEQUENTIALLY** (`await` each), never in parallel (same connection-pool caution as the batch).
1411
+ 3. **For each pending new Area** (from `more`): `create_discovery_matter(...)` then `add_discovery_question(...)` per its questions, sequentially.
1389
1412
 
1390
- This is the same gap as the Step 9 "freelance dedupe action" anti-pattern: the SKILL specifies the behavior; the agent must not override based on its own assessment of whether the gate "feels needed."
1391
-
1392
- If a trigger fires, summarize the pattern in plain language and ask the user to classify unpicked areas. This is a top-level decision gate that closes the picker sub-views, so the full rail returns:
1413
+ One status line for the whole persist step (not one per question):
1393
1414
 
1394
1415
  ```text
1395
- Ritual build
1396
- ✓ Context ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
1397
-
1398
- Scope check
1399
-
1400
- {One-line summary of which pattern fired — e.g. "You picked 4 of 32 questions, mostly in retention."}
1401
-
1402
- How should I treat the unpicked areas?
1403
-
1404
- 1. Out of scope — tighten the current scope around what you picked.
1405
- 2. Later phase — keep the broad scope, but mark unpicked areas as phase-later candidates.
1406
- 3. Open questions — keep the broad scope and treat unpicked areas as context debt.
1407
- 4. Pick more — return to question picking before continuing.
1408
-
1409
- Reply with `1`, `2`, `3`, or `4`. Reply `pause` to stop here.
1410
- ```
1411
-
1412
- Use `references/discovery-classification.md` for the branch handlers, pulse templates, and no-discrimination case. Do not preview score deltas in the question-picking menu; let the pulse explain the consequence after the user chooses.
1413
-
1414
- For Branch 2, append an exact block to `recon_context` before build brief generation:
1415
-
1416
- ```markdown
1417
- ## Explicit phase-later candidates
1418
-
1419
- These were intentionally deferred by the user during discovery. They are not context debt. Include them in the Build Brief under "Phase Candidates / Deferrable Items."
1420
-
1421
- - {matter/question}
1422
- Reason: {user choice or inferred dependency}
1423
- Related RB/source: {optional}
1416
+ Adding your {M} question(s) across {K} Area(s)…
1424
1417
  ```
1425
1418
 
1419
+ Only after all holds are persisted, proceed to anti-goals. The floor (≥6) counts
1420
+ custom + AI questions together — never `start_agentic_run` before the held questions are
1421
+ written.
1426
1422
 
1427
1423
  ##### 7.5 — Optional: capture out-of-scope items
1428
1424
 
1429
1425
  If the user mentioned things they DON'T want investigated ("don't touch enterprise SSO", "skip pricing"), capture them as anti-goals.
1430
1426
 
1427
+ **Pre-flight (mandatory):** before calling `set_anti_goals`, run the change pre-flight in `references/change-preflight.md` — restate the out-of-scope items you heard and show the exact anti-goal `text` array you're about to send, then wait for `yes`. A misread anti-goal poisons rec-gen and the R4 audit downstream, so this hard pause (even in auto-mode) applies even when the user's phrasing seemed clear. Do not call the tool until the user confirms.
1428
+
1431
1429
  Call `mcp__ritual__set_anti_goals(exploration_id, [{ text, reason? }, ...])`.
1432
1430
 
1433
- Skip silently if no anti-goals were mentioned.
1431
+ Skip silently if no anti-goals were mentioned. (No mention = nothing to confirm; the pre-flight only runs when the user actually states out-of-scope items.)
1434
1432
 
1435
1433
  **Pulse (Step 7.4 done — and again after 7.5 if anti-goals were set):** Emit a pulse — decision resolution and (if 7.5 ran) assumption safety just moved. Compact format unless this crosses Under-specified → Exploration-safe.
1436
1434
 
@@ -1442,7 +1440,7 @@ For `engineering`, `delivery`, and `operations` roles, show:
1442
1440
 
1443
1441
  ```text
1444
1442
  Ritual build
1445
- Context ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
1443
+ ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
1446
1444
 
1447
1445
  Run discovery
1448
1446
 
@@ -1463,7 +1461,7 @@ For `product`, `design`, or explicitly PRD-style flows, answer review may be use
1463
1461
 
1464
1462
  ```text
1465
1463
  Ritual build
1466
- Context ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
1464
+ ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
1467
1465
 
1468
1466
  Run discovery
1469
1467
 
@@ -1530,7 +1528,7 @@ Pick whichever fits the user's flow — they're equivalent in content. Do not in
1530
1528
 
1531
1529
  ##### 8.1 — Polling loop
1532
1530
 
1533
- Poll `mcp__ritual__get_agentic_run(run_id)` using `references/async-polling.md`: **`Bash sleep 5` (always 5 — never escalate to 15/20/25)** per iteration, then a fresh status call. Even if the run takes 2+ minutes, the sleep value stays 5; the harness blocks chained-shorter-sleeps-at-increasing-N just like it blocks `sleep ≥ 30`. Agentic runs CAN exceed 5 min for large explorations — if you see status still running past ~5 min of polling, switch to the `Monitor` + `until <check>; do sleep 2; done` pattern from `references/async-polling.md` § Long waits.
1531
+ Poll `mcp__ritual__get_agentic_run(run_id)` using `references/async-polling.md`: **`Bash sleep 20` (constant 20matches Spark's 20s agentic cadence; never escalate)** per iteration, then a fresh status call. Even if the run takes 2+ minutes, the sleep value stays a constant 20; the harness blocks chained-shorter-sleeps-at-increasing-N just like it blocks `sleep ≥ 30`, but a fixed `20` is non-escalating and under 30 → guard-safe. Agentic runs CAN exceed 5 min for large explorations — if you see status still running past ~5 min of polling, switch to the `Monitor` + `until <check>; do sleep 2; done` pattern from `references/async-polling.md` § Long waits.
1534
1532
 
1535
1533
  **On the FIRST poll only** (not every poll), prepend one line that locks the "background execution is default" mental model:
1536
1534
 
@@ -1559,7 +1557,7 @@ Landing (first question, full rail + intro):
1559
1557
 
1560
1558
  ```text
1561
1559
  Ritual build
1562
- Context ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
1560
+ ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
1563
1561
 
1564
1562
  Run Agentic Exploration
1565
1563
 
@@ -1631,356 +1629,146 @@ For each question's loop:
1631
1629
 
1632
1630
  **Pulse (Step 8 done):** Emit a pulse — decision resolution moved significantly (answers complete, draft recommendations now exist). Render full if this crosses Under-specified → Exploration-safe, else compact.
1633
1631
 
1634
- #### Step 9 — Review and accept recommendations (grouped, role-aware)
1632
+ <!-- lite:keep-start -->
1635
1633
 
1636
- **Use `mcp__ritual__get_recommendations_preview(exploration_id)` for the Step 9.1 landing screen.** It returns a server-rendered preview with `previewText` (terminal-formatted, hard-wrapped at 78 cols print verbatim), `idMap` (`R1..RN` → uuid lookup for resolving `accept R3` / `detail R7`), `actions` (role-aware structured command list), `categoryGroups` (structured grouped list for non-terminal surfaces), `actionHint`, `scopeLine`, and `totalCount`. The server already handles role detection (admin vs collaborator) and filters out `approved`/`rejected` recs.
1634
+ #### Step 9 — Review recommendations (category walk)
1637
1635
 
1638
- Use `mcp__ritual__get_recommendations(exploration_id)` (the raw array) only when you need fields not in the preview full `metadata.acceptance_criteria[]`, `metadata.explainability` rationale chain, `metadata.labels[]`, etc. The detail card in 9.3 (`detail R{N}`) loads from the raw tool keyed by the uuid you got from `idMap`.
1636
+ This is the most-read screen in the build flow, and — as of 2026-06-08 — a **non-blocking review**. Recommendations are **auto-accepted at generation** (created `approved`); the artifacts that depend on them (requirements, the deliverable doc, and — for developer-function jobs — the build brief) are **already being generated** the moment rec-gen completes. Step 9 is the user's chance to **read and refine** the set, not an accept-or-reject gate. Replying `proceed` records that a human reviewed it (stamps `reviewedAt` / `reviewedBy`) and continues to the build brief it never blocks, and there is **no reject path here**.
1639
1637
 
1640
- Each raw rec includes:
1638
+ The review is a **category walk**, mirroring Spark's recommendation drawer: the user moves through one **category** at a time, sees each recommendation in that category in full (title, description, and the "Why this" reasoning), and can refine any one of them in place before continuing.
1641
1639
 
1642
- - top-level: `id`, `title`, `content` (summary), `status`, `priority`, `points`, `confidence`
1643
- - `metadata.category.name` — **the load-bearing grouping key** (one rec → one category)
1644
- - `metadata.acceptance_criteria[]` — concrete pass conditions
1645
- - `metadata.explainability` — `rationale` (chained `→` arrow string), `faq_references[]`, `problem_alignment`, `inferred_elements`, optional `initial_input_analysis`
1646
- - `metadata.labels[]` — secondary tags
1640
+ **Data source.** Use `mcp__ritual__get_recommendations(exploration_id)` (the raw array) — the walk shows full per-rec content, so you need the fields a titles-only preview omits:
1647
1641
 
1648
- **Role model — load-bearing**: only **admins** can accept recommendations (call `accept_recommendations`). **Collaborators** can read, comment, and proceed to implement, but they cannot move recs from `draft`/`pending_review` to `approved`. The preview API handles this automatically — the `actions` list and `actionHint` are gated on the caller's workspace role; admins see `accept recommended` while everyone else sees `request admin review` plus the optional `continue` (implement-ahead) path. Respect what the preview returns; don't substitute it.
1649
-
1650
- If you don't already know the user's role on this workspace, prefer the workspace member endpoint or cached role from `/ritual init`. When unavailable, ask plainly: *"Are you the workspace admin or a collaborator?"* Do not attempt acceptance blindly unless the user explicitly says to accept.
1651
-
1652
- **Vocabulary**: do NOT use "Reasoning chain" or "reasoning_chain" in user-facing copy. The user-visible label is **"Why this"** — a 4-line Problem / Discovery / Tradeoff / Recommendation breakdown derived from the rationale field. "Reasoning chain" sounds like internal model chain-of-thought; "Why this" is product-native.
1653
-
1654
- **Vocabulary anti-pattern — load-bearing**: recommendations are grouped by **category** (`metadata.category.name`). They are **NEVER** grouped by `matter` or by `Area`. Those are **discovery-phase concepts** — the matter / Area is where DISCOVERY QUESTIONS live; recommendations are synthesized across all matters and grouped by the category the LLM assigns (themes like "Token security & replay", "Atomicity & architecture", etc.). The internal DB field `matter_id` does not appear in the recommendation surface and **must never appear in user-facing copy** at this step. Anti-pattern observed in agent output: *"44 recs grouped by matter"* — the right framing is *"44 recs grouped by category"* (with categoryGroups returned by the preview API doing the work). If you find yourself referring to recommendation groups as "Areas" or "matters," stop and re-read this paragraph.
1642
+ - top-level: `id`, `title`, `content` (the description / summary), `status`, `priority`, `points`, `confidence`
1643
+ - `metadata.category.name` — **the load-bearing grouping key** (one rec → one category)
1644
+ - `metadata.explainability` `rationale` (chained `→` arrow string), `faq_references[]`, `problem_alignment`, `inferred_elements`
1645
+ - `metadata.acceptance_criteria[]` — concrete pass conditions (optional to surface; see § 9.1)
1655
1646
 
1656
- **Action-menu anti-pattern load-bearing**: the **blessed action set at the Step 9 acceptance gate** is exactly:
1647
+ Assign stable `R1..RN` IDs **globally across all categories** in page order (NOT restarting per-category), and remember the `R{N}` `id` map so you can resolve `edit R{N}` to the rec UUID for the MCP calls.
1657
1648
 
1658
- - `accept recommended` admin path, accepts all on-screen recs
1659
- - `request admin review` — collaborator path, notifies workspace admin
1660
- - `drop R{N}` — remove one rec from the set before accepting
1661
- - `drill R{N}` — show one rec's full detail card
1662
- - `comment R{N}` — leave feedback on a specific rec
1663
- - `pause` — stop here; user can resume via `/ritual resume`
1649
+ **Vocabularyload-bearing:**
1664
1650
 
1665
- Plus the `continue` (implement-ahead) escape hatch for collaborators with explicit authorization.
1651
+ - Recommendations are grouped by **category** (`metadata.category.name`). They are **NEVER** grouped by `matter` or by `Area` — those are discovery-phase concepts. `matter_id` must never appear in user-facing copy. Anti-pattern observed in agent output: *"44 recs grouped by matter"* — the right framing is *"44 recs across K categories."*
1652
+ - Do NOT use "Reasoning chain" / "reasoning_chain" in user-facing copy. The user-visible label is **"Why this"** — a short Problem / Discovery / Tradeoff distillation derived from the `rationale` field, NOT the literal `→` arrow chain (that's the model's internal scratchpad shape).
1666
1653
 
1667
- **Do NOT freelance other actions.** Anti-patterns observed in agent output:
1654
+ **Action set load-bearing (exactly three, no freelancing):**
1668
1655
 
1669
- - `dedupe` there is no de-dupe action. The system produces a non-duplicated rec set by design (single-flight rec-generation, V5 cap-enforcer, Stage A.2 quality audit). If duplicates appear, that's a system regression — file a bug, don't offer a workaround.
1670
- - `open the admin` / "open the admin UI to reject one pass" — there is no admin UI surface invoked from `/ritual build`. The CLI is the surface; the action set above is the contract.
1671
- - `reject one pass` / `accept the survivors` assumes a duplicate-pass shape that should not exist post-PR #345.
1672
- - ❌ Any invented compound action (`accept and dedupe`, `merge similar`, etc.) — drives the user into a workflow the system doesn't support.
1656
+ - `edit R{N} <your change>` refine one recommendation: regenerate its title / description / reasoning from a plain-language ask, **preview** the change, then **apply** it. 9.2)
1657
+ - `next` move to the next category. 9.3)
1658
+ - `proceed` mark the set reviewed and continue to the build brief, from any category. (§ 9.3)
1673
1659
 
1674
- If the rec set looks wrong, the right responses are: surface the anomaly explicitly, ask the user how to proceed, and consult `mcp__ritual__get_recommendation_attestation` for the quality audit's `duplicateTitlePrefixes` signal. Don't paper over with an invented action.
1660
+ **Do NOT freelance other actions.** There is **no `drop` / reject** (recs are auto-accepted and the review is non-blocking — a rec the user dislikes is refined with `edit`, or simply left as-is), **no `comment`**, and **no separate `drill` / `detail`** (full content is already on screen). Reject none of these by inventing compounds either (`dedupe`, `accept the survivors`, `merge similar`, `open the admin UI` — all forbidden). If the rec set itself looks wrong (e.g. apparent duplicates), surface the anomaly explicitly and consult `mcp__ritual__get_recommendation_attestation` (`duplicateTitlePrefixes`) — don't paper over it with an invented action.
1675
1661
 
1676
- ##### 9.1 — Landing screen: server-rendered preview (primary path)
1662
+ ##### 9.1 — The walk: one category per turn
1677
1663
 
1678
- The recommendations review is the most-read screen in the whole build flow.
1664
+ **[USER PAUSE]** Render the **current category only**, then stop and wait for the user's reply. One category per turn — never dump every category's full content in a single message (that's the wall-of-text failure mode; the walk is what keeps a 13-rec set readable). The first render opens with the full rail; subsequent categories use the in-phase chip.
1679
1665
 
1680
- **Primary path print the server preview verbatim:**
1666
+ First category (rail shown):
1681
1667
 
1682
1668
  ```text
1683
- 1. Call mcp__ritual__get_recommendations_preview(exploration_id).
1684
-
1685
- 2. Response shape:
1686
- {
1687
- terminalPreviewText: "...", // present for surface=terminal (default)
1688
- uiPreview: { // always present
1689
- stage: "recommendations",
1690
- stageIndex: 4, stageCount: 6,
1691
- scopeLine, stats, categoryGroups,
1692
- idMap, actions
1693
- }
1694
- }
1695
-
1696
- 3. Print response.terminalPreviewText VERBATIM. Do not re-render,
1697
- re-wrap, re-number, or add a leading "Here are your recommendations..."
1698
- line. The server already laid out the build rail, scope, grouped recs,
1699
- and role-aware action hint at 78-col wrap.
1700
-
1701
- 4. Remember response.uiPreview.idMap so you can resolve user input — when
1702
- they reply `accept R3` or `detail R7`, look up `R{N}` → uuid in
1703
- idMap and use that uuid in the follow-up MCP call (accept_recommendations,
1704
- get_recommendations).
1705
-
1706
- 5. response.uiPreview.actions is for mobile/web button rendering — terminal
1707
- flow ignores it (action hint copy is already inside terminalPreviewText).
1708
- Each action carries `style: "primary" | "secondary"` so a non-terminal
1709
- UI knows which is the call-to-action.
1710
- ```
1669
+ Ritual build
1670
+ ✓ Scope ✓ Discovery ● Recommendations ○ Build brief ○ Implementation (Your agent)
1711
1671
 
1712
- The server controls the rendering shape (category numbering, R-IDs, titles-only, 78-col wrap, role-aware action hint). Your job is to print and look up — not to invent labels, re-group, or add commentary.
1672
+ Scope:
1673
+ {one-line compressed scope — ~80-120 chars; truncate at a clause boundary, no ellipsis}
1713
1674
 
1714
- **Rendering anti-pattern DO NOT DO THIS:** the most-seen Step 9 regression is the agent printing the preview AND THEN free-form-listing the recs themselves as a bulleted summary "for the user's convenience." This is wrong on three axes:
1675
+ {N} recommendations across {K} categories. They're accepted by default
1676
+ review and refine any, or proceed anytime.
1715
1677
 
1716
- 1. **Doubles the content** preview already has titles + R-IDs + action hint at 78-col wrap. A second free-form list is redundant and pushes the action hint off-screen on small terminals.
1717
- 2. **Drops the R-IDs** — a free-form bullet list erases the stable `R{N}` references the user needs to reply with `accept R3` / `drill R7` / `comment R12`. The user then types `view 10` (positional) thinking that's stable; it's not.
1718
- 3. **Invents grouping labels** — free-form rendering tempts the agent to label groups as "Areas" or "matters" (already covered by the vocabulary anti-pattern above).
1678
+ Category 1/{K}{category name}
1719
1679
 
1720
- If the user wants more detail than the preview shows, they use `drill R{N}` — that's what the action menu is for. Do not pre-empt their drill choice with a wall of free-form bullets.
1680
+ R1 {title}
1681
+ {content — the description, wrapped at terminal width, 1-3 lines}
1682
+ Why this: {one-line Problem→Discovery→Tradeoff distillation, plain prose}
1721
1683
 
1722
- **"Many recs" rule — load-bearing for high-count sets**: when `response.uiPreview.stats.totalCount > 20`, the preview is **especially** the right surface to use; do NOT compensate by dumping the rec content inline. The server preview keeps high-count sets navigable (R-IDs + titles + compact category groups). If a 40+ rec set ever lands, the right reaction is to investigate WHY (single-flight regression? cap-enforcer bypass?) — see Stage A.2 audit signals via `get_recommendation_attestation` — not to add helpful free-form rendering on top.
1684
+ R2 {title}
1685
+ {description}
1686
+ Why this: {...}
1723
1687
 
1724
- **Fallback path if the preview tool is unavailable or returns a non-200**: render per the contract block below. The contract is the same shape the server uses, so a mismatch between server-rendered and agent-rendered output is unlikely. The fallback exists for older MCP servers that haven't deployed the preview endpoint yet.
1688
+ Pulse: Reasoning Readiness ~88% · Context Debt 12% (implementation-ready)
1725
1689
 
1726
- ```text
1727
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1728
- STEP 9.1 RENDERING CONTRACT (FALLBACK) — non-negotiable
1729
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1730
-
1731
- Use this contract ONLY if get_recommendations_preview is unavailable
1732
- (older MCP server) or returns an error. Otherwise, print the preview
1733
- verbatim per the Primary path above.
1734
-
1735
-
1736
- Landing view is for SELECTION, not reading. Full prose belongs in 9.3.
1737
-
1738
- ✓ DO:
1739
- - Number categories `1.`, `2.`, `3.` … `K.` in page order
1740
- - Assign recommendations stable `R1`, `R2`, … `RN` IDs GLOBALLY across
1741
- all categories (NOT restart per-category — so `detail R7` is
1742
- unambiguous without naming the category)
1743
- - Show recommendation TITLES ONLY at the landing
1744
- - Indent recs 3 spaces under their category
1745
- - One blank line between categories
1746
- - Include compact scope line above the list
1747
- - End with the action block (`accept recommended` etc.)
1748
-
1749
- ✗ DO NOT:
1750
- - Do NOT render recs as a flat `1..N` list with no category structure
1751
- - Do NOT use raw numeric rec IDs like `1.`, `2.`, `3.` — use `R1`, `R2`, `R3`
1752
- - Do NOT show recommendation `content` / summary text at the landing
1753
- - Do NOT show acceptance criteria, rationale, tactics, or references at
1754
- the landing — those are 9.3 detail-card content
1755
- - Do NOT omit category numbering (the prefix is what separates this
1756
- from a wall-of-text grouped list)
1757
- - Do NOT invent a "raw / deduped" framing line — the API does not return
1758
- pre-dedup counts. Use `{N} recommendations across {K} categories.`
1759
-
1760
- OBSERVED FAILURE — never render this:
1761
-
1762
- Recommendations (13)
1763
-
1764
- 1. Backfill legacy data to fail-closed PRIVATE visibility
1765
- Add a constrained `visibility` field with DB default PRIVATE...
1766
-
1767
- 2. Codify actor-state rights around owner-only mutation
1768
- Define a single permission matrix across PRIVATE/SHARED/PUBLIC...
1769
-
1770
- 3. Centralize object permissions across storefront and dashboard
1771
- Reusable `can_view_wishlist` / `can_edit_wishlist` methods...
1772
-
1773
- Why wrong:
1774
- - Looks grouped only implicitly; categories not visible as headers
1775
- - Uses `1..N` numeric IDs (should be `R1..RN`)
1776
- - Dumps `content` summaries — defeats the purpose of a landing view
1777
- - `detail R7` no longer maps to a stable ID
1778
-
1779
- PREFLIGHT — before printing 9.1 output, self-check:
1780
- □ Did I group by `metadata.category.name`?
1781
- □ Did I prefix each category with `1.`, `2.`, … `K.`?
1782
- □ Did I assign global `R1..RN` IDs across categories?
1783
- □ Did I show titles only (no summaries / no rationale)?
1784
- □ Is there a compact scope line above the list?
1785
- □ Does my action block use `R{N}` references that match the IDs above?
1786
-
1787
- If any answer is no, FIX BEFORE PRINTING.
1788
- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1690
+ Reply edit R{N} <your change> · next (Category 2/{K}) · proceed (build brief)
1789
1691
  ```
1790
1692
 
1791
- Full rail at the landing (Recommendations stage opens):
1693
+ Subsequent categories (in-phase chip, no full rail):
1792
1694
 
1793
1695
  ```text
1794
- Ritual build
1795
- ✓ Context ✓ Scope ✓ Discovery ● Recommendations ○ Build brief ○ Implementation (Your agent)
1796
-
1797
- Scope:
1798
- {one-line compressed scope — ~80-120 chars; truncate the full problem
1799
- statement at a natural clause boundary, no ellipsis}
1800
-
1801
- Recommendations ready
1802
-
1803
- {N} recommendations across {K} categories.
1696
+ Recommendations · Category 2/{K} — {category name}
1804
1697
 
1805
- 1. {Category 1 name}
1806
- R1 {title}
1807
- R2 {title}
1698
+ R3 {title}
1699
+ {description}
1700
+ Why this: {...}
1808
1701
 
1809
- 2. {Category 2 name}
1810
- R3 {title}
1811
- R4 {title}
1812
- R5 {title}
1813
-
1814
- 3. {Category 3 name}
1815
- R6 {title}
1816
-
1817
- ...
1818
-
1819
- Pulse: Reasoning Readiness ~88% · Context Debt 12% · +26% (implementation-ready)
1820
-
1821
- Recommended: reply `accept recommended` to approve these {N} and generate
1822
- the build brief.
1702
+ ...
1823
1703
 
1824
- Or reply:
1825
- - `detail R7` to inspect one recommendation
1826
- - `drop R8` to remove one before accepting
1827
- - `change R3: <edit>` to revise one
1828
- - `hold` to stop here
1704
+ Reply edit R{N} <your change> · next (Category 3/{K}) · proceed (build brief)
1829
1705
  ```
1830
1706
 
1831
1707
  Notes:
1832
1708
 
1833
- - **Categories are numbered `1..K`** (their position on the page). **Recommendations get stable `R1..RN` IDs** across the whole set. The numbering is for reading orientation; the user references recs by `R{N}`, not by category number.
1834
- - **One blank line between categories**; titles indent at 3 spaces (so the eye lands on the category name first, then the R-IDs scan down).
1835
- - **Pulse uses full labels** per `references/cli-output-contract.md` § Pulse tier labels.
1836
- - **`accept recommended`** is the visible CTA NOT `accept all`. "Recommended" frames the action as "the curated set you see on screen"; "all" sounds like a bulk operation over deduped/hidden/raw recs.
1837
- - **Surface 4 actions at first render not more.** The four above (`detail R{N}`, `drop R{N}`, `change R{N}: <edit>`, `hold`) cover the decisive cases. Less-frequent actions stay discoverable but off-screen at the landing:
1838
- - **`add <topic>`** lets the user request an additional recommendation on the fly (e.g. `add telemetry` → agent calls `regenerate_recommendation` with a new rec hint, or asks the user to clarify what's missing). Surface it in `help` or on the 9.3 detail card, NOT in the landing action line — too many actions at once weakens the selection screen. If the backing API doesn't yet support targeted single-rec addition, prompt the user with: "I can add a rec for `{topic}` by regenerating the full set with that pinned — that takes ~30s. Or hold the current set and add manually via the web UI."
1839
- - **`show scope`** to expand the full problem statement (covered in 9.2).
1840
-
1841
- ##### 9.2 — `show scope` handling
1709
+ - **Global `R{N}` IDs** continue across categories (Category 2 starts at R3 if Category 1 held R1–R2). The R-ID is how the user references a rec in `edit R{N}`; never restart numbering per category.
1710
+ - **`content` (the description) and "Why this" ARE shown** at the walk unlike the old titles-only landing. That's deliberate: the user reads and refines in place. Keep each rec to title + 1–3 description lines + one "Why this" line. If a rec's `acceptance_criteria` are short and genuinely useful you may add a single `Pass: {...}` line, but don't pad — the walk must stay scannable.
1711
+ - **One blank line between recs**; indent rec bodies under their `R{N}` so the eye lands on the title first.
1712
+ - **`proceed` is the primary CTA** and is offered on every category the user never has to walk all categories to continue.
1713
+ - **On the last category**, the action line drops `next`; if the user types `next` there, reply: "That was the last category reply `proceed` to continue, or `edit R{N}` to refine one."
1842
1714
 
1843
- When the user replies `show scope`, expand to the full problem statement (no rail repetition — this is a sub-view inside the same phase, use the in-phase chip):
1715
+ ##### 9.2 `edit R{N} <ask>`: preview, then apply
1844
1716
 
1845
- ```text
1846
- Recommendations · Scope (full)
1717
+ This mirrors Spark's "Revise → Preview Revision → Apply revision" exactly: the change is **previewed before anything persists**.
1847
1718
 
1848
- {full problemStatement, wrapped at terminal width}
1849
-
1850
- Reply `back` to return to the recommendations list, or any of the regular
1851
- recommendation actions.
1852
- ```
1853
-
1854
- ##### 9.3 — Detail card (when user replies `detail R{N}`)
1855
-
1856
- In-phase chip + focused single-rec card. Use the LABELED-BLOCK shape per `references/cli-output-contract.md` § Dense list format. The "Why this" block REPLACES the `rationale` chained-arrow string — render it as 4 named lines, not the literal `Problem → Discovery → Tradeoff → Recommendation` arrow chain (which is the LLM's internal scratchpad shape, not user-facing).
1719
+ 1. Resolve `R{N}` rec UUID from the walk's ID map.
1720
+ 2. Call `mcp__ritual__suggest_recommendation_edit({ recommendation_id, instruction: "<the user's ask, verbatim>" })`. This runs an LLM and returns a **transient proposal** — nothing is mutated yet. It carries `id` (the proposal id), `summary` ("what changed"), and `diff[]` of `{ field, before, after }` where `field` is `title`, `description`, or `chain.<idx>`.
1721
+ 3. **[USER PAUSE]** Render the preview and wait:
1857
1722
 
1858
1723
  ```text
1859
- Recommendations — R7
1724
+ Recommendations · R{N} proposed revision
1860
1725
 
1861
- R7. {title}
1726
+ What changed: {proposal.summary}
1862
1727
 
1863
- Category:
1864
- {metadata.category.name}
1728
+ Title
1729
+ - {before}
1730
+ + {after}
1865
1731
 
1866
- Recommendation:
1867
- {content — direct, actionable summary; 2-4 sentences}
1732
+ Description
1733
+ - {before}
1734
+ + {after}
1868
1735
 
1869
- Why this:
1870
- - Problem: {one-line distillation from metadata.explainability.problem_alignment}
1871
- - Discovery: {one-line distillation from metadata.explainability.faq_references[0].insight}
1872
- - Tradeoff: {one-line distillation from rationale's "Tradeoffs (...)" segment}
1873
- - Recommendation: {one-line distillation from rationale's "Recommendation (...)" segment}
1736
+ Why this — step {i}
1737
+ - {before}
1738
+ + {after}
1874
1739
 
1875
- Tactics:
1876
- - {short imperative — derived from metadata.acceptance_criteria where actionable}
1877
- - {short imperative}
1878
- - {short imperative}
1879
-
1880
- Acceptance criteria:
1881
- - {metadata.acceptance_criteria[0]}
1882
- - {metadata.acceptance_criteria[1]}
1883
- - {metadata.acceptance_criteria[N]}
1884
-
1885
- References:
1886
- - {file path or RB id from metadata.explainability.faq_references / referenced_faq_ids}
1887
- - {reference}
1888
-
1889
- Reply `drop R7`, `change R7: <edit>`, or `back`.
1890
-
1891
- To move forward, reply `accept recommended` from the summary.
1892
- If you only want a subset, `drop` the recs you don't want first, then `accept recommended`.
1740
+ Reply apply (save this revision) · discard (keep the original)
1893
1741
  ```
1894
1742
 
1895
- Notes on the detail card:
1743
+ - Render ONLY the `diff` fields that are present. Map `field: "title"` → `Title`, `"description"` → `Description`, `"chain.<idx>"` → `Why this — step {idx+1}`.
1744
+ - If the proposal's `diff` is empty (the LLM found no meaningful change), say so plainly and return to the category view unchanged — don't fabricate a diff.
1896
1745
 
1897
- - **Per-rec and subset accept are first-class CTAs as of cli 0.9.6.** The MCP `accept_recommendations` tool now takes an optional `recommendation_ids: string[]` param: omit it to bulk-accept everything (legacy), or pass a subset to promote only those rec IDs. Surface `accept R7` (single from detail), `accept R5,R8,R12` (subset from landing), and `accept recommended` (all) as the three accept-shaped CTAs. The agent accumulates the approved subset across the one-by-one walk-through and submits ONE batch call at the end — not N individual calls.
1898
- - The 4-line "Why this" block is a transformation of the chained-arrow `rationale` string. The arrow chain is fine as a one-line summary at the very bottom if helpful, but the 4-named-line form is the primary readable shape.
1899
- - `Tactics` and `Acceptance criteria` are related but distinct: tactics are SHORT IMPERATIVE STEPS ("Call Django authenticate() / login() through configured backends"); acceptance criteria are PASS CONDITIONS ("Valid inline registration creates exactly one user and authenticates the session").
1900
- - `References` come from `metadata.explainability.faq_references` (subject + question text) AND `referenced_faq_ids` (which the agent can resolve back to the underlying source files / RBs if known).
1901
- - `back` returns to the landing summary, NOT to a new fetch — the agent should cache the recs from the landing call and re-render.
1746
+ 4. On `apply`: call `mcp__ritual__apply_recommendation_proposal({ recommendation_id, proposal_id })`. It persists a new version, replays the reasoning chain, and returns the applied proposal. Re-fetch the rec (`get_recommendations`) and **re-render the current category with R{N} updated in place**, then continue the walk (action line `edit R{N} <change> · next · proceed`).
1747
+ On `discard`: return to the current category unchanged nothing was persisted.
1902
1748
 
1903
- ##### 9.4Action handling
1904
-
1905
- Visible CTAs in 9.1 / 9.3 map to MCP/API actions. Some are direct, some require interpretation. The agent maps free-text replies to these actions:
1906
-
1907
- | User reply | Action | Backing call |
1908
- |---|---|---|
1909
- | `accept recommended` | Accept ALL recs currently on screen | `mcp__ritual__accept_recommendations({ exploration_id })` (omit `recommendation_ids` — admin only, see Branch B) |
1910
- | `accept R{N}` (from detail) | Mark that single rec approved (batch of 1) | `mcp__ritual__accept_recommendations({ exploration_id, recommendation_ids: [rec_uuid_for_R{N}] })`. Exploration stays in REVIEWING_RECOMMENDATIONS if other recs remain in draft/pending; transitions to COMPLETE once nothing remains. |
1911
- | `accept R{N},R{M},R{P}` (subset from landing) | Mark that subset approved (batch of N) | `mcp__ritual__accept_recommendations({ exploration_id, recommendation_ids: [rec_uuids…] })`. Single round-trip — don't loop N calls. |
1912
- | `detail R{N}` | Render the detail card for that rec | None (in-memory) |
1913
- | `change R{N}: <edit>` | Regenerate that single rec with the user's hint | `mcp__ritual__regenerate_recommendation(recommendation_id, hint)` if available; else queue as a comment + ask the user to wait for re-gen |
1914
- | `drop R{N}` | Mark that rec rejected | `update_recommendation` with status=rejected, OR add a "deliberately excluded" note for the brief generator |
1915
- | `add <topic>` | Request a new rec on the topic | See § 9.1 note — typically requires full regenerate with the new topic pinned; SKILL surfaces the choice to the user before triggering |
1916
- | `show scope` | Expand the scope reference | None (in-memory) |
1917
- | `hold` | Stop here without accepting | None (exits the flow; user can resume later) |
1749
+ Editing is non-destructive and does not advance the flow the user can `edit` several recs, across categories, before `proceed`.
1918
1750
 
1919
- Don't display all aliases. Display the most-likely-needed: `accept recommended`, `accept R{N}` (single), `detail R{N}`, `drop R{N}`, `hold`. Show `accept R{N},R{M}` (subset), `change R{N}: <edit>`, and `add <topic>` in the detail card or as a one-line hint when the landing screen is presented for the second time (the user knows the basics by then).
1751
+ ##### 9.3 `next` and `proceed`
1920
1752
 
1921
- **Subset-accept agent behavior one call, not N:** when the user types `accept R5,R8,R12` (or accumulates approvals across the one-by-one walkthrough), the agent collects the rec UUIDs in memory and submits a SINGLE `accept_recommendations({ exploration_id, recommendation_ids })` call. Do not loop and call the tool once per rec — the API + downstream artifact-trigger is designed for one batch per "user is done with this set" event. Multiple calls inflate latency, multiply the triage-complete event emission, and cause duplicate auto-artifact queueing.
1922
-
1923
- **Backlog notes** (referenced for the agent so it doesn't over-promise):
1924
- - `add <topic>` requires a regenerate with a pinned topic — that's a forthcoming `regenerate_recommendation` improvement; until then it's a full regeneration cycle.
1925
- - Per-rec MCP `reject` (status=rejected) doesn't have a dedicated MCP tool yet. For now, `drop R{N}` is handled via the web's per-rec PATCH OR by the user simply not including it in the batch-accept call (it stays in draft/pending until the user explicitly accepts or rejects it). Adding `reject_recommendation` MCP tool is on the backlog.
1926
-
1927
- ##### 9.A — Branch A: admin replies `accept recommended`
1928
-
1929
- Call `mcp__ritual__accept_recommendations(exploration_id)`. Response includes counts (`promoted`, `alreadyApproved`, `skipped`, `transitionedToComplete`). Show the full rail at this completion state — Recommendations is done, Build brief comes next:
1753
+ - **`next`** render the next category per § 9.1 (in-phase chip). After the last category, prompt `proceed`.
1754
+ - **`proceed`** (from any category) → call `mcp__ritual__accept_recommendations({ exploration_id })`. Under the non-blocking model this **records the human review** (stamps `reviewedAt` / `reviewedBy`) and advances; it is NOT a draft→approved promotion (the recs are already `approved`). The downstream artifacts were queued at rec-gen time, so this returns fast. Then show the completion rail and continue to Step 9.5:
1930
1755
 
1931
1756
  ```text
1932
1757
  Ritual build
1933
- Context ✓ Scope ✓ Discovery ✓ Recommendations ● Build brief ○ Implementation (Your agent)
1758
+ ✓ Scope ✓ Discovery ✓ Recommendations ● Build brief ○ Implementation (Your agent)
1934
1759
 
1935
- Accepted {N} recommendations.
1760
+ Reviewed {N} recommendations.
1936
1761
 
1937
1762
  View: https://app.ritualapp.cloud/e/{exploration_id}
1938
1763
 
1939
- Next: generating the build brief…
1764
+ Next: preparing the build brief…
1940
1765
  ```
1941
1766
 
1942
- **Pulse (recommendations accepted):** Emit a pulse — this is almost always a state-tier crossing into **Recommendation-ready**. Render full.
1767
+ **Pulse (recommendations reviewed):** emit a pulse — this is almost always a state-tier crossing into **Recommendation-ready**. Render full.
1943
1768
 
1944
1769
  Continue to Step 9.5 (`Wait for requirements`).
1945
1770
 
1946
- ##### 9.B — Branch B: user is a collaborator (no admin acceptance available)
1947
-
1948
- Same landing screen as 9.1, but the action block changes — collaborators can request admin review instead of accepting directly:
1949
-
1950
- ```text
1951
- Ritual build
1952
- ✓ Context ✓ Scope ✓ Discovery ● Recommendations ○ Build brief ○ Implementation (Your agent)
1953
-
1954
- Scope:
1955
- {compact scope}
1956
-
1957
- Admin acceptance pending
1958
-
1959
- These recommendations are in {status — draft / pending_review}. Only an
1960
- admin can formally accept them.
1961
-
1962
- 1. {Category 1}
1963
- R1 {title}
1964
- R2 {title}
1965
-
1966
- ...
1967
-
1968
- Recommended: reply `request admin review` to send these for approval.
1969
- Or reply `detail R7`, `change R3: <edit>`, `drop R8`, or `hold`.
1970
-
1971
- (If your team allows it, you can continue to implementation before admin
1972
- acceptance — Ritual will mark the exploration as `implemented_ahead` so
1973
- the admin can reconcile later. Reply `continue` to take that path.)
1974
- ```
1975
-
1976
- Note the THREE-tier CTA structure for collaborators:
1977
- 1. `request admin review` — the recommended path (notifies admin, no implementation yet)
1978
- 2. `continue` — implement-ahead-of-acceptance (logs as `implemented_ahead`; admin can reconcile later)
1979
- 3. `hold` — stop entirely
1980
-
1981
- The `request admin review` action maps to the workspace notification endpoint (or falls back to a Slack/email DM the agent surfaces as a copyable message). The `implemented_ahead` path is documented in Step 11 / 12.
1982
-
1983
- If the user picks `continue`, proceed to Step 9.5. The `sync_implementation` call in Step 12 will automatically snapshot the rec status via the A1.5 column.
1771
+ <!-- lite:keep-end -->
1984
1772
 
1985
1773
  #### Step 9.5 — Wait for requirements (auto-triggered by Step 9)
1986
1774
 
@@ -2012,11 +1800,11 @@ Steps:
2012
1800
  | Response | Action |
2013
1801
  |---|---|
2014
1802
  | `status === 'READY'` | Proceed to Step 10 |
2015
- | `exists === false` (still null) for 3+ polls | The fire-and-forget hasn't reached the DB yet, OR Branch B was just hit (no LLM call yet). After several polls either keep polling OR proceed to Step 10 — the API auto-triggers generation inline if the set is still missing when the brief is requested (adds ~30s to the brief call but never hard-fails). |
1803
+ | `exists === false` (still null) for 3+ polls | The fire-and-forget hasn't reached the DB yet, OR `proceed` (accept_recommendations) hasn't run yet (no LLM call yet). After several polls either keep polling OR proceed to Step 10 — the API auto-triggers generation inline if the set is still missing when the brief is requested (adds ~30s to the brief call but never hard-fails). |
2016
1804
  | `status === 'GENERATING'` | Keep polling |
2017
1805
  | `status === 'FAILED'` | Surface `errorMessage` to the user; offer to retry by calling `generate_build_brief` directly (which will auto-trigger a fresh generation), OR by hitting `POST /requirements?force=true` via the web UI |
2018
1806
 
2019
- 4. **Special case — Branch B from Step 9 (collaborator did NOT call accept_recommendations):** there's no fire-and-forget auto-trigger because accept never ran. Skip the polling entirely and let Step 10's auto-trigger handle requirement generation inline. The brief call will take ~30s longer than it otherwise would.
1807
+ 4. **Special case — `proceed` not yet called (accept_recommendations hasn't run):** if the user jumped ahead without the rec-review `proceed`, there's no fire-and-forget auto-trigger from that path. Skip the polling entirely and let Step 10's auto-trigger handle requirement generation inline. The brief call will take ~30s longer than it otherwise would. (Note: auto-finalize at rec-gen completion usually already queued requirements, so this case is rare.)
2020
1808
 
2021
1809
  5. When `status === 'READY'`, tell the user one line ("Requirements ready…") and continue to Step 9.6 (if anti-goals exist) OR directly to Step 10 (if no anti-goals, audit step is skipped silently).
2022
1810
 
@@ -2210,15 +1998,15 @@ Call `mcp__ritual__generate_build_brief` with:
2210
1998
  - `recon_context` — the Step 3 `codebase_context_packet` plus any explicit phase/later candidates from discovery. Do not pass raw recon notes. This grounds "Codebase Anchors" in real file paths while keeping agent hypotheses auditable and non-authoritative.
2211
1999
  - `sources` — the **same** file-path array passed to `generate_considerations` and `generate_problem_statement` in Steps 4–5. Critical for KG consistency: the brief's "Previously Deferred" section only populates when overlapping prior implementations exist on these files.
2212
2000
 
2213
- Returns the brief markdown + an `id` + `kgContextUsed` block. The brief is **idempotent on (exploration, icp)** — same recommendation+requirement hashes return the cached READY row. Pass `force: true` only when a prompt-version update requires re-generation.
2001
+ Returns **immediately** with `status: 'GENERATING'` (synthesis runs in the background poll per Step 10b) UNLESS it's a cache hit, which returns `status: 'READY'` with the brief markdown directly. The brief is **idempotent on (exploration, icp)** — same recommendation+requirement hashes return the cached READY row. Pass `force: true` only when a prompt-version update requires re-generation (also returns `GENERATING` → poll).
2214
2002
 
2215
- ##### 10b — Timeout-recovery polling (CLI Tenet #8)
2003
+ ##### 10b — Status polling (CLI Tenet #8)
2216
2004
 
2217
- `generate_build_brief` can outlive the local MCP request timeout, especially when the API auto-triggers RequirementSet generation inline. You may see a local-timeout error while server-side work is still running.
2005
+ `generate_build_brief` is **fire-and-poll**: it returns almost immediately with `status: 'GENERATING'` (the synthesis runs server-side in the background) — NOT the finished brief. A cache hit returns `status: 'READY'` directly; treat that as done. So you no longer wait on a local timeout you poll the status from the start.
2218
2006
 
2219
- **Don't give up and don't blindly regenerate.** Instead, fall back to status polling:
2007
+ **Don't treat the GENERATING response as the brief, and don't re-call generate to "check".** Poll the status:
2220
2008
 
2221
- 1. On timeout/error from `generate_build_brief`, call `mcp__ritual__get_build_brief_status(exploration_id, icp)` immediately.
2009
+ 1. After `generate_build_brief` returns `GENERATING` (or on the rare local timeout), call `mcp__ritual__get_build_brief_status(exploration_id, icp)`.
2222
2010
  2. Poll using the standard async polling rule: one `Bash sleep 5` per poll iteration, then a fresh status call. Print a brief "still generating…" update every ~3 polls when the status is unchanged.
2223
2011
  3. Exit conditions:
2224
2012
 
@@ -2252,6 +2040,13 @@ Steps:
2252
2040
  - `contradicted` — brief claim is wrong; the code does something different.
2253
2041
  - `not_found` — symbol couldn't be located.
2254
2042
 
2043
+ **Narrating a finding (if you surface one before the summary): frame it as resolving drift, not as an error report.** Lead with *resolving drift between the brief and the codebase*, then ONE plain sentence describing the drift and where the real pattern lives. Do **not** lead with "X doesn't exist" / "references a function that doesn't exist" — a `not_found` / `contradicted` verdict is the verification working as intended (it caught a brief-vs-code gap before you shipped), not a failure to alarm the user about.
2044
+
2045
+ ❌ `get_core_apps is not in the codebase — the brief's RB-1 references a function that doesn't exist. The actual pattern is direct INSTALLED_APPS manipulation (index + replace), as seen in tests/settings.py.`
2046
+ ✅ `Resolving drift between the brief and the codebase: RB-1 cites get_core_apps, but the repo edits INSTALLED_APPS directly (index + replace — see tests/settings.py). Noting it in the verification.`
2047
+
2048
+ This is a progress line, not a gate — keep it to one sentence and continue; the structured findings land in `BUILD-BRIEF-VERIFICATION.md` and the Step 10d gate.
2049
+
2255
2050
  5. **Write `BUILD-BRIEF-VERIFICATION.md`** to disk alongside `BUILD-BRIEF.md` using the schema in `references/brief-verification-checklist.md`. Cite file + line range + actual code snippet on every contradiction. Do not fabricate evidence.
2256
2051
 
2257
2052
  6. **Sync the verification to Ritual's KG** — call `mcp__ritual__sync_brief_review` with:
@@ -2368,7 +2163,7 @@ End Step 10 with a single recommended action plus a cheap escape hatch — never
2368
2163
 
2369
2164
  ```text
2370
2165
  Ritual build
2371
- Context ✓ Scope ✓ Discovery ✓ Recommendations ● Build brief ○ Implementation (Your agent)
2166
+ ✓ Scope ✓ Discovery ✓ Recommendations ● Build brief ○ Implementation (Your agent)
2372
2167
 
2373
2168
  Build brief ready
2374
2169
 
@@ -2394,6 +2189,7 @@ Branch by user response. The CTA on screen is `go`, but accept these as synonyms
2394
2189
 
2395
2190
  **Pulse (Step 10 done):** Emit a pulse — this often crosses into **Implementation-ready** (90%+). Render full when that crossing happens. Use the build-brief celebration line: `✓ Build brief ready — discovery has become an implementation path.` If still below 90% (e.g. brief flagged residual debt), surface that in the pulse line itself and propose addressing it before coding.
2396
2191
 
2192
+ <!-- lite:skip-start reason="optional UX brief review is not part of lite" -->
2397
2193
  #### Step 10.5 — Optional UX brief review (entered ONLY when the user picks `ux-review` at Step 10d)
2398
2194
 
2399
2195
  This step is opt-in. If the user picked `go` at Step 10d, skip directly to Step 11. The `ux-review` path is reached only when the user explicitly asks for it at the Step 10d gate — there is no auto-gating in this MVP (later iterations may use Stage E's UI-surface classifier to suggest the path automatically; see `backlog_design_recon_stage_e.md`).
@@ -2473,7 +2269,7 @@ Steps:
2473
2269
 
2474
2270
  ```text
2475
2271
  Reply `go` to start implementation with the UX review as plan-mode input,
2476
- or `refine` / `drill {N}` / `pause` per the earlier options.
2272
+ or `drill {N}` / `pause` per the earlier options.
2477
2273
  ```
2478
2274
 
2479
2275
  When the user replies `go`, continue to Step 11 with the explicit instruction (passed to plan mode) to read both `BUILD-BRIEF.md` AND `UX-REVIEW.md`, and to use the "Plan Mode Prompt" block at the bottom of `UX-REVIEW.md` as its first numbered list — not a generic plan.
@@ -2487,6 +2283,8 @@ Steps:
2487
2283
 
2488
2284
  **Pulse (Step 10.5 done):** Re-emit the Step 10 pulse if the review surfaced material gaps or mismatches — Readiness can dip back below 90% when significant UX work is flagged that the brief didn't capture. If the review came back clean (zero mismatches, zero gaps, zero new-work), keep the existing pulse — the brief was already implementation-ready.
2489
2285
 
2286
+ <!-- lite:skip-end -->
2287
+ <!-- lite:keep-start -->
2490
2288
  #### Step 11 — Implement
2491
2289
 
2492
2290
  This step happens **inside** the same `/ritual build` chat if the agent is also the coding agent (Claude Code / Cursor / etc.), or hand-off if the user is implementing themselves.
@@ -2495,7 +2293,7 @@ The Implementation phase landing — full rail (the rail moves to Implementation
2495
2293
 
2496
2294
  ```text
2497
2295
  Ritual build
2498
- Context ✓ Scope ✓ Discovery ✓ Recommendations ✓ Build brief ● Implementation (Your agent)
2296
+ ✓ Scope ✓ Discovery ✓ Recommendations ✓ Build brief ● Implementation (Your agent)
2499
2297
 
2500
2298
  Implementation (Your agent)
2501
2299
 
@@ -2577,9 +2375,23 @@ The user is now in plan mode (from Step 11.0.5). The agent must:
2577
2375
 
2578
2376
  1. **Load `BUILD-BRIEF.md`** as the first input. If `BUILD-BRIEF-VERIFICATION.md` exists, load it too — every `contradicted` and `not_found` entry becomes an explicit constraint in the plan ("the brief claimed X but the code does Y; the plan must reconcile / not assume X"). If `UX-REVIEW.md` exists alongside `BUILD-BRIEF.md` (the user opted into Step 10.5), use the "Plan Mode Prompt" block at its bottom as the FIRST input — its numbered list of mismatches / gaps / new-work surfaces is the tailored agenda. The generic plan-mode template is the fallback for when only the brief exists.
2579
2377
 
2580
- 2. **Produce a numbered implementation plan** whose top entries are: (1) the RBs from the brief, (2) any contradictions surfaced by verification, (3) any "new work" surfaces from UX review. The plan should name the specific files / functions / new modules each plan step will touch concrete enough that the user can spot a mistake before any edit happens.
2378
+ 2. **Load the SCOPE CONTRACT as hard constraints (the load-bearing step prevention, not just detection).** The brief read (`get_build_brief_status` `scopeContractResolved`, or the `generate_build_brief` response) carries the SAME typed contract Ritual will audit your plan against at Step 11.1.6. Treat it as binding and put it at the TOP of the plan-mode prompt verbatim:
2379
+
2380
+ > **Scope contract — your plan must honour this (it will be audited):**
2381
+ > - **MUST cover** (one or more plan steps each, and cite the requirement): {each `scopeContractResolved.inScope[].text`}
2382
+ > - **Do NOT implement — deferred to a LATER PR** (out of scope for this change): {each `deferred[].text`}
2383
+ > - **Do NOT cross — non-goals**: {each `antiGoals[].text`}
2384
+ > - **Open questions — do NOT silently implement; flag if you must touch**: {each `discoveryGates[].text`}
2581
2385
 
2582
- 3. **Stay in plan mode until the user accepts the plan.** Do NOT switch to edit/auto-accept mode until the user explicitly approves the plan in plan mode (Claude Code's "accept plan" affordance, or the user typing `accept` / `looks good` / `go`).
2386
+ This is what makes plan mode deliver on the promise of the brief (which delivers on the recs). Feeding the contract in UP FRONT prevents the divergences Step 11.1.6 would otherwise have to catch and send back.
2387
+
2388
+ 3. **Produce a numbered implementation plan** that:
2389
+ - has **one or more steps covering EVERY in-scope requirement** above (map each step to the requirement id it implements — this is the coverage the audit checks),
2390
+ - implements **none** of the deferred items and crosses **none** of the non-goals,
2391
+ - puts the RBs, any verification contradictions, and any UX "new work" surfaces at the top,
2392
+ - names the specific files / functions / new modules each step touches — concrete enough that the user can spot a mistake before any edit.
2393
+
2394
+ 4. **Stay in plan mode until the user accepts the plan.** Do NOT switch to edit/auto-accept mode until the user explicitly approves the plan in plan mode (Claude Code's "accept plan" affordance, or the user typing `accept` / `looks good` / `go`).
2583
2395
 
2584
2396
  ##### 11.1.5 — Optional: save the implementation plan as a markdown artifact
2585
2397
 
@@ -2622,6 +2434,87 @@ Save this plan to `IMPLEMENTATION-PLAN.md` before coding? (y/N)
2622
2434
 
2623
2435
  **Why this matters:** `BUILD-BRIEF.md` is the Ritual requirements artifact (what + why). `IMPLEMENTATION-PLAN.md` is the agent's concrete execution strategy (how). For non-trivial implementations, saving both gives reviewers a useful bridge from requirement to code — and gives `/ritual lineage` queries a richer trail to surface on future builds touching the same files.
2624
2436
 
2437
+ <!-- lite:skip-start reason="optional plan-fidelity audit is not part of lite" -->
2438
+ ##### 11.1.6 — Optional: audit the plan against the brief (Audit 3 / plan-fidelity)
2439
+
2440
+ After plan mode produces the plan and **before any code edits**, you can audit the plan against the build brief's frozen **scope contract** (its in-scope requirements, discovery-gate requirements, and anti-goals). This is **Audit 3 / R6** — the downstream bookend to the Step 9.6 recs audit. It's non-circular by construction: the contract derives from discovery/recs, never the plan, so a flagged divergence is a real drift, not a tautology.
2441
+
2442
+ **Gate behavior by build mode** (from Step 0.1's `auditMode`):
2443
+
2444
+ - **`normal` (default):** offer it; default is to skip (most plans are faithful).
2445
+ - **`audited`:** recommend it (default yes).
2446
+ - **`strict`:** run it automatically (no prompt), and treat an `anti_goal_violation` as blocking.
2447
+
2448
+ **Rendering contract — verbatim (normal / audited modes):**
2449
+
2450
+ ```text
2451
+ Plan ready — audit it against the brief before coding?
2452
+
2453
+ Ritual can check this plan against BUILD-BRIEF.md's scope contract — flagging
2454
+ anything the plan drops (a brief requirement no step covers), sneaks in
2455
+ (out-of-scope work), or that crosses a non-goal — before you write code.
2456
+
2457
+ Reply `audit-plan` to run it, or `proceed` to start implementing.
2458
+ ```
2459
+
2460
+ [USER PAUSE] Branch on response:
2461
+
2462
+ - **`audit-plan`** (or auto, in `strict` mode): call
2463
+ `mcp__ritual__audit_plan(exploration_id, plan_content)` where `plan_content`
2464
+ is the implementation plan plan mode just produced (the same text you'd save to
2465
+ `IMPLEMENTATION-PLAN.md`). The server normalizes it to plan operations and runs
2466
+ R6 against the brief's scope contract. It's async — the tool polls to
2467
+ completion and returns a thin payload:
2468
+ - `audit_status: "ok"` (no divergences) → tell the user the plan is faithful to
2469
+ the brief and continue to Step 11.2.
2470
+ - `audit_status: "needs_attention"` → render each divergence (`divergence_kind`
2471
+ + the `plan_op` and/or `brief_reference` it concerns + `rationale`). Group by
2472
+ kind: **missing_brief_decision** ("the brief asked for X; no plan step covers
2473
+ it" — computed deterministically from coverage), **out_of_scope_addition**
2474
+ ("step N does X, which maps to nothing in the brief"), **premature_implementation**
2475
+ ("step N implements X, which the brief deferred to a LATER phase/PR — not this
2476
+ one"), **scope_creep** ("step N covers X but does substantially more"). Then
2477
+ pause: *"Revise the plan to address these (back to plan mode), or proceed and
2478
+ accept the divergences? Reply `revise` or `proceed`."*
2479
+ - `audit_status: "blocked"` (an `anti_goal_violation`) → surface it prominently:
2480
+ *"⚠ The plan advances something the brief explicitly forbids: {evidence}. This
2481
+ crosses a non-goal you set during discovery."* In `strict` mode this blocks —
2482
+ require `revise` or an explicit `override` with a one-line justification. In
2483
+ other modes, strongly recommend `revise`.
2484
+ - On `revise`: the audit response carries a ready-to-paste **`revision_directive`**
2485
+ (assembled from the structured `revisions[]`, blockers first — each is a
2486
+ `request_plan_revision` repair keyed to a specific divergence). Feed that
2487
+ directive **verbatim** back into plan mode as the revision agenda (back to
2488
+ Step 11.1, keeping the scope contract from 11.1's step 2 in force), let plan
2489
+ mode produce a revised plan, then **re-run `audit_plan` on the revised plan**.
2490
+ This is the runtime repair loop: `audit_plan` → `revise` → `audit_plan`.
2491
+ - **Cap it at 2 revision rounds.** If divergences remain after the 2nd
2492
+ revision, stop looping and surface the residual divergences to the user with
2493
+ a decision: *"These divergences persist after 2 revisions — accept them
2494
+ (they'll be logged), or stop here? Reply `accept` or `pause`."* Don't churn.
2495
+ - On `proceed` / `override` / `accept`: continue to Step 11.2. Treat each
2496
+ accepted divergence as a **`confirm_intentional_divergence`** — record it as a
2497
+ Step 12 `sync_implementation` decision (`area` = the requirement/anti-goal,
2498
+ `choice` = "intentionally diverged: {why}", `source_recommendation_id` = the
2499
+ `brief_reference.id`) so the override is captured in lineage rather than lost.
2500
+ A persistent *anti-goal violation* the user keeps overriding is a signal the
2501
+ BRIEF (or its anti-goals) is wrong — surface that, don't just bury it.
2502
+ - **`proceed`** (or anything else): skip the audit and continue to Step 11.2. Do
2503
+ not re-prompt.
2504
+
2505
+ **Rules:**
2506
+
2507
+ - **Requires a READY BuildBrief with a scope contract.** Briefs synthesized before
2508
+ the scope-contract feature lack one; if `audit_plan` returns a 400 about a
2509
+ missing contract, regenerate the brief (`generate_build_brief force:true`) or
2510
+ skip the audit — don't block the build on it.
2511
+ - **Advisory, not auto-repair.** R6 surfaces divergences; the fix is always a
2512
+ human-in-the-loop plan revision or an explicit accept. Never silently rewrite
2513
+ the plan.
2514
+ - **Don't dump the raw normalized plan ops** into the chat — surface the
2515
+ divergences (the signal), not the methodology.
2516
+
2517
+ <!-- lite:skip-end -->
2625
2518
  ##### 11.2 — Implement
2626
2519
 
2627
2520
  1. Use the standard coding-loop tools (Edit/Write/Bash/etc.) to execute the accepted plan.
@@ -2669,40 +2562,55 @@ If the user says "y" / "push" / "open PR":
2669
2562
  3. `gh pr create --base <default-branch> --title <…> --body <…>`.
2670
2563
  4. Surface the PR URL to the user.
2671
2564
 
2565
+ **Write the PR body for a maintainer who has never heard of Ritual.** Lead with what changed, *where to look* (in review order), *why*, and *how to verify* — so a reviewer can move fast and trust the change. Ritual lineage goes at the bottom, not the top. Fill every section from real artifacts (brief decisions, the diff, the test files); never leave a `<placeholder>` in the posted body.
2566
+
2672
2567
  **PR body template:**
2673
2568
 
2674
2569
  ```markdown
2675
- ## Summary
2570
+ ## What this PR does
2676
2571
 
2677
- <2-3 lines max, derived from the build brief's Goal section>
2572
+ <2-3 plain sentences: the change + the problem it solves, derived from the build brief's Goal>
2678
2573
 
2679
- ## RBs satisfied
2574
+ ## Where to look (review order)
2680
2575
 
2681
- | RB | Title | Where |
2682
- |---|---|---|
2683
- | RB-1 | <title from brief> | <key file/module> |
2684
- | RB-2 | <title from brief> | <…> |
2685
- | … | | |
2576
+ 1. `<path>` <the load-bearing change; start here>
2577
+ 2. `<path>` — <how it integrates>
2578
+ 3. `<path>` <schema/data changes, if any>
2579
+ <ordered load-bearing plumbing, so review time goes where it matters>
2686
2580
 
2687
- ## Test plan
2581
+ ## Why / key decisions
2688
2582
 
2689
- - <one bullet per test file / suite added>
2690
- - <coverage notes if non-trivial>
2583
+ - <decision + the trade-off / alternative rejected — the 1-3 calls a reviewer might second-guess, taken from the brief's decisions>
2691
2584
 
2692
- ## Exploration
2585
+ ## How to verify
2693
2586
 
2694
- - Exploration: [<exploration name>](https://app.ritualapp.cloud/e/<exploration_id>)
2695
- - Build brief: see `BUILD-BRIEF.md` (committed in this PR for reviewer reference)
2696
- - Implementation plan: see `IMPLEMENTATION-PLAN.md` *(only include this line if Step 11.1.5 actually wrote the file — agent execution strategy alongside the brief)*
2697
- - Deferrals intentionally punted: <count, with one-line each>
2587
+ - Automated: <test files + how to run them>
2588
+ - Manual: <steps a reviewer runs locally to see it work>
2698
2589
 
2699
- ---
2590
+ ## Scope & follow-ups
2591
+
2592
+ - In scope: <what this PR delivers>
2593
+ - Out of scope / deferred: <intentional punts, one line each — so reviewers don't flag them as gaps>
2594
+
2595
+ ## Risk / blast radius
2596
+
2597
+ - <backward-compat, migration ordering, perf — what could break in prod>
2598
+
2599
+ ## Ritual lineage
2600
+
2601
+ - Exploration: [<exploration name>](<EXPLORATION_URL>) · Build brief: `BUILD-BRIEF.md` (committed for reviewer reference) · Requirements satisfied: <N/M>
2602
+ - Implementation plan: see `IMPLEMENTATION-PLAN.md` *(only if Step 11.1.5 wrote it)*
2603
+
2604
+ Ritual-Exploration: <exploration_id>
2700
2605
 
2701
2606
  🪷 Generated via [Ritual](https://ritual.work) — closing the loop with `sync_implementation` after merge.
2702
2607
  ```
2703
2608
 
2609
+ > **`<EXPLORATION_URL>` MUST be environment-correct — never hardcode `app.ritualapp.cloud`.** Use the server-resolved exploration URL the MCP returns (built from the server's `WEB_URL`). Hardcoding production breaks the link for **dev** builds (the exploration lives in the dev DB) and for **self-hosted / single-tenant enterprise** deployments (the exploration lives on the customer's own Ritual instance, not Ritual's SaaS). If the MCP response does not carry a URL, derive the base from your Ritual auth issuer rather than assuming production. Same rule for the `Ritual-Exploration-Url` commit trailer.
2610
+
2704
2611
  If the user is implementing manually: hand off the brief + the branch-strategy note ("create a feature branch off `main` — don't commit to trunk"), tell them you'll be ready to run `sync_implementation` when they're done.
2705
2612
 
2613
+ <!-- lite:keep-end -->
2706
2614
  #### Step 12 — Close the loop with `sync_implementation`
2707
2615
 
2708
2616
  ##### 12.0 — What this step does (in product terms)
@@ -2711,7 +2619,7 @@ Before asking for permission, frame the call in language the user can act on. `s
2711
2619
 
2712
2620
  ```text
2713
2621
  Ritual build
2714
- Context ✓ Scope ✓ Discovery ✓ Recommendations ✓ Build brief ● Implementation (Your agent)
2622
+ ✓ Scope ✓ Discovery ✓ Recommendations ✓ Build brief ● Implementation (Your agent)
2715
2623
 
2716
2624
  Log implementation
2717
2625
 
@@ -2741,7 +2649,7 @@ Call `mcp__ritual__sync_implementation` with:
2741
2649
  - `deferrals[]` — for things you intentionally punted (`rb_id`, `description`, `reason`, `severity`, `related_files[]`, `related_modules[]`)
2742
2650
  - `gate_verdict`, `adherence_rate` — your own self-reported quality signals
2743
2651
 
2744
- The A1.5 snapshot column auto-captures each linked recommendation's status at the moment of sync — so if you implemented while the rec was still `draft` (Branch B in Step 9), the timeline is preserved automatically.
2652
+ The A1.5 snapshot column auto-captures each linked recommendation's status at the moment of sync — so if you implemented before the rec review's `proceed` (while the rec was still un-reviewed), the timeline is preserved automatically.
2745
2653
 
2746
2654
  When sync_implementation succeeds, the response includes:
2747
2655
 
@@ -2754,7 +2662,7 @@ When sync_implementation succeeds, the response includes:
2754
2662
 
2755
2663
  ```text
2756
2664
  Ritual build
2757
- Context ✓ Scope ✓ Discovery ✓ Recommendations ✓ Build brief ✓ Implementation (Your agent)
2665
+ ✓ Scope ✓ Discovery ✓ Recommendations ✓ Build brief ✓ Implementation (Your agent)
2758
2666
 
2759
2667
  ✓ Logged implementation for {exploration name}
2760
2668
 
@@ -2773,7 +2681,7 @@ any touched file to trace this back later.
2773
2681
 
2774
2682
  The `Implemented:` line surfaces a representative slice of WHAT got implemented (concrete area:choice pairs from the underlying `decisions[]` payload) rather than a labeled count. Per the vocabulary rule in `cli-output-contract.md`: the word "decisions" is not surfaced as a user-facing label; the artifacts ARE the signal.
2775
2683
 
2776
- If any anchor's `recommendationStatusAtImplementation` is NOT `approved` (i.e. the Branch B path), add a callout — still frame in implementation/recommendation terms. Append this block BELOW the completion message (no separate rail; the rail is already rendered at the top):
2684
+ If any anchor's `recommendationStatusAtImplementation` is NOT `approved` (i.e. implemented before the rec review's `proceed`), add a callout — still frame in implementation/recommendation terms. Append this block BELOW the completion message (no separate rail; the rail is already rendered at the top):
2777
2685
 
2778
2686
  ```text
2779
2687
  ⚠ {M} of the recommendations were implemented while still in {status}
@@ -2789,7 +2697,7 @@ User-visible (full rail — sync failure is a top-level state):
2789
2697
 
2790
2698
  ```text
2791
2699
  Ritual build
2792
- Context ✓ Scope ✓ Discovery ✓ Recommendations ✓ Build brief ● Implementation (Your agent)
2700
+ ✓ Scope ✓ Discovery ✓ Recommendations ✓ Build brief ● Implementation (Your agent)
2793
2701
 
2794
2702
  Sync failed (recoverable)
2795
2703
 
@@ -2827,7 +2735,7 @@ If stale, surface to the user with the full rail (top-level decision gate):
2827
2735
 
2828
2736
  ```text
2829
2737
  Ritual build
2830
- Context ✓ Scope ✓ Discovery ✓ Recommendations ✓ Build brief ● Implementation (Your agent)
2738
+ ✓ Scope ✓ Discovery ✓ Recommendations ✓ Build brief ● Implementation (Your agent)
2831
2739
 
2832
2740
  Pending sync is stale
2833
2741
 
@@ -2850,7 +2758,85 @@ Reply `1`, `2`, or `3`. Reply `pause` to stop here.
2850
2758
 
2851
2759
  If the saved payload's `commits[]` matches current git state, proceed silently to the retry.
2852
2760
 
2853
- #### Step 13 — Optional follow-up
2761
+ <!-- lite:keep-start -->
2762
+ #### Step 13 — Suggest the next job to be done
2763
+
2764
+ The loop just closed (Step 12). Rather than stop cold and make the user
2765
+ re-bootstrap context for whatever they do next, offer the **next best job to be
2766
+ done** — a NEW discovery exploration in THIS workspace, so the knowledge graph,
2767
+ deferrals, and prior explorations you just built keep compounding. This is
2768
+ forward motion, never required work.
2769
+
2770
+ ##### 13.1 — Generate the suggestion set
2771
+
2772
+ Call `mcp__ritual__suggest_next_job` with `{ exploration_id }` (the
2773
+ just-finished exploration). It returns 1 primary + up to 2 alternatives. Each is
2774
+ a NEW exploration that runs its own discovery — it is **never** "go implement the
2775
+ recommendations you already have" (that's the coding agent's job — `/ritual
2776
+ resume` on this same exploration). Each suggestion carries:
2777
+
2778
+ - `jtbd` + `label` — the job, already picked
2779
+ - `reasoning` — the concrete signal it cites (a deferral, an unaddressed recommendation, or the natural lifecycle continuation)
2780
+ - `descriptionSeed` — a first-person "what to explore" framing to pre-fill the next exploration's problem box
2781
+ - `recommendedPersona`, `sourceRecommendationId`, `id`
2782
+
2783
+ Also returned: `recommendationsAddressed` (false ⇒ this exploration still has
2784
+ clear-to-implement work that ships via `resume`, not a next job).
2785
+
2786
+ - **If `suggestions` is empty** (or the call errors) → say nothing about next jobs; drop straight to 13.3. Never block the closed-loop completion on this.
2787
+
2788
+ ##### 13.2 — Present the picker
2789
+
2790
+ **[USER PAUSE]** Render the standard list-picker (primary first, marked ★):
2791
+
2792
+ ```text
2793
+ Next job to be done
2794
+
2795
+ {exploration name} is shipped and logged. To keep building on what this
2796
+ workspace now knows, here's the next discovery worth running:
2797
+
2798
+ ★ 1. {primary label}
2799
+ {primary reasoning}
2800
+
2801
+ 2. {alt1 label}
2802
+ {alt1 reasoning}
2803
+
2804
+ 3. {alt2 label}
2805
+ {alt2 reasoning}
2806
+
2807
+ Reply `1`, `2`, or `3` to start it — the job's already picked, so you'll go
2808
+ straight to framing what to explore. Reply `skip` to stop here.
2809
+ ```
2810
+
2811
+ Only render lines for the suggestions actually returned (there may be just a
2812
+ primary, or a primary + 1). If `recommendationsAddressed` is `false`, add ONE
2813
+ line below the picker — lean on the coding agent, don't turn Ritual into a
2814
+ backlog manager:
2815
+
2816
+ ```text
2817
+ ({N} item{s} from this exploration are clear to implement — say `resume` to continue shipping them here.)
2818
+ ```
2819
+
2820
+ **[USER PAUSE — required, do not auto-answer]** Wait for the user's reply.
2821
+
2822
+ ##### 13.2.1 — On pick (`1` / `2` / `3`)
2823
+
2824
+ The picked suggestion is a NEW exploration in the SAME workspace with the job
2825
+ already chosen — so **advance, don't re-bootstrap**:
2826
+
2827
+ 1. Skip the work-item / job pick entirely (Steps 0–4) — `jtbd` is already set by the suggestion.
2828
+ 2. Go to **Step 5 (problem frame)** using the suggestion's `descriptionSeed` as the DRAFT "what are you trying to explore?" — present it as an editable starting point, not a blank box. Let the user refine it.
2829
+ 3. At **Step 6 (`create_exploration`)**, pass `from_next_job_suggestion_id` = the picked suggestion's `id`. The server links the new exploration to its parent + source recommendation, defaults the `jtbd` from the suggestion, and marks the suggestion started (it stops showing as an open next job, and the originating recommendation now reads as handed off).
2830
+ - If `create_exploration` returns **409** (this next job was already started), don't create a duplicate — tell the user it's already in progress and offer to open that exploration instead.
2831
+ 4. Continue the normal flow from **Step 7 (discovery)**.
2832
+
2833
+ ##### 13.2.2 — On `skip`
2834
+
2835
+ Acknowledge and drop to 13.3. The suggestion set is persisted — a later `ritual
2836
+ graph status` or re-run of `/ritual build` in this workspace can surface it
2837
+ again; nothing is lost.
2838
+
2839
+ ##### 13.3 — Follow-up pointer
2854
2840
 
2855
2841
  If they want to check the state at any time, point them at:
2856
2842
 
@@ -2858,9 +2844,10 @@ If they want to check the state at any time, point them at:
2858
2844
 
2859
2845
  Or: re-run `/ritual build` in this workspace later — the existing-work check will surface this exploration with its new `done` state badge, and any future build whose `sources` overlap will pull in the decisions + deferrals you just logged as priorContext.
2860
2846
 
2847
+ <!-- lite:keep-end -->
2861
2848
  ### Failure modes & recovery
2862
2849
 
2863
- **Discovery generation hangs (>5 min polling without `ready: true`)**: ask the user — wait longer? retry (`suggest_discovery_questions` again, new task)? or skip discovery entirely (proceed to Step 8 without picked questions)?
2850
+ **Discovery generation hangs (>5 min polling without `ready: true`)**: ask the user — wait longer, or retry (`suggest_discovery_questions` again, new task)? Discovery questions are required (the user must pick at least 6 to run), so there is no skip-and-proceed option; if generation can't produce questions, surface the failure rather than running with none.
2864
2851
 
2865
2852
  **Agentic run fails or stalls**: surface the error, offer retry or stop.
2866
2853
 
@@ -2908,8 +2895,9 @@ This subcommand exclusively uses Ritual MCP tools, in the order they appear:
2908
2895
  24f. `mcp__ritual__apply_repair` (Step 9.6 — apply or waive a structured repair instruction returned by an audit iteration; cli 0.10.0+)
2909
2896
  24g. `mcp__ritual__get_audit_chain` (Step 9.6 — fetch the full chain trail for review/lineage; cli 0.10.0+)
2910
2897
  25. `mcp__ritual__sync_implementation` (Step 12)
2898
+ 26. `mcp__ritual__suggest_next_job` (Step 13.1 — propose the next discovery job after the loop closes; `create_exploration` at Step 13.2.1 takes `from_next_job_suggestion_id` to record the handoff)
2911
2899
 
2912
- 35 of the 46 Ritual MCP tools (cli 0.10.0+: the 3 new audit tools — `audit_recommendations`, `apply_repair`, `get_audit_chain` — joined the linear flow at Step 9.6 (audit-suite.md § Audit 1)). The other 11 (`ping`, `get_exploration`, `list_agentic_runs`, `add_collaborator`, `check_anti_goals`, `query_knowledge_graph`, `get_workspace_overview`, `get_knowledge_source`, `remove_knowledge_source`, `get_recommendation_attestation`, `score_context_pulse`) are situational, not part of the linear build flow.
2900
+ 36 of the 48 Ritual MCP tools (cli 0.10.0+: the 3 audit tools — `audit_recommendations`, `apply_repair`, `get_audit_chain` — joined the linear flow at Step 9.6 (audit-suite.md § Audit 1); cli 0.22.0+: `suggest_next_job` joined at Step 13 to close-then-continue the loop). The other 12 (`ping`, `get_exploration`, `list_agentic_runs`, `add_collaborator`, `check_anti_goals`, `query_knowledge_graph`, `get_workspace_overview`, `get_knowledge_source`, `remove_knowledge_source`, `get_recommendation_attestation`, `score_context_pulse`, `get_next_job`) are situational, not part of the linear build flow (`get_next_job` re-reads a persisted next-job set; the flow itself only needs `suggest_next_job`).
2913
2901
 
2914
2902
  **Note on `check_anti_goals` vs `audit_recommendations`:** these are distinct tools. `check_anti_goals` is the older, single-shot validation tool (read-tier; one LLM call, no chain rows) used ad-hoc to validate a proposal against an exploration's current anti-goal set. `audit_recommendations` (cli 0.10.0+, write-tier) starts a stateful `AuditChain` that runs R4 (constraint-perturbation) against a brief, produces structured `SurvivalReport` + `RepairInstruction` rows, and supports the apply/waive repair loop. Use `check_anti_goals` for one-shot proposal validation; use `audit_recommendations` for chain-tracked constraint-survival audits of a brief.
2915
2903
 
@@ -2918,8 +2906,8 @@ This subcommand exclusively uses Ritual MCP tools, in the order they appear:
2918
2906
  When `/ritual build` completes, the exploration is in COMPLETE state with accepted recommendations AND a build brief has been generated AND (if the agent implemented in-chat) `sync_implementation` has been called. The full close-the-loop cycle now lives inside this skill — there's no separate downstream `/ritual-builder-spec` step required.
2919
2907
 
2920
2908
  Variants:
2921
- - Admin runs the whole flow: Steps 1 → 13, no handoff.
2922
- - Collaborator runs the build flow: Steps 1 13 with Step 9 Branch B (no admin acceptance available); the resulting exploration shows `⚠ implemented_ahead` until an admin reconciles.
2909
+ - One person runs the whole flow: Steps 1 → 13, no handoff. Step 9 is a uniform non-blocking review (recs are auto-accepted; `proceed` records the review and continues).
2910
+ - Implementation lands before the rec review/`proceed`: the `sync_implementation` snapshot freezes that timeline and the exploration shows `⚠ implemented_ahead` until reconciled (see Step 12).
2923
2911
  - Resume mid-flow: the existing-work check surfaces explorations with state badges and jumps directly to the right phase. (Or, for the "I just want to pick up" intent, see `/ritual resume` below.)
2924
2912
 
2925
2913
  ---