@ritualai/cli 0.9.6 → 0.24.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.
- package/dist/commands/doctor.js +59 -23
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/init.js +33 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/uninstall.js +114 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/agents/providers.js +44 -4
- package/dist/lib/agents/providers.js.map +1 -1
- package/dist/lib/memory-update.js +158 -0
- package/dist/lib/memory-update.js.map +1 -0
- package/dist/lib/uninstall-plan.js +102 -0
- package/dist/lib/uninstall-plan.js.map +1 -0
- package/package.json +1 -1
- package/skills/claude-code/ritual/.ritual-bundle.json +2 -2
- package/skills/claude-code/ritual/SKILL.md +14 -11
- package/skills/claude-code/ritual/manifest.json +0 -5
- package/skills/claude-code/ritual/references/async-polling.md +5 -5
- package/skills/claude-code/ritual/references/build-flow.md +739 -497
- package/skills/claude-code/ritual/references/change-preflight.md +81 -0
- package/skills/claude-code/ritual/references/cli-output-contract.md +2 -2
- package/skills/claude-code/ritual/references/context-pulse-flow.md +0 -1
- package/skills/claude-code/ritual/references/lite-flow.md +2781 -0
- package/skills/claude-code/ritual/references/scoring-fallback.md +1 -1
- package/skills/codex/ritual/.ritual-bundle.json +2 -2
- package/skills/codex/ritual/SKILL.md +14 -11
- package/skills/codex/ritual/manifest.json +0 -5
- package/skills/codex/ritual/references/async-polling.md +5 -5
- package/skills/codex/ritual/references/build-flow.md +739 -497
- package/skills/codex/ritual/references/change-preflight.md +81 -0
- package/skills/codex/ritual/references/cli-output-contract.md +2 -2
- package/skills/codex/ritual/references/context-pulse-flow.md +0 -1
- package/skills/codex/ritual/references/lite-flow.md +2781 -0
- package/skills/codex/ritual/references/scoring-fallback.md +1 -1
- package/skills/cursor/ritual/.ritual-bundle.json +2 -2
- package/skills/cursor/ritual/SKILL.md +14 -11
- package/skills/cursor/ritual/manifest.json +0 -5
- package/skills/cursor/ritual/references/async-polling.md +5 -5
- package/skills/cursor/ritual/references/build-flow.md +739 -497
- package/skills/cursor/ritual/references/change-preflight.md +81 -0
- package/skills/cursor/ritual/references/cli-output-contract.md +2 -2
- package/skills/cursor/ritual/references/context-pulse-flow.md +0 -1
- package/skills/cursor/ritual/references/lite-flow.md +2781 -0
- package/skills/cursor/ritual/references/scoring-fallback.md +1 -1
- package/skills/gemini/ritual/.ritual-bundle.json +2 -2
- package/skills/gemini/ritual/SKILL.md +14 -11
- package/skills/gemini/ritual/manifest.json +0 -5
- package/skills/gemini/ritual/references/async-polling.md +5 -5
- package/skills/gemini/ritual/references/build-flow.md +739 -497
- package/skills/gemini/ritual/references/change-preflight.md +81 -0
- package/skills/gemini/ritual/references/cli-output-contract.md +2 -2
- package/skills/gemini/ritual/references/context-pulse-flow.md +0 -1
- package/skills/gemini/ritual/references/lite-flow.md +2781 -0
- package/skills/gemini/ritual/references/scoring-fallback.md +1 -1
- package/skills/kiro/ritual/.ritual-bundle.json +2 -2
- package/skills/kiro/ritual/SKILL.md +14 -11
- package/skills/kiro/ritual/manifest.json +0 -5
- package/skills/kiro/ritual/references/async-polling.md +5 -5
- package/skills/kiro/ritual/references/build-flow.md +739 -497
- package/skills/kiro/ritual/references/change-preflight.md +81 -0
- package/skills/kiro/ritual/references/cli-output-contract.md +2 -2
- package/skills/kiro/ritual/references/context-pulse-flow.md +0 -1
- package/skills/kiro/ritual/references/lite-flow.md +2781 -0
- package/skills/kiro/ritual/references/scoring-fallback.md +1 -1
- package/skills/vscode/ritual/.ritual-bundle.json +2 -2
- package/skills/vscode/ritual/SKILL.md +14 -11
- package/skills/vscode/ritual/manifest.json +0 -5
- package/skills/vscode/ritual/references/async-polling.md +5 -5
- package/skills/vscode/ritual/references/build-flow.md +739 -497
- package/skills/vscode/ritual/references/change-preflight.md +81 -0
- package/skills/vscode/ritual/references/cli-output-contract.md +2 -2
- package/skills/vscode/ritual/references/context-pulse-flow.md +0 -1
- package/skills/vscode/ritual/references/lite-flow.md +2781 -0
- package/skills/vscode/ritual/references/scoring-fallback.md +1 -1
- package/skills/claude-code/ritual/references/discovery-classification.md +0 -175
- package/skills/codex/ritual/references/discovery-classification.md +0 -175
- package/skills/cursor/ritual/references/discovery-classification.md +0 -175
- package/skills/gemini/ritual/references/discovery-classification.md +0 -175
- package/skills/kiro/ritual/references/discovery-classification.md +0 -175
- package/skills/vscode/ritual/references/discovery-classification.md +0 -175
|
@@ -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
|
|
|
@@ -85,8 +85,39 @@ Pausing discipline is still load-bearing — every `[USER PAUSE]` later in the f
|
|
|
85
85
|
|
|
86
86
|
The table is here so future contributors understand WHY the heads-up mentions Claude Code's Shift+Tab specifically — that's the dominant target client. If we add an elicitation-based picker (see `documents/architecture/selection-cursor-pattern.md` §"Future — MCP elicitation"), the auto-mode concern reduces further because elicitation form-mode requires actual user input regardless of agent mode.
|
|
87
87
|
|
|
88
|
+
##### Step 0.1 — Parse build-mode flags (load-bearing for Step 9.6, future Audit 2/3 gates)
|
|
89
|
+
|
|
90
|
+
Per `documents/architecture/audit-suite.md` § 7a, `/ritual build` accepts three audit-mode levels:
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
/ritual build <problem> → auditMode = 'normal' (today's behavior, default proceed)
|
|
94
|
+
/ritual build --audited <problem> → auditMode = 'audited' (recommend at each gate)
|
|
95
|
+
/ritual build --audit=strict <problem> → auditMode = 'strict' (auto-run with 90s/chain time budget)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Aliases the SKILL accepts (for agent-friendly UX):
|
|
99
|
+
- `--audit` (no-equals form, treated identically to `--audited`)
|
|
100
|
+
- `audited` (bareword form, agent-friendly when users type conversationally)
|
|
101
|
+
|
|
102
|
+
At Step 0 (or whenever the agent first parses the user's `/ritual build` invocation), extract the audit-mode flag and store as `auditMode` in working memory. Default to `'normal'` if no flag present. The audit gate at Step 9.6 (and future Audits 2/3 at Steps 10b.5 + 11.1, ships in PRs B/C) read this variable to choose between three prompt styles.
|
|
103
|
+
|
|
104
|
+
If the user types `always audit for this build` mid-flow at the Step 9.6 prompt, upgrade `auditMode` from `'normal'` or `'audited'` → `'strict'` for any remaining audit gates in the same session. The upgrade is session-scoped (doesn't persist across `/ritual build` invocations).
|
|
105
|
+
|
|
106
|
+
Persist `auditMode` to `Exploration.metadata.auditMode` at `create_exploration` time (additive JSONB key — no schema migration) so `/ritual resume <exploration-id>` picks up the same mode the original build started with, and `/ritual lineage <exploration-id>` can render which gates ran + their outcomes.
|
|
107
|
+
|
|
88
108
|
#### Step 1 — Pick a workspace
|
|
89
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
|
+
|
|
90
121
|
Resolution order:
|
|
91
122
|
|
|
92
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.
|
|
@@ -258,7 +289,7 @@ Steps:
|
|
|
258
289
|
- Use the state badge to decide which step to jump to (see "Suggested next action" column above).
|
|
259
290
|
- Skip ahead in this skill — don't re-run Steps 2-9 for an exploration that already has them done.
|
|
260
291
|
- For `ready` or `in_flight` states, jump directly to Step 10 (build brief generation).
|
|
261
|
-
- For `awaiting_admin`, jump to Step 9 (review +
|
|
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.
|
|
262
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.
|
|
263
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:
|
|
264
295
|
|
|
@@ -865,6 +896,55 @@ If the user says "skip" / "none" / "later", proceed silently to Step 4. Do NOT p
|
|
|
865
896
|
|
|
866
897
|
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).
|
|
867
898
|
|
|
899
|
+
#### Step 3.9 — Classify the work item + pick the lead persona
|
|
900
|
+
|
|
901
|
+
Before generating sub-problems, settle **what job this is** and **whose lens leads it** — both shape
|
|
902
|
+
everything downstream, so they come first. **You** classify the job (you have the repo open — you're the
|
|
903
|
+
best-informed classifier, and doing it here saves a backend LLM call); the server returns the lenses.
|
|
904
|
+
|
|
905
|
+
1. **Classify the request** into ONE development work-item slug, using the user's raw ask + your code
|
|
906
|
+
recon:
|
|
907
|
+
|
|
908
|
+
```text
|
|
909
|
+
understand-codebase-area · design-technical-approach · create-implementation-plan ·
|
|
910
|
+
build-frontend-feature · build-backend-service · integrate-api · create-docs-site ·
|
|
911
|
+
refactor-code · debug-production-issue · improve-performance · add-tests · prepare-release
|
|
912
|
+
```
|
|
913
|
+
|
|
914
|
+
(Use `build-feature` only when the ask is a generic build that none of the specific jobs fit.) Pick the
|
|
915
|
+
single best match — e.g. "add OAuth to the dashboard" → `build-backend-service`; "the checkout page is
|
|
916
|
+
slow" → `improve-performance`; "clean up the payments module" → `refactor-code`.
|
|
917
|
+
|
|
918
|
+
2. **Call `mcp__ritual__work_item`** with that `jtbd` (and `entry_use_case` if known). It returns
|
|
919
|
+
`{ workItemLabel, deliverableTemplate, recommended, options: [{ persona, label, whenToChoose }] }` —
|
|
920
|
+
deterministic, no LLM, already biased by the user's `ritual init` persona.
|
|
921
|
+
|
|
922
|
+
3. **Present the work item + lens options** as a `(label + description)` bottom-drawer choice picker
|
|
923
|
+
(same shape as discovery picks, per `references/cli-output-contract.md`), recommended lens first and
|
|
924
|
+
marked:
|
|
925
|
+
|
|
926
|
+
```text
|
|
927
|
+
This looks like: Build backend service / API → Service Build Brief
|
|
928
|
+
Who's leading it? (recommended: Backend Developer)
|
|
929
|
+
|
|
930
|
+
1. Backend Developer — Best when you care about API contracts, data, transactions, scaling. ← recommended
|
|
931
|
+
2. Developer — Best when you care about feasibility, implementation correctness, shippability.
|
|
932
|
+
3. Eng Lead — Best when you care about technical approach, risk, sequencing, review.
|
|
933
|
+
|
|
934
|
+
Reply `use` to lead as Backend Developer, a number to switch, or name a lens.
|
|
935
|
+
```
|
|
936
|
+
|
|
937
|
+
4. **Default = the recommended lens.** An ambiguous reply (`use`/`ok`/`go`) accepts it. If the user says
|
|
938
|
+
the *work item* is wrong ("no, this is a refactor"), re-classify and call `work_item` again. If they
|
|
939
|
+
switch the *lens*, that's a change → run the change pre-flight (`references/change-preflight.md`) to
|
|
940
|
+
confirm before adopting it.
|
|
941
|
+
|
|
942
|
+
5. **Remember the chosen `persona` slug** — you pass it through to `create_exploration` as `lead_persona`
|
|
943
|
+
at Step 6. (It also carries into the generation prompts once persona-aware generation ships; for now
|
|
944
|
+
it's persisted + surfaced.)
|
|
945
|
+
|
|
946
|
+
Keep this light — one drawer, recommended pre-selected; most users accept. Don't belabour it.
|
|
947
|
+
|
|
868
948
|
#### Step 4 — Generate sub-problems
|
|
869
949
|
|
|
870
950
|
##### 4.1 First draft
|
|
@@ -872,7 +952,7 @@ The user can always come back later with `/ritual context-pulse <exploration>` t
|
|
|
872
952
|
Call `mcp__ritual__generate_considerations` with:
|
|
873
953
|
- `workspace_id`
|
|
874
954
|
- `raw_input` (the user's problem + the Step 3 `codebase_context_packet` + any reference context, concatenated as described above)
|
|
875
|
-
- `template_id` (the
|
|
955
|
+
- `template_id` — **OPTIONAL.** Per Step 2 (server-side template resolution), the agent does NOT pick a template_id. Omit this field unless the user explicitly passed `--template-id` on the CLI; the server resolves the right template from `user.persona` → `workspace.defaultTemplateId` → system default and uses the same resolution chain `create_exploration` will use at Step 6. Passing it explicitly only matters when overriding the default.
|
|
876
956
|
- `sources` (the file path list from Step 3 step 7 — file-path strings only, e.g. `["apps/checkout/views.py", ...]`)
|
|
877
957
|
|
|
878
958
|
LLM call, ~5–10s. Returns 5–6 sub-problems — different framing axes the system should investigate. Track each one as `{ text, version: 1 }` in your working memory.
|
|
@@ -918,8 +998,11 @@ Only the title line gets the number. Put a blank line between candidates. Do not
|
|
|
918
998
|
|
|
919
999
|
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.
|
|
920
1000
|
|
|
1001
|
+
**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.
|
|
1002
|
+
|
|
921
1003
|
Call `mcp__ritual__refine_considerations` with:
|
|
922
|
-
- `workspace_id`, `raw_input`, `
|
|
1004
|
+
- `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.
|
|
1005
|
+
- `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.
|
|
923
1006
|
- `change_prompt`: the user's request verbatim
|
|
924
1007
|
- `selected`: items from prior versions the user kept (track `{ text, from_version }`, send just `text`)
|
|
925
1008
|
- `dismissed`: items the user explicitly rejected
|
|
@@ -939,7 +1022,7 @@ Call `mcp__ritual__generate_problem_statement` with:
|
|
|
939
1022
|
- `workspace_id`
|
|
940
1023
|
- `raw_input` (same augmented version from Step 4)
|
|
941
1024
|
- `considerations` (the picks from Step 4)
|
|
942
|
-
- `template_id`
|
|
1025
|
+
- `template_id` — OPTIONAL, same rule as Step 4. Omit unless the user explicitly overrode; server resolution stays consistent across `generate_considerations` → `generate_problem_statement` → `create_exploration`.
|
|
943
1026
|
- `sources` (the same file-path list passed to generate_considerations — keeps the KG anchor consistent)
|
|
944
1027
|
|
|
945
1028
|
Returns a candidate problem statement plus optional follow-up questions and quality scores. For engineering / agentic-coding templates, translate the returned statement into a developer-oriented **problem frame** before showing it. Do not default to "How might we…" unless the selected template is product/design oriented or the user asks for HMW phrasing.
|
|
@@ -985,8 +1068,11 @@ Rules:
|
|
|
985
1068
|
|
|
986
1069
|
If the user asks for a refinement:
|
|
987
1070
|
|
|
1071
|
+
**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.
|
|
1072
|
+
|
|
988
1073
|
Call `mcp__ritual__refine_problem_statement` with:
|
|
989
|
-
- `workspace_id`, `raw_input`, `considerations`, `
|
|
1074
|
+
- `workspace_id`, `raw_input`, `considerations`, `sources` — unchanged. (Same `sources` as the original generate call — keeps the KG anchor stable.)
|
|
1075
|
+
- `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.
|
|
990
1076
|
- `previous_problem_statement`: the FULL TEXT of the current best draft
|
|
991
1077
|
- `change_prompt`: the user's request verbatim
|
|
992
1078
|
- `version`: optional telemetry only; do not show version labels to the user
|
|
@@ -1004,7 +1090,7 @@ When the user locks the frame, store the final text as `problem_statement` for S
|
|
|
1004
1090
|
|
|
1005
1091
|
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)`.
|
|
1006
1092
|
|
|
1007
|
-
|
|
1093
|
+
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).
|
|
1008
1094
|
|
|
1009
1095
|
User-visible before the call, if needed:
|
|
1010
1096
|
|
|
@@ -1016,8 +1102,10 @@ Call `mcp__ritual__create_exploration` with:
|
|
|
1016
1102
|
- `workspace_id`
|
|
1017
1103
|
- `name`
|
|
1018
1104
|
- `problem_statement` (the scope from Step 5)
|
|
1019
|
-
- `template_id` — **
|
|
1105
|
+
- `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.
|
|
1020
1106
|
- `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.
|
|
1107
|
+
- `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`).
|
|
1108
|
+
- `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.
|
|
1021
1109
|
|
|
1022
1110
|
Store `exploration_id`. Move the progress header from Scope to Discovery:
|
|
1023
1111
|
|
|
@@ -1048,6 +1136,34 @@ This keeps the repo root clean (CLI Tenet #1 — files for reference, not clutte
|
|
|
1048
1136
|
|
|
1049
1137
|
If `git mv` fails (file wasn't tracked yet): use plain `mv` instead — same outcome, the user just commits the move whenever they next commit.
|
|
1050
1138
|
|
|
1139
|
+
##### 6.2 — Register staged knowledge sources (load-bearing)
|
|
1140
|
+
|
|
1141
|
+
If Step 3.5 staged any knowledge sources in working memory (PRDs / tickets / transcripts / etc.), register them NOW that `exploration_id` exists. The staging step deliberately deferred the MCP call because `add_knowledge_source` requires an exploration to attach to — this is where the deferral resolves.
|
|
1142
|
+
|
|
1143
|
+
For each staged record from § 3.5.3, call `mcp__ritual__add_knowledge_source` with:
|
|
1144
|
+
|
|
1145
|
+
- `exploration_id` (from Step 6)
|
|
1146
|
+
- `source_content_type` (from the staged record)
|
|
1147
|
+
- `content` (the full text the agent obtained)
|
|
1148
|
+
- `title` (from the staged record)
|
|
1149
|
+
- `source_url` / `source_path` (whichever applies, optional)
|
|
1150
|
+
- `origin_feature: 'DISCOVERY'`
|
|
1151
|
+
|
|
1152
|
+
Fire these in parallel — they're independent inserts + async extraction kickoffs. Cap concurrency at 5 if the user staged more than that (rare).
|
|
1153
|
+
|
|
1154
|
+
Surface a single compact summary after all registrations resolve:
|
|
1155
|
+
|
|
1156
|
+
> Attached {N} knowledge source{s} to the exploration: {comma-separated titles, truncated to 80 chars total}. Extraction running in the background.
|
|
1157
|
+
|
|
1158
|
+
**Failure handling:** if any `add_knowledge_source` call fails (network / 4xx / 5xx), retry once. On a second failure, surface a one-line note and continue — do NOT block the build flow on a knowledge-source registration failure:
|
|
1159
|
+
|
|
1160
|
+
> ⚠ Couldn't register `{title}` ({error in 1 sentence}). The exploration is still usable; you can re-add the ref later with `/ritual context-pulse <exploration> --add-ref {path}`.
|
|
1161
|
+
|
|
1162
|
+
**Skip path:** if Step 3.5 was skipped (user said "skip" / "none" / "later"), there are no staged records and this step is a silent no-op. Do NOT prompt the user again — they already declined at Step 3.5.
|
|
1163
|
+
|
|
1164
|
+
**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.
|
|
1165
|
+
|
|
1166
|
+
<!-- lite:skip-start reason="unpicked-consideration preservation is not part of lite" -->
|
|
1051
1167
|
#### Step 6.5 — Preserve unpicked considerations without cluttering the workspace
|
|
1052
1168
|
|
|
1053
1169
|
Unpicked or dismissed considerations are useful signal, but automatically creating sibling explorations can clutter the workspace. Do **not** fork sibling explorations by default.
|
|
@@ -1074,6 +1190,7 @@ If sibling creation is confirmed, call:
|
|
|
1074
1190
|
|
|
1075
1191
|
Then summarize the created siblings in the dense-list format. Do not pause after creation; return to the primary build flow.
|
|
1076
1192
|
|
|
1193
|
+
<!-- lite:skip-end -->
|
|
1077
1194
|
#### Step 7 — Discovery questions
|
|
1078
1195
|
|
|
1079
1196
|
Longest phase because generation is async + the user picks per-Area. (Internally the API field is `matter_id`; user-facing copy always says Area.)
|
|
@@ -1082,16 +1199,22 @@ Longest phase because generation is async + the user picks per-Area. (Internally
|
|
|
1082
1199
|
|
|
1083
1200
|
1. Call `mcp__ritual__suggest_discovery_questions(exploration_id)` (Step 7.1) — no user input needed; just kick it off.
|
|
1084
1201
|
2. Poll `mcp__ritual__get_discovery_state(exploration_id)` until `ready: true` (Step 7.2).
|
|
1085
|
-
3. Render the
|
|
1086
|
-
4. `[USER PAUSE]` — the user picks Areas
|
|
1087
|
-
5.
|
|
1088
|
-
6.
|
|
1089
|
-
|
|
1202
|
+
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).
|
|
1203
|
+
4. `[USER PAUSE]` — the user picks questions across Areas (**floor: 6 to run; aim for 15–20; no cap**), or types `accept shortlist`.
|
|
1204
|
+
5. Commit all picked Areas in ONE `mcp__ritual__accept_discovery_questions_batch` call (Step 7.4) — never one parallel call per Area.
|
|
1205
|
+
6. Optionally capture anti-goals (Step 7.5), then proceed to Step 8 and render the *"Reply `run` to continue"* CTA.
|
|
1206
|
+
|
|
1207
|
+
**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.
|
|
1208
|
+
- **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?".
|
|
1209
|
+
- **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.)
|
|
1210
|
+
- **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.
|
|
1211
|
+
- **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.)
|
|
1090
1212
|
|
|
1091
1213
|
**Forbidden behaviors:**
|
|
1092
1214
|
|
|
1093
|
-
- Calling `start_agentic_run` before
|
|
1215
|
+
- 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.
|
|
1094
1216
|
- 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.
|
|
1217
|
+
- **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.
|
|
1095
1218
|
- Rendering "Next: run discovery through recommendations / Reply `run` to continue" anywhere in the chat before Step 7.4 has completed.
|
|
1096
1219
|
|
|
1097
1220
|
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.
|
|
@@ -1111,29 +1234,40 @@ Generating discovery questions for each area…
|
|
|
1111
1234
|
|
|
1112
1235
|
Loop:
|
|
1113
1236
|
- Call `mcp__ritual__get_discovery_state(exploration_id)`
|
|
1114
|
-
- If `ready: false`, wait
|
|
1237
|
+
- If `ready: false`, wait 10 seconds, poll again
|
|
1115
1238
|
- If `ready: true`, exit loop
|
|
1116
1239
|
|
|
1117
|
-
Don't poll faster than every
|
|
1240
|
+
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.
|
|
1118
1241
|
|
|
1119
|
-
##### 7.3 —
|
|
1242
|
+
##### 7.3 — Matter-walk picker (Area rail + selected Area's questions → walk with `next`/`prev` → Summary)
|
|
1120
1243
|
|
|
1121
1244
|
The state contains `matters[]`, each with `id`, `name`, and `questions[]`. Internally these are `matter`s; user-facing copy ALWAYS calls them **Areas**.
|
|
1122
1245
|
|
|
1123
|
-
|
|
1246
|
+
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.
|
|
1247
|
+
|
|
1248
|
+
The two failure modes this contract prevents:
|
|
1249
|
+
- **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.)
|
|
1250
|
+
- **A full dump** — every Area's questions in one message. Only the **current** Area's questions render per turn.
|
|
1251
|
+
|
|
1252
|
+
**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.
|
|
1124
1253
|
|
|
1125
1254
|
###### 7.3.0 — Compute per-Area recommendations + the global shortlist (internal, not user-facing)
|
|
1126
1255
|
|
|
1127
|
-
|
|
1256
|
+
Three things surface, **none auto-applied**:
|
|
1257
|
+
- **(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*.
|
|
1258
|
+
- **(b) The per-Area ★ recommended set** (3–4 questions) — computed for the Area you are currently showing.
|
|
1259
|
+
- **(c) The global shortlist** (6–10 across all Areas) — computed only when the user types `accept shortlist`.
|
|
1128
1260
|
|
|
1129
|
-
|
|
1261
|
+
The user always picks; nothing is auto-committed.
|
|
1262
|
+
|
|
1263
|
+
**Per-Area recommended set** (the ★ set, for the Area currently shown):
|
|
1130
1264
|
|
|
1131
1265
|
- 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.
|
|
1132
1266
|
- Area has **< 4 questions**: all are recommended.
|
|
1133
1267
|
- Area has **4–7 questions**: top 3 are recommended.
|
|
1134
1268
|
- Area has **8+ questions**: top 4 are recommended.
|
|
1135
1269
|
|
|
1136
|
-
**Global shortlist** (what `accept shortlist` accepts
|
|
1270
|
+
**Global shortlist** (what `accept shortlist` accepts — available from any Area or the Summary):
|
|
1137
1271
|
|
|
1138
1272
|
- Pick **6–10 questions TOTAL across all Areas**, biased toward questions most likely to change recommendations.
|
|
1139
1273
|
- 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).
|
|
@@ -1142,246 +1276,197 @@ Two computations happen before the index renders. Both stay internal — they sh
|
|
|
1142
1276
|
|
|
1143
1277
|
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.
|
|
1144
1278
|
|
|
1145
|
-
###### 7.3.1 —
|
|
1279
|
+
###### 7.3.1 — First render: Area rail + Area 1's questions (the walk begins)
|
|
1146
1280
|
|
|
1147
|
-
|
|
1281
|
+
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.
|
|
1148
1282
|
|
|
1149
1283
|
```text
|
|
1150
1284
|
Ritual build
|
|
1151
1285
|
✓ Context ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
|
|
1152
1286
|
|
|
1153
|
-
Question picking
|
|
1154
|
-
|
|
1155
|
-
Ritual generated questions across {N} areas for the {M} locked sub-problems:
|
|
1156
|
-
{first sub-problem name} + {second sub-problem name}.
|
|
1157
|
-
|
|
1158
|
-
Pick an Area to review. I'll show the 3–4 questions most likely to change
|
|
1159
|
-
the implementation plan.
|
|
1160
|
-
|
|
1161
|
-
Areas:
|
|
1287
|
+
Question picking · Area 1 of {N} · {Area name} picked so far: 0
|
|
1162
1288
|
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
3. {Area name 3} {N} recommended · {N} total
|
|
1166
|
-
...
|
|
1167
|
-
|
|
1168
|
-
Reply with an Area number, `accept shortlist`, or `skip discovery`.
|
|
1169
|
-
Inside an Area, use `show more` to see the rest.
|
|
1170
|
-
```
|
|
1171
|
-
|
|
1172
|
-
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).
|
|
1173
|
-
|
|
1174
|
-
**Rendering anti-pattern (load-bearing) — the Areas index renders ONLY area names + counts. Observed violations 2026-05-15:**
|
|
1175
|
-
|
|
1176
|
-
- ❌ Question previews under each area:
|
|
1177
|
-
```text
|
|
1178
|
-
1. Wishlist Visibility Contract (10 qs)
|
|
1179
|
-
|
|
1180
|
-
1. How PUBLIC/SHARED behave across owner controls...
|
|
1181
|
-
2. Shared Wishlist Surfaces (8 qs)
|
|
1182
|
-
|
|
1183
|
-
2. Which entry points light up first...
|
|
1184
|
-
```
|
|
1185
|
-
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.
|
|
1289
|
+
Areas ● {Area name 1} ○ {Area name 2} ○ {Area name 3} ○ {Area name 4} ○ {Area name 5}
|
|
1290
|
+
● current · ✓N after a name = picked in that Area · move with `next` / `prev`
|
|
1186
1291
|
|
|
1187
|
-
|
|
1292
|
+
Ritual generated questions across {N} areas for {M} locked sub-problems.
|
|
1293
|
+
I'll walk you through each — aim for 15–20 total (6 minimum to run, no cap).
|
|
1188
1294
|
|
|
1189
|
-
|
|
1295
|
+
Showing the {k} most likely to change the plan ({total} in this Area):
|
|
1190
1296
|
|
|
1191
|
-
|
|
1297
|
+
1. {recommended question 1, wrapped readably}
|
|
1298
|
+
2. {recommended question 2, wrapped readably}
|
|
1299
|
+
3. {recommended question 3, wrapped readably}
|
|
1192
1300
|
|
|
1301
|
+
pick numbers (e.g. `1,3`) · `suggested` (these ★) · `add <your question>` · `show more` ({total−k} more)
|
|
1302
|
+
walk `next` · `prev` · `skip` · `done` (≥6) · `accept shortlist`
|
|
1193
1303
|
```
|
|
1194
|
-
Areas:
|
|
1195
1304
|
|
|
1196
|
-
|
|
1197
|
-
2. {Area name} {N} recommended · {N} total
|
|
1198
|
-
...
|
|
1199
|
-
```
|
|
1200
|
-
|
|
1201
|
-
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."
|
|
1202
|
-
|
|
1203
|
-
**Why `accept shortlist`, not `accept recommended`:**
|
|
1305
|
+
**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.
|
|
1204
1306
|
|
|
1205
|
-
|
|
1206
|
-
- This creates a clean vocabulary split: **discovery = `accept shortlist`** (questions), **recommendations = `accept recommended`** (themes).
|
|
1307
|
+
**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.
|
|
1207
1308
|
|
|
1208
|
-
|
|
1309
|
+
###### 7.3.2 — Within an Area (pick, then move)
|
|
1209
1310
|
|
|
1210
|
-
|
|
1311
|
+
**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.
|
|
1211
1312
|
|
|
1212
|
-
|
|
1313
|
+
- **`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`.
|
|
1314
|
+
- **`suggested`**: pick this Area's recommended (★) set in one go.
|
|
1315
|
+
- **`show more`**: reveal the rest, grouped Recommended / More (lazy per-Area expansion — never a global dump):
|
|
1213
1316
|
|
|
1214
1317
|
```text
|
|
1215
|
-
Question picking · {Area name}
|
|
1216
|
-
|
|
1217
|
-
Showing {N} recommended questions out of {total}.
|
|
1218
|
-
|
|
1219
|
-
1. {question 1, wrapped readably}
|
|
1220
|
-
|
|
1221
|
-
2. {question 2, wrapped readably}
|
|
1222
|
-
|
|
1223
|
-
3. {question 3, wrapped readably}
|
|
1224
|
-
|
|
1225
|
-
Reply with numbers like `1,2` to pick, `show more` to see all {total},
|
|
1226
|
-
or `skip` to leave this Area without picks.
|
|
1227
|
-
```
|
|
1228
|
-
|
|
1229
|
-
`show more` reveals the rest of the questions, formatted in two groups (Recommended / More):
|
|
1230
|
-
|
|
1231
|
-
```text
|
|
1232
|
-
Question picking · {Area name}
|
|
1318
|
+
Question picking · {Area name} picked so far: {T}
|
|
1233
1319
|
|
|
1234
1320
|
Recommended:
|
|
1235
|
-
|
|
1236
|
-
1. {recommended question 1}
|
|
1321
|
+
1. {recommended question 1} ✓
|
|
1237
1322
|
2. {recommended question 2}
|
|
1238
1323
|
3. {recommended question 3}
|
|
1239
1324
|
|
|
1240
1325
|
More questions:
|
|
1241
|
-
|
|
1242
1326
|
4. {non-recommended question 1}
|
|
1243
1327
|
5. {non-recommended question 2}
|
|
1244
|
-
6. {non-recommended question 3}
|
|
1245
|
-
7. {non-recommended question 4}
|
|
1246
1328
|
...
|
|
1247
1329
|
|
|
1248
|
-
Reply
|
|
1330
|
+
Reply numbers (e.g. `1,4`), `next`, `prev`, or `skip`.
|
|
1249
1331
|
```
|
|
1250
1332
|
|
|
1251
|
-
|
|
1333
|
+
- **`next` / `prev`**: move to the next / previous Area (picks preserved). At the last Area, `next` goes to the Summary (§ 7.3.3).
|
|
1334
|
+
- **`skip`**: leave this Area with no picks, advance to `next`.
|
|
1335
|
+
- **`done`**: jump straight to the Summary (allowed from any Area).
|
|
1336
|
+
- **`pause`**: stop here — state is saved, nothing committed.
|
|
1337
|
+
- **`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.
|
|
1338
|
+
- **`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).
|
|
1252
1339
|
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
```text
|
|
1256
|
-
Question picking
|
|
1340
|
+
###### 7.3.3 — Summary (after the last Area, or on `done`) — the review-before-commit gate
|
|
1257
1341
|
|
|
1258
|
-
|
|
1342
|
+
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).
|
|
1259
1343
|
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1344
|
+
```text
|
|
1345
|
+
Question picking · Summary {T} picked
|
|
1346
|
+
|
|
1347
|
+
✓ 1. {Area name 1} {n} picked
|
|
1348
|
+
– {picked question}
|
|
1349
|
+
– {picked question}
|
|
1350
|
+
— 2. {Area name 2} none picked
|
|
1351
|
+
✓ 3. {Area name 3} {n} picked
|
|
1352
|
+
– {picked question}
|
|
1264
1353
|
...
|
|
1265
1354
|
|
|
1266
|
-
|
|
1267
|
-
|
|
1355
|
+
{if T < 15} A good set is usually 15–20 — you've picked {T}. Reply an Area
|
|
1356
|
+
number to add more, `more` to suggest new Areas, or `commit`.
|
|
1357
|
+
{if T ≥ 15} Reply `commit` to run discovery on these {T} questions, an Area
|
|
1358
|
+
number to adjust, `more` for new Areas, or `pause` to stop.
|
|
1268
1359
|
```
|
|
1269
1360
|
|
|
1270
|
-
|
|
1361
|
+
**The minimum model — floor 6 HARD, good 15–20 SOFT, no cap:**
|
|
1271
1362
|
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1363
|
+
- **`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`.
|
|
1364
|
+
- **`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.
|
|
1365
|
+
- **`commit` with T ≥ 15** → proceed to § 7.4.
|
|
1366
|
+
- **An Area number** at the Summary → re-open that Area's questions (picks preserved), then return here.
|
|
1367
|
+
|
|
1368
|
+
**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).
|
|
1276
1369
|
|
|
1277
|
-
|
|
1370
|
+
- **`more`** at the Summary → the user wants broader coverage. **Suggest 2–3 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.**
|
|
1278
1371
|
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
-
|
|
1372
|
+
###### 7.3.4 — Power paths (available from any Area or the Summary)
|
|
1373
|
+
|
|
1374
|
+
- **`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.
|
|
1375
|
+
- **`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.
|
|
1376
|
+
- **`done`**: jump to the Summary from any Area to review + `commit`.
|
|
1377
|
+
- **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.)
|
|
1282
1378
|
|
|
1283
1379
|
###### 7.3.5 — What NOT to say
|
|
1284
1380
|
|
|
1285
1381
|
- 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.
|
|
1286
1382
|
- DO NOT use `Press Enter` anywhere in this picker (see § Surface-aware continuation prompts).
|
|
1287
|
-
- DO NOT say `lock` for the picking confirmation; use `done`
|
|
1288
|
-
- DO NOT
|
|
1383
|
+
- DO NOT say `lock` for the picking confirmation; use `done` (to the Summary) then `commit`.
|
|
1384
|
+
- 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.
|
|
1289
1385
|
|
|
1290
1386
|
###### Legacy alias notes
|
|
1291
1387
|
|
|
1292
|
-
- `suggest` (legacy per-Area shortcut) is now
|
|
1293
|
-
- `accept recommended` (legacy global shortcut): if a user types this, treat it as `accept shortlist
|
|
1388
|
+
- `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.
|
|
1389
|
+
- `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`.)
|
|
1294
1390
|
- `all` (legacy fourth option) remains removed (see § Removed below).
|
|
1295
1391
|
|
|
1296
1392
|
###### Removed: `all` (the old fourth option)
|
|
1297
1393
|
|
|
1298
1394
|
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.
|
|
1299
1395
|
|
|
1300
|
-
##### 7.4 — Commit picks (
|
|
1396
|
+
##### 7.4 — Commit picks (ONE batch call across all Areas)
|
|
1301
1397
|
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1398
|
+
**load-bearing — forbidden behavior:** do NOT fan out one
|
|
1399
|
+
`accept_discovery_questions` call per Area in parallel. Each per-Area call
|
|
1400
|
+
does several DB round-trips; firing them concurrently exhausts the server's
|
|
1401
|
+
connection pool and returns 503s on the later Areas (observed in prod). The
|
|
1402
|
+
batch endpoint exists precisely to avoid this — use it.
|
|
1306
1403
|
|
|
1307
|
-
|
|
1404
|
+
Call `mcp__ritual__accept_discovery_questions_batch` **once** with every
|
|
1405
|
+
Area's picks in a single atomic request:
|
|
1406
|
+
- `state_id` (from the discovery state)
|
|
1407
|
+
- `picks[]` — one entry per Area the user picked in, each `{ matter_id, question_ids[] }`
|
|
1308
1408
|
|
|
1309
1409
|
```ts
|
|
1310
|
-
//
|
|
1311
|
-
await
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
);
|
|
1410
|
+
// ONE call. All Areas, one atomic transaction, one successor state.
|
|
1411
|
+
await accept_discovery_questions_batch(state_id, [
|
|
1412
|
+
{ matter_id: areaA.matter_id, question_ids: areaA.question_ids },
|
|
1413
|
+
{ matter_id: areaB.matter_id, question_ids: areaB.question_ids },
|
|
1414
|
+
// …one entry per Area with at least one pick
|
|
1415
|
+
]);
|
|
1316
1416
|
```
|
|
1317
1417
|
|
|
1418
|
+
Use the single-Area `accept_discovery_questions` ONLY when the user picked in
|
|
1419
|
+
exactly one Area. If for some reason you must use it across several Areas
|
|
1420
|
+
(e.g. the batch tool is unavailable), call it **sequentially** (`await` each
|
|
1421
|
+
in turn) — never in parallel.
|
|
1422
|
+
|
|
1318
1423
|
User-facing: emit ONE status line for the whole commit, not one per Area:
|
|
1319
1424
|
|
|
1320
1425
|
```text
|
|
1321
1426
|
Saving picks across {N} Areas…
|
|
1322
1427
|
```
|
|
1323
1428
|
|
|
1324
|
-
|
|
1429
|
+
The batch call is all-or-nothing — validation fails the whole request if any
|
|
1430
|
+
pick is malformed, so there's no partial-success state to reconcile. Areas the
|
|
1431
|
+
user chose not to pick from are simply left unpicked.
|
|
1325
1432
|
|
|
1326
|
-
|
|
1433
|
+
**If there are NO held custom questions or pending new Areas, proceed to anti-goals.**
|
|
1327
1434
|
|
|
1328
|
-
|
|
1435
|
+
###### 7.4.1 — Persist held custom questions + new Areas (only if any were held)
|
|
1329
1436
|
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1437
|
+
Custom questions (`add`, § 7.3.2) and pending new Areas (`more`, § 7.3.3) were held
|
|
1438
|
+
LOCALLY during the walk because `add_discovery_question` needs a **workspace** matter id,
|
|
1439
|
+
which only exists after the batch above materialized the picked Areas. Persist them now,
|
|
1440
|
+
AFTER the batch call:
|
|
1334
1441
|
|
|
1335
|
-
|
|
1442
|
+
1. **Resolve workspace matter ids.** Call `mcp__ritual__get_exploration(exploration_id)` and
|
|
1443
|
+
map each Area **name** → its workspace `matters[i].id`. (The batch only materialized Areas
|
|
1444
|
+
the user picked AI questions in.)
|
|
1445
|
+
2. **For each Area that has held custom questions:**
|
|
1446
|
+
- if a workspace matter for that name exists → use its id;
|
|
1447
|
+
- if not (a custom-only Area, or a pending new Area) → `mcp__ritual__create_discovery_matter(exploration_id, name)` first, use the returned id.
|
|
1448
|
+
- 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).
|
|
1449
|
+
3. **For each pending new Area** (from `more`): `create_discovery_matter(...)` then `add_discovery_question(...)` per its questions, sequentially.
|
|
1336
1450
|
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
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.
|
|
1340
|
-
|
|
1341
|
-
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."
|
|
1342
|
-
|
|
1343
|
-
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:
|
|
1451
|
+
One status line for the whole persist step (not one per question):
|
|
1344
1452
|
|
|
1345
1453
|
```text
|
|
1346
|
-
|
|
1347
|
-
✓ Context ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
|
|
1348
|
-
|
|
1349
|
-
Scope check
|
|
1350
|
-
|
|
1351
|
-
{One-line summary of which pattern fired — e.g. "You picked 4 of 32 questions, mostly in retention."}
|
|
1352
|
-
|
|
1353
|
-
How should I treat the unpicked areas?
|
|
1354
|
-
|
|
1355
|
-
1. Out of scope — tighten the current scope around what you picked.
|
|
1356
|
-
2. Later phase — keep the broad scope, but mark unpicked areas as phase-later candidates.
|
|
1357
|
-
3. Open questions — keep the broad scope and treat unpicked areas as context debt.
|
|
1358
|
-
4. Pick more — return to question picking before continuing.
|
|
1359
|
-
|
|
1360
|
-
Reply with `1`, `2`, `3`, or `4`. Reply `pause` to stop here.
|
|
1361
|
-
```
|
|
1362
|
-
|
|
1363
|
-
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.
|
|
1364
|
-
|
|
1365
|
-
For Branch 2, append an exact block to `recon_context` before build brief generation:
|
|
1366
|
-
|
|
1367
|
-
```markdown
|
|
1368
|
-
## Explicit phase-later candidates
|
|
1369
|
-
|
|
1370
|
-
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."
|
|
1371
|
-
|
|
1372
|
-
- {matter/question}
|
|
1373
|
-
Reason: {user choice or inferred dependency}
|
|
1374
|
-
Related RB/source: {optional}
|
|
1454
|
+
Adding your {M} question(s) across {K} Area(s)…
|
|
1375
1455
|
```
|
|
1376
1456
|
|
|
1457
|
+
Only after all holds are persisted, proceed to anti-goals. The floor (≥6) counts
|
|
1458
|
+
custom + AI questions together — never `start_agentic_run` before the held questions are
|
|
1459
|
+
written.
|
|
1377
1460
|
|
|
1378
1461
|
##### 7.5 — Optional: capture out-of-scope items
|
|
1379
1462
|
|
|
1380
1463
|
If the user mentioned things they DON'T want investigated ("don't touch enterprise SSO", "skip pricing"), capture them as anti-goals.
|
|
1381
1464
|
|
|
1465
|
+
**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.
|
|
1466
|
+
|
|
1382
1467
|
Call `mcp__ritual__set_anti_goals(exploration_id, [{ text, reason? }, ...])`.
|
|
1383
1468
|
|
|
1384
|
-
Skip silently if no anti-goals were mentioned.
|
|
1469
|
+
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.)
|
|
1385
1470
|
|
|
1386
1471
|
**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.
|
|
1387
1472
|
|
|
@@ -1481,7 +1566,7 @@ Pick whichever fits the user's flow — they're equivalent in content. Do not in
|
|
|
1481
1566
|
|
|
1482
1567
|
##### 8.1 — Polling loop
|
|
1483
1568
|
|
|
1484
|
-
Poll `mcp__ritual__get_agentic_run(run_id)` using `references/async-polling.md`: **`Bash sleep
|
|
1569
|
+
Poll `mcp__ritual__get_agentic_run(run_id)` using `references/async-polling.md`: **`Bash sleep 20` (constant 20 — matches 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.
|
|
1485
1570
|
|
|
1486
1571
|
**On the FIRST poll only** (not every poll), prepend one line that locks the "background execution is default" mental model:
|
|
1487
1572
|
|
|
@@ -1582,394 +1667,353 @@ For each question's loop:
|
|
|
1582
1667
|
|
|
1583
1668
|
**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.
|
|
1584
1669
|
|
|
1585
|
-
|
|
1670
|
+
<!-- lite:keep-start -->
|
|
1671
|
+
|
|
1672
|
+
#### Step 9 — Review recommendations (category walk)
|
|
1586
1673
|
|
|
1587
|
-
|
|
1674
|
+
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**.
|
|
1588
1675
|
|
|
1589
|
-
|
|
1676
|
+
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.
|
|
1590
1677
|
|
|
1591
|
-
|
|
1678
|
+
**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:
|
|
1592
1679
|
|
|
1593
|
-
- top-level: `id`, `title`, `content` (summary), `status`, `priority`, `points`, `confidence`
|
|
1680
|
+
- top-level: `id`, `title`, `content` (the description / summary), `status`, `priority`, `points`, `confidence`
|
|
1594
1681
|
- `metadata.category.name` — **the load-bearing grouping key** (one rec → one category)
|
|
1595
|
-
- `metadata.
|
|
1596
|
-
- `metadata.
|
|
1597
|
-
- `metadata.labels[]` — secondary tags
|
|
1682
|
+
- `metadata.explainability` — `rationale` (chained `→` arrow string), `faq_references[]`, `problem_alignment`, `inferred_elements`
|
|
1683
|
+
- `metadata.acceptance_criteria[]` — concrete pass conditions (optional to surface; see § 9.1)
|
|
1598
1684
|
|
|
1599
|
-
|
|
1685
|
+
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.
|
|
1600
1686
|
|
|
1601
|
-
|
|
1687
|
+
**Vocabulary — load-bearing:**
|
|
1602
1688
|
|
|
1603
|
-
|
|
1689
|
+
- 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."*
|
|
1690
|
+
- 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).
|
|
1604
1691
|
|
|
1605
|
-
**
|
|
1692
|
+
**Action set — load-bearing (exactly three, no freelancing):**
|
|
1606
1693
|
|
|
1607
|
-
|
|
1694
|
+
- `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)
|
|
1695
|
+
- `next` — move to the next category. (§ 9.3)
|
|
1696
|
+
- `proceed` — mark the set reviewed and continue to the build brief, from any category. (§ 9.3)
|
|
1608
1697
|
|
|
1609
|
-
- `accept
|
|
1610
|
-
- `request admin review` — collaborator path, notifies workspace admin
|
|
1611
|
-
- `drop R{N}` — remove one rec from the set before accepting
|
|
1612
|
-
- `drill R{N}` — show one rec's full detail card
|
|
1613
|
-
- `comment R{N}` — leave feedback on a specific rec
|
|
1614
|
-
- `pause` — stop here; user can resume via `/ritual resume`
|
|
1698
|
+
**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.
|
|
1615
1699
|
|
|
1616
|
-
|
|
1700
|
+
##### 9.1 — The walk: one category per turn
|
|
1617
1701
|
|
|
1618
|
-
**
|
|
1702
|
+
**[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.
|
|
1619
1703
|
|
|
1620
|
-
|
|
1621
|
-
- ❌ `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.
|
|
1622
|
-
- ❌ `reject one pass` / `accept the survivors` — assumes a duplicate-pass shape that should not exist post-PR #345.
|
|
1623
|
-
- ❌ Any invented compound action (`accept and dedupe`, `merge similar`, etc.) — drives the user into a workflow the system doesn't support.
|
|
1704
|
+
First category (rail shown):
|
|
1624
1705
|
|
|
1625
|
-
|
|
1706
|
+
```text
|
|
1707
|
+
Ritual build
|
|
1708
|
+
✓ Context ✓ Scope ✓ Discovery ● Recommendations ○ Build brief ○ Implementation (Your agent)
|
|
1626
1709
|
|
|
1627
|
-
|
|
1710
|
+
Scope:
|
|
1711
|
+
{one-line compressed scope — ~80-120 chars; truncate at a clause boundary, no ellipsis}
|
|
1628
1712
|
|
|
1629
|
-
|
|
1713
|
+
{N} recommendations across {K} categories. They're accepted by default —
|
|
1714
|
+
review and refine any, or proceed anytime.
|
|
1630
1715
|
|
|
1631
|
-
|
|
1716
|
+
Category 1/{K} — {category name}
|
|
1632
1717
|
|
|
1633
|
-
|
|
1634
|
-
1
|
|
1635
|
-
|
|
1636
|
-
2. Response shape:
|
|
1637
|
-
{
|
|
1638
|
-
terminalPreviewText: "...", // present for surface=terminal (default)
|
|
1639
|
-
uiPreview: { // always present
|
|
1640
|
-
stage: "recommendations",
|
|
1641
|
-
stageIndex: 4, stageCount: 6,
|
|
1642
|
-
scopeLine, stats, categoryGroups,
|
|
1643
|
-
idMap, actions
|
|
1644
|
-
}
|
|
1645
|
-
}
|
|
1646
|
-
|
|
1647
|
-
3. Print response.terminalPreviewText VERBATIM. Do not re-render,
|
|
1648
|
-
re-wrap, re-number, or add a leading "Here are your recommendations..."
|
|
1649
|
-
line. The server already laid out the build rail, scope, grouped recs,
|
|
1650
|
-
and role-aware action hint at 78-col wrap.
|
|
1651
|
-
|
|
1652
|
-
4. Remember response.uiPreview.idMap so you can resolve user input — when
|
|
1653
|
-
they reply `accept R3` or `detail R7`, look up `R{N}` → uuid in
|
|
1654
|
-
idMap and use that uuid in the follow-up MCP call (accept_recommendations,
|
|
1655
|
-
get_recommendations).
|
|
1656
|
-
|
|
1657
|
-
5. response.uiPreview.actions is for mobile/web button rendering — terminal
|
|
1658
|
-
flow ignores it (action hint copy is already inside terminalPreviewText).
|
|
1659
|
-
Each action carries `style: "primary" | "secondary"` so a non-terminal
|
|
1660
|
-
UI knows which is the call-to-action.
|
|
1661
|
-
```
|
|
1718
|
+
R1 {title}
|
|
1719
|
+
{content — the description, wrapped at terminal width, 1-3 lines}
|
|
1720
|
+
Why this: {one-line Problem→Discovery→Tradeoff distillation, plain prose}
|
|
1662
1721
|
|
|
1663
|
-
|
|
1722
|
+
R2 {title}
|
|
1723
|
+
{description}
|
|
1724
|
+
Why this: {...}
|
|
1664
1725
|
|
|
1665
|
-
|
|
1726
|
+
Pulse: Reasoning Readiness ~88% · Context Debt 12% (implementation-ready)
|
|
1666
1727
|
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
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).
|
|
1728
|
+
Reply edit R{N} <your change> · next (Category 2/{K}) · proceed (build brief)
|
|
1729
|
+
```
|
|
1670
1730
|
|
|
1671
|
-
|
|
1731
|
+
Subsequent categories (in-phase chip, no full rail):
|
|
1672
1732
|
|
|
1673
|
-
|
|
1733
|
+
```text
|
|
1734
|
+
Recommendations · Category 2/{K} — {category name}
|
|
1674
1735
|
|
|
1675
|
-
|
|
1736
|
+
R3 {title}
|
|
1737
|
+
{description}
|
|
1738
|
+
Why this: {...}
|
|
1676
1739
|
|
|
1677
|
-
|
|
1678
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
1679
|
-
STEP 9.1 RENDERING CONTRACT (FALLBACK) — non-negotiable
|
|
1680
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
1681
|
-
|
|
1682
|
-
Use this contract ONLY if get_recommendations_preview is unavailable
|
|
1683
|
-
(older MCP server) or returns an error. Otherwise, print the preview
|
|
1684
|
-
verbatim per the Primary path above.
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
Landing view is for SELECTION, not reading. Full prose belongs in 9.3.
|
|
1688
|
-
|
|
1689
|
-
✓ DO:
|
|
1690
|
-
- Number categories `1.`, `2.`, `3.` … `K.` in page order
|
|
1691
|
-
- Assign recommendations stable `R1`, `R2`, … `RN` IDs GLOBALLY across
|
|
1692
|
-
all categories (NOT restart per-category — so `detail R7` is
|
|
1693
|
-
unambiguous without naming the category)
|
|
1694
|
-
- Show recommendation TITLES ONLY at the landing
|
|
1695
|
-
- Indent recs 3 spaces under their category
|
|
1696
|
-
- One blank line between categories
|
|
1697
|
-
- Include compact scope line above the list
|
|
1698
|
-
- End with the action block (`accept recommended` etc.)
|
|
1699
|
-
|
|
1700
|
-
✗ DO NOT:
|
|
1701
|
-
- Do NOT render recs as a flat `1..N` list with no category structure
|
|
1702
|
-
- Do NOT use raw numeric rec IDs like `1.`, `2.`, `3.` — use `R1`, `R2`, `R3`
|
|
1703
|
-
- Do NOT show recommendation `content` / summary text at the landing
|
|
1704
|
-
- Do NOT show acceptance criteria, rationale, tactics, or references at
|
|
1705
|
-
the landing — those are 9.3 detail-card content
|
|
1706
|
-
- Do NOT omit category numbering (the prefix is what separates this
|
|
1707
|
-
from a wall-of-text grouped list)
|
|
1708
|
-
- Do NOT invent a "raw / deduped" framing line — the API does not return
|
|
1709
|
-
pre-dedup counts. Use `{N} recommendations across {K} categories.`
|
|
1710
|
-
|
|
1711
|
-
OBSERVED FAILURE — never render this:
|
|
1712
|
-
|
|
1713
|
-
Recommendations (13)
|
|
1714
|
-
|
|
1715
|
-
1. Backfill legacy data to fail-closed PRIVATE visibility
|
|
1716
|
-
Add a constrained `visibility` field with DB default PRIVATE...
|
|
1717
|
-
|
|
1718
|
-
2. Codify actor-state rights around owner-only mutation
|
|
1719
|
-
Define a single permission matrix across PRIVATE/SHARED/PUBLIC...
|
|
1720
|
-
|
|
1721
|
-
3. Centralize object permissions across storefront and dashboard
|
|
1722
|
-
Reusable `can_view_wishlist` / `can_edit_wishlist` methods...
|
|
1723
|
-
|
|
1724
|
-
Why wrong:
|
|
1725
|
-
- Looks grouped only implicitly; categories not visible as headers
|
|
1726
|
-
- Uses `1..N` numeric IDs (should be `R1..RN`)
|
|
1727
|
-
- Dumps `content` summaries — defeats the purpose of a landing view
|
|
1728
|
-
- `detail R7` no longer maps to a stable ID
|
|
1729
|
-
|
|
1730
|
-
PREFLIGHT — before printing 9.1 output, self-check:
|
|
1731
|
-
□ Did I group by `metadata.category.name`?
|
|
1732
|
-
□ Did I prefix each category with `1.`, `2.`, … `K.`?
|
|
1733
|
-
□ Did I assign global `R1..RN` IDs across categories?
|
|
1734
|
-
□ Did I show titles only (no summaries / no rationale)?
|
|
1735
|
-
□ Is there a compact scope line above the list?
|
|
1736
|
-
□ Does my action block use `R{N}` references that match the IDs above?
|
|
1737
|
-
|
|
1738
|
-
If any answer is no, FIX BEFORE PRINTING.
|
|
1739
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
1740
|
-
```
|
|
1740
|
+
...
|
|
1741
1741
|
|
|
1742
|
-
|
|
1742
|
+
Reply edit R{N} <your change> · next (Category 3/{K}) · proceed (build brief)
|
|
1743
|
+
```
|
|
1743
1744
|
|
|
1744
|
-
|
|
1745
|
-
Ritual build
|
|
1746
|
-
✓ Context ✓ Scope ✓ Discovery ● Recommendations ○ Build brief ○ Implementation (Your agent)
|
|
1745
|
+
Notes:
|
|
1747
1746
|
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1747
|
+
- **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.
|
|
1748
|
+
- **`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.
|
|
1749
|
+
- **One blank line between recs**; indent rec bodies under their `R{N}` so the eye lands on the title first.
|
|
1750
|
+
- **`proceed` is the primary CTA** and is offered on every category — the user never has to walk all categories to continue.
|
|
1751
|
+
- **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."
|
|
1751
1752
|
|
|
1752
|
-
|
|
1753
|
+
##### 9.2 — `edit R{N} <ask>`: preview, then apply
|
|
1753
1754
|
|
|
1754
|
-
|
|
1755
|
+
This mirrors Spark's "Revise → Preview Revision → Apply revision" exactly: the change is **previewed before anything persists**.
|
|
1755
1756
|
|
|
1756
|
-
1. {
|
|
1757
|
-
|
|
1758
|
-
|
|
1757
|
+
1. Resolve `R{N}` → rec UUID from the walk's ID map.
|
|
1758
|
+
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>`.
|
|
1759
|
+
3. **[USER PAUSE]** Render the preview and wait:
|
|
1759
1760
|
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
R4 {title}
|
|
1763
|
-
R5 {title}
|
|
1761
|
+
```text
|
|
1762
|
+
Recommendations · R{N} — proposed revision
|
|
1764
1763
|
|
|
1765
|
-
|
|
1766
|
-
R6 {title}
|
|
1764
|
+
What changed: {proposal.summary}
|
|
1767
1765
|
|
|
1768
|
-
|
|
1766
|
+
Title
|
|
1767
|
+
- {before}
|
|
1768
|
+
+ {after}
|
|
1769
1769
|
|
|
1770
|
-
|
|
1770
|
+
Description
|
|
1771
|
+
- {before}
|
|
1772
|
+
+ {after}
|
|
1771
1773
|
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
+
Why this — step {i}
|
|
1775
|
+
- {before}
|
|
1776
|
+
+ {after}
|
|
1774
1777
|
|
|
1775
|
-
|
|
1776
|
-
- `detail R7` to inspect one recommendation
|
|
1777
|
-
- `drop R8` to remove one before accepting
|
|
1778
|
-
- `change R3: <edit>` to revise one
|
|
1779
|
-
- `hold` to stop here
|
|
1778
|
+
Reply apply (save this revision) · discard (keep the original)
|
|
1780
1779
|
```
|
|
1781
1780
|
|
|
1782
|
-
|
|
1781
|
+
- Render ONLY the `diff` fields that are present. Map `field: "title"` → `Title`, `"description"` → `Description`, `"chain.<idx>"` → `Why this — step {idx+1}`.
|
|
1782
|
+
- 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.
|
|
1783
1783
|
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
- **Pulse uses full labels** per `references/cli-output-contract.md` § Pulse tier labels.
|
|
1787
|
-
- **`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.
|
|
1788
|
-
- **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:
|
|
1789
|
-
- **`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."
|
|
1790
|
-
- **`show scope`** to expand the full problem statement (covered in 9.2).
|
|
1784
|
+
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`).
|
|
1785
|
+
On `discard`: return to the current category unchanged — nothing was persisted.
|
|
1791
1786
|
|
|
1792
|
-
|
|
1787
|
+
Editing is non-destructive and does not advance the flow — the user can `edit` several recs, across categories, before `proceed`.
|
|
1793
1788
|
|
|
1794
|
-
|
|
1789
|
+
##### 9.3 — `next` and `proceed`
|
|
1790
|
+
|
|
1791
|
+
- **`next`** → render the next category per § 9.1 (in-phase chip). After the last category, prompt `proceed`.
|
|
1792
|
+
- **`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:
|
|
1795
1793
|
|
|
1796
1794
|
```text
|
|
1797
|
-
|
|
1795
|
+
Ritual build
|
|
1796
|
+
✓ Context ✓ Scope ✓ Discovery ✓ Recommendations ● Build brief ○ Implementation (Your agent)
|
|
1797
|
+
|
|
1798
|
+
Reviewed {N} recommendations.
|
|
1798
1799
|
|
|
1799
|
-
{
|
|
1800
|
+
View: https://app.ritualapp.cloud/e/{exploration_id}
|
|
1800
1801
|
|
|
1801
|
-
|
|
1802
|
-
recommendation actions.
|
|
1802
|
+
Next: preparing the build brief…
|
|
1803
1803
|
```
|
|
1804
1804
|
|
|
1805
|
-
|
|
1805
|
+
**Pulse (recommendations reviewed):** emit a pulse — this is almost always a state-tier crossing into **Recommendation-ready**. Render full.
|
|
1806
|
+
|
|
1807
|
+
Continue to Step 9.5 (`Wait for requirements`).
|
|
1806
1808
|
|
|
1807
|
-
|
|
1809
|
+
<!-- lite:keep-end -->
|
|
1808
1810
|
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
+
#### Step 9.5 — Wait for requirements (auto-triggered by Step 9)
|
|
1812
|
+
|
|
1813
|
+
`accept_recommendations` fires requirement generation **fire-and-forget** the moment it succeeds. By the time you reach this step, generation is already in flight (or done, for fast LLM calls). The brief in Step 10 needs requirements ready, so wait here.
|
|
1814
|
+
|
|
1815
|
+
Steps:
|
|
1811
1816
|
|
|
1812
|
-
|
|
1817
|
+
1. **Tell the user once** that requirements are being generated:
|
|
1813
1818
|
|
|
1814
|
-
|
|
1815
|
-
{metadata.category.name}
|
|
1819
|
+
> Generating requirements for the build brief…
|
|
1816
1820
|
|
|
1817
|
-
|
|
1818
|
-
{content — direct, actionable summary; 2-4 sentences}
|
|
1821
|
+
2. **Poll `mcp__ritual__get_requirement_set_status(exploration_id)` every ~5s.** The response shape:
|
|
1819
1822
|
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1823
|
+
```
|
|
1824
|
+
{
|
|
1825
|
+
exists: boolean,
|
|
1826
|
+
status: 'GENERATING' | 'READY' | 'FAILED' | null,
|
|
1827
|
+
icp, startedAt, completedAt, errorMessage
|
|
1828
|
+
}
|
|
1829
|
+
```
|
|
1825
1830
|
|
|
1826
|
-
|
|
1827
|
-
-
|
|
1828
|
-
-
|
|
1829
|
-
-
|
|
1831
|
+
Polling rules in this harness:
|
|
1832
|
+
- **`Bash sleep 5` per poll. Always 5. Never escalate to 15/20/25.** The harness blocks chained sleeps, `sleep ≥ 30`, AND successive `sleep N` calls across turns at increasing N. One short sleep per turn dodges all three guards AND keeps the user-facing progress feel live.
|
|
1833
|
+
- **Update the user every ~3 polls** with a "still generating…" line so they know you haven't stalled.
|
|
1834
|
+
- If polling crosses ~5 minutes, switch to the `Monitor` + `until <check>; do sleep 2; done` pattern from `references/async-polling.md` § Long waits.
|
|
1830
1835
|
|
|
1831
|
-
|
|
1832
|
-
- {metadata.acceptance_criteria[0]}
|
|
1833
|
-
- {metadata.acceptance_criteria[1]}
|
|
1834
|
-
- {metadata.acceptance_criteria[N]}
|
|
1836
|
+
3. **Exit conditions:**
|
|
1835
1837
|
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1838
|
+
| Response | Action |
|
|
1839
|
+
|---|---|
|
|
1840
|
+
| `status === 'READY'` | Proceed to Step 10 |
|
|
1841
|
+
| `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). |
|
|
1842
|
+
| `status === 'GENERATING'` | Keep polling |
|
|
1843
|
+
| `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 |
|
|
1839
1844
|
|
|
1840
|
-
|
|
1845
|
+
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.)
|
|
1841
1846
|
|
|
1842
|
-
|
|
1843
|
-
If you only want a subset, `drop` the recs you don't want first, then `accept recommended`.
|
|
1844
|
-
```
|
|
1847
|
+
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).
|
|
1845
1848
|
|
|
1846
|
-
|
|
1849
|
+
#### Step 9.6 — Audit the recommendations + requirements against declared anti-goals (load-bearing — audit-repair loop)
|
|
1847
1850
|
|
|
1848
|
-
|
|
1849
|
-
- 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.
|
|
1850
|
-
- `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").
|
|
1851
|
-
- `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).
|
|
1852
|
-
- `back` returns to the landing summary, NOT to a new fetch — the agent should cache the recs from the landing call and re-render.
|
|
1851
|
+
Run a constraint-survival audit on the typed Recommendation + Requirement substrate BEFORE brief generation. The audit answers the question: *"Did the anti-goal directives the user declared actually constrain the recs+reqs, or are they decorative?"* — the R4 operator (constraint-perturbation) applied to the (anti-goals, recs+reqs, R4) triple per the audit-triple-framing rule.
|
|
1853
1852
|
|
|
1854
|
-
|
|
1853
|
+
**Why this is load-bearing**: an inert anti-goal — declared but not actually constraining anything in the recs+reqs — propagates downstream as an unconstrained brief. By Step 11 (implementation) it's too late; the agent codes against a substrate whose forbidden states were never enforced. The audit catches inert directives at the upstream typed substrate where the fix is cheap (rec content edit), not at the brief markdown where the fix is expensive (full regen).
|
|
1855
1854
|
|
|
1856
|
-
|
|
1855
|
+
**Skip condition**: if the exploration has zero anti-goals (`set_anti_goals` was never called OR all anti-goals are `confidence < 0.4`) OR no APPROVED recommendations exist OR the latest RequirementSet isn't READY, skip this step silently and continue to Step 10. The audit tool returns 404 in any of those cases; check the substrate state first if unsure.
|
|
1857
1856
|
|
|
1858
|
-
|
|
1859
|
-
|---|---|---|
|
|
1860
|
-
| `accept recommended` | Accept ALL recs currently on screen | `mcp__ritual__accept_recommendations({ exploration_id })` (omit `recommendation_ids` — admin only, see Branch B) |
|
|
1861
|
-
| `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. |
|
|
1862
|
-
| `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. |
|
|
1863
|
-
| `detail R{N}` | Render the detail card for that rec | None (in-memory) |
|
|
1864
|
-
| `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 |
|
|
1865
|
-
| `drop R{N}` | Mark that rec rejected | `update_recommendation` with status=rejected, OR add a "deliberately excluded" note for the brief generator |
|
|
1866
|
-
| `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 |
|
|
1867
|
-
| `show scope` | Expand the scope reference | None (in-memory) |
|
|
1868
|
-
| `hold` | Stop here without accepting | None (exits the flow; user can resume later) |
|
|
1857
|
+
**Build modes** (per `documents/architecture/audit-suite.md` § 7a) — the gate prompt below renders differently depending on which mode flag the user invoked:
|
|
1869
1858
|
|
|
1870
|
-
|
|
1859
|
+
| Mode | Prompt behavior | Default on enter |
|
|
1860
|
+
|---|---|---|
|
|
1861
|
+
| bare `/ritual build` | Compact opt-in: "Reply `audit` or `proceed`" | `proceed` |
|
|
1862
|
+
| `/ritual build --audited` | Elevated: "Recommended: run constraint-survival audit. Reply `audit`, `proceed`, or `always audit for this build`" | Awaits user input (no implicit default) |
|
|
1863
|
+
| `/ritual build --audit=strict` | Audit auto-runs; user sees results + repair menu, not the gate prompt | N/A (no gate prompt rendered) |
|
|
1871
1864
|
|
|
1872
|
-
|
|
1865
|
+
`auditMode` is read from working memory (set at Step 0 from the user's invocation flags). Mid-flow, `always audit for this build` upgrades the session to `--audit=strict` behavior for any remaining audit gates (Audit 2 at Step 10b.5, Audit 3 at Step 11.1 — both PR B/C).
|
|
1873
1866
|
|
|
1874
|
-
**
|
|
1875
|
-
- `add <topic>` requires a regenerate with a pinned topic — that's a forthcoming `regenerate_recommendation` improvement; until then it's a full regeneration cycle.
|
|
1876
|
-
- 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.
|
|
1867
|
+
**Strict mode time budget**: each audit chain runs up to 3 iterations of verifier calls (~5-15s per iteration × 3 = ~15-45s typical). Hard wall-clock cap of 90s per chain — on timeout, the gate degrades to `--audited` behavior (surface findings, let user decide rather than block the build).
|
|
1877
1868
|
|
|
1878
|
-
|
|
1869
|
+
### Step 9.6.1 — Render the gate prompt (mode-aware)
|
|
1879
1870
|
|
|
1880
|
-
|
|
1871
|
+
**For `bare` mode:**
|
|
1881
1872
|
|
|
1882
1873
|
```text
|
|
1883
|
-
|
|
1884
|
-
✓ Context ✓ Scope ✓ Discovery ✓ Recommendations ● Build brief ○ Implementation (Your agent)
|
|
1874
|
+
Recommendations + requirements are ready. Optional constraint-survival audit available.
|
|
1885
1875
|
|
|
1886
|
-
|
|
1876
|
+
Reply `audit` to run, or `proceed` to skip to brief generation.
|
|
1877
|
+
```
|
|
1887
1878
|
|
|
1888
|
-
|
|
1879
|
+
**For `--audited` mode:**
|
|
1889
1880
|
|
|
1890
|
-
|
|
1891
|
-
|
|
1881
|
+
```text
|
|
1882
|
+
Recommendations + requirements are ready.
|
|
1892
1883
|
|
|
1893
|
-
|
|
1884
|
+
Recommended: run constraint-survival audit before brief generation.
|
|
1885
|
+
This checks whether anti-goals survived into the recs + requirements.
|
|
1894
1886
|
|
|
1895
|
-
|
|
1887
|
+
Reply `audit`, `proceed`, or `always audit for this build`.
|
|
1888
|
+
```
|
|
1896
1889
|
|
|
1897
|
-
|
|
1890
|
+
**For `--audit=strict` mode:** SKIP the prompt; jump directly to Step 9.6.2 (run the audit).
|
|
1898
1891
|
|
|
1899
|
-
|
|
1892
|
+
### Step 9.6.2 — Run the audit (when chosen or in strict mode)
|
|
1900
1893
|
|
|
1901
|
-
|
|
1902
|
-
Ritual build
|
|
1903
|
-
✓ Context ✓ Scope ✓ Discovery ● Recommendations ○ Build brief ○ Implementation (Your agent)
|
|
1894
|
+
Render:
|
|
1904
1895
|
|
|
1905
|
-
|
|
1906
|
-
{
|
|
1896
|
+
```text
|
|
1897
|
+
Auditing recs + requirements against {N} declared anti-goal{s}…
|
|
1898
|
+
```
|
|
1907
1899
|
|
|
1908
|
-
|
|
1900
|
+
Call `mcp__ritual__audit_recommendations({ exploration_id })` with the default config (threshold mode, 80% acceptance threshold, max 3 iterations). The response shape:
|
|
1909
1901
|
|
|
1910
|
-
|
|
1911
|
-
|
|
1902
|
+
```json
|
|
1903
|
+
{
|
|
1904
|
+
"chain_id": "ac-...",
|
|
1905
|
+
"audit_status": "ok" | "needs_attention" | "blocked",
|
|
1906
|
+
"iteration": 1,
|
|
1907
|
+
"findings": [
|
|
1908
|
+
{
|
|
1909
|
+
"repair_id": "ri-...",
|
|
1910
|
+
"after_audit_id": "...",
|
|
1911
|
+
"severity": "blocker" | "high" | "medium" | "low",
|
|
1912
|
+
"directive_text": "Audit log must be append-only.",
|
|
1913
|
+
"status": "inert" | "omitted" | "weakened" | "contradicted",
|
|
1914
|
+
"gap_kind": "global_inert" | "local_gap" | "weak_coupling" | "contradiction",
|
|
1915
|
+
"affected_entities": [{"entity_type": "recommendation", "entity_id": "..."}],
|
|
1916
|
+
"message": "Anti-goal #2 is referenced but not by the entity it most-applies-to — ...",
|
|
1917
|
+
"auto_dispatchable": true | false
|
|
1918
|
+
}
|
|
1919
|
+
],
|
|
1920
|
+
"summary": {
|
|
1921
|
+
"total_constraints": 7,
|
|
1922
|
+
"survival_rate_percent": 57,
|
|
1923
|
+
"by_severity": { "blocker": 1, "high": 0, "medium": 2, "low": 0 },
|
|
1924
|
+
"by_gap_kind": { "global_inert": 1, "local_gap": 2, "weak_coupling": 0, "contradiction": 0 }
|
|
1925
|
+
},
|
|
1926
|
+
"decision_reason": "...",
|
|
1927
|
+
"attestation_digest": "sha256:...",
|
|
1928
|
+
"next_step_hint": "..."
|
|
1929
|
+
}
|
|
1930
|
+
```
|
|
1912
1931
|
|
|
1913
|
-
|
|
1914
|
-
R1 {title}
|
|
1915
|
-
R2 {title}
|
|
1932
|
+
### Step 9.6.3 — Render the findings + repair-action menu
|
|
1916
1933
|
|
|
1917
|
-
|
|
1934
|
+
Render based on `audit_status`:
|
|
1918
1935
|
|
|
1919
|
-
|
|
1920
|
-
Or reply `detail R7`, `change R3: <edit>`, `drop R8`, or `hold`.
|
|
1936
|
+
**`audit_status: "ok"`** — survival rate met threshold AND no blockers. Render one line and proceed silently to Step 10:
|
|
1921
1937
|
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
the admin can reconcile later. Reply `continue` to take that path.)
|
|
1938
|
+
```text
|
|
1939
|
+
✓ Audit passed: {survival_rate_percent}% of {total_constraints} anti-goals preserved. Chain accepted.
|
|
1925
1940
|
```
|
|
1926
1941
|
|
|
1927
|
-
|
|
1928
|
-
1. `request admin review` — the recommended path (notifies admin, no implementation yet)
|
|
1929
|
-
2. `continue` — implement-ahead-of-acceptance (logs as `implemented_ahead`; admin can reconcile later)
|
|
1930
|
-
3. `hold` — stop entirely
|
|
1942
|
+
**`audit_status: "needs_attention"` or `"blocked"`** — surface the findings inline so the user sees them before deciding:
|
|
1931
1943
|
|
|
1932
|
-
|
|
1944
|
+
```text
|
|
1945
|
+
⚠ Audit — {iteration} of {max_iterations} — {audit_status}
|
|
1946
|
+
|
|
1947
|
+
{survival_rate_percent}% of {total_constraints} anti-goals preserved.
|
|
1948
|
+
Findings ({findings.length} total):
|
|
1949
|
+
{for each finding, severity-prefixed (⛔ blocker / ⚠ high / · medium / · low):}
|
|
1950
|
+
{severity_glyph} {repair_id} — {directive_text}
|
|
1951
|
+
status: {status} · gap: {gap_kind} · affects: {affected_entities.length} entit{ies/y}
|
|
1952
|
+
{message[:120]}…
|
|
1953
|
+
|
|
1954
|
+
Reply:
|
|
1955
|
+
· `resolve all` — apply all auto-dispatchable repairs, re-audit
|
|
1956
|
+
(recommended — your config has blocker findings
|
|
1957
|
+
set to always_resolve)
|
|
1958
|
+
· `resolve {repair_id}` — apply a single repair (good for inspection)
|
|
1959
|
+
· `waive {repair_id}: <reason>`
|
|
1960
|
+
— record explicit acceptance of one finding;
|
|
1961
|
+
document the gap and continue
|
|
1962
|
+
· `accept` — accept current substrate, document all remaining
|
|
1963
|
+
findings as gaps (BLOCKED while any
|
|
1964
|
+
blocker-severity finding remains; the chain
|
|
1965
|
+
config enforces this)
|
|
1966
|
+
· `show chain` — render the full audit chain trail
|
|
1967
|
+
(calls get_audit_chain)
|
|
1968
|
+
· `pause` — stop here; resume via /ritual resume
|
|
1969
|
+
```
|
|
1933
1970
|
|
|
1934
|
-
|
|
1971
|
+
**On `resolve all`** — for each `auto_dispatchable: true` finding, call `mcp__ritual__apply_repair({ repair_id, chain_id, after_audit_id })`. Each call returns:
|
|
1935
1972
|
|
|
1936
|
-
|
|
1973
|
+
```json
|
|
1974
|
+
{
|
|
1975
|
+
"action_id": "ra-...",
|
|
1976
|
+
"action": "apply",
|
|
1977
|
+
"status": "applied",
|
|
1978
|
+
"next_iteration_id": "...",
|
|
1979
|
+
"hint": "Re-audit ran (SurvivalReport ...). Call get_audit_chain with chain_id=... to see the updated trail and whether the chain accepted."
|
|
1980
|
+
}
|
|
1981
|
+
```
|
|
1937
1982
|
|
|
1938
|
-
|
|
1983
|
+
Apply-repair is sequential per finding; the server runs the next audit iteration inline after each successful apply, so just call them in order. After the last `auto_dispatchable: true` finding, call `mcp__ritual__get_audit_chain({ chain_id })` to fetch the final state and re-render the loop UX with the new survival rate. If `chain_status === 'accepted'` after this round, proceed to Step 10; otherwise re-render the findings (the chain may have iterated and produced new findings the next iteration surfaces).
|
|
1939
1984
|
|
|
1940
|
-
|
|
1985
|
+
**On `resolve {repair_id}`** — single-finding apply. Same dispatch shape; render the next iteration's findings on completion.
|
|
1941
1986
|
|
|
1942
|
-
|
|
1987
|
+
**On `waive {repair_id}: <reason>`** — `apply_repair({ repair_id, chain_id, after_audit_id, action: 'waive', waive_reason: '<reason>' })`. No re-audit; render confirmation + return to the loop UX.
|
|
1943
1988
|
|
|
1944
|
-
|
|
1989
|
+
**On `accept`** — only allowed when no `blocker`-severity findings remain (the L1 tool returns `audit_status: "blocked"` while they do). Surface a single confirm: *"Accepting substrate with {findings.length} documented gap(s). Proceed?"* On yes, proceed to Step 10. The audit chain's final state is recorded; future `/ritual lineage` on this exploration surfaces the chain trail + the gaps the user explicitly accepted.
|
|
1945
1990
|
|
|
1946
|
-
|
|
1991
|
+
**On `show chain`** — render the full trail (iterations + repairs + status) from `get_audit_chain`. Keep it compact: one line per iteration + one line per repair. Then re-render the loop UX so the user can pick their next action.
|
|
1947
1992
|
|
|
1948
|
-
|
|
1949
|
-
{
|
|
1950
|
-
exists: boolean,
|
|
1951
|
-
status: 'GENERATING' | 'READY' | 'FAILED' | null,
|
|
1952
|
-
icp, startedAt, completedAt, errorMessage
|
|
1953
|
-
}
|
|
1954
|
-
```
|
|
1993
|
+
**On `pause`** — stop here. Chain stays `in_progress`; resume via `/ritual resume`.
|
|
1955
1994
|
|
|
1956
|
-
|
|
1957
|
-
- **`Bash sleep 5` per poll. Always 5. Never escalate to 15/20/25.** The harness blocks chained sleeps, `sleep ≥ 30`, AND successive `sleep N` calls across turns at increasing N. One short sleep per turn dodges all three guards AND keeps the user-facing progress feel live.
|
|
1958
|
-
- **Update the user every ~3 polls** with a "still generating…" line so they know you haven't stalled.
|
|
1959
|
-
- If polling crosses ~5 minutes, switch to the `Monitor` + `until <check>; do sleep 2; done` pattern from `references/async-polling.md` § Long waits.
|
|
1995
|
+
**On `halt_unresolvable`** (chain reached `max_iterations` with unresolved must-resolve findings) — the L1 tool returns `audit_status: "blocked"` and the chain is terminated. Surface:
|
|
1960
1996
|
|
|
1961
|
-
|
|
1997
|
+
```text
|
|
1998
|
+
⛔ Audit halted after {max_iterations} iterations — {n_blockers} blocker(s) unresolved.
|
|
1999
|
+
|
|
2000
|
+
The repair loop didn't converge. Options:
|
|
2001
|
+
· `extend max-iterations <N>` — re-run the audit with a higher cap (creates a new chain)
|
|
2002
|
+
· `force accept` — proceed to Step 10 with the substrate as-is; remaining
|
|
2003
|
+
blockers are recorded on the chain trail but no longer
|
|
2004
|
+
gate the build flow
|
|
2005
|
+
· `pause` — stop here for human review
|
|
2006
|
+
```
|
|
1962
2007
|
|
|
1963
|
-
|
|
1964
|
-
|---|---|
|
|
1965
|
-
| `status === 'READY'` | Proceed to Step 10 |
|
|
1966
|
-
| `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). |
|
|
1967
|
-
| `status === 'GENERATING'` | Keep polling |
|
|
1968
|
-
| `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 |
|
|
2008
|
+
**Special: contradiction-class findings** — when a finding has `gap_kind: "contradiction"`, it surfaces as `auto_dispatchable: false`. The repair (`replace_recommendation`) IS implemented and CAN be applied via `apply_repair {repair_id}`, but `resolve all` skips it because replacing a rec is a structural change worth explicit user consent. The SKILL should render contradiction findings with an explicit "needs review" prefix:
|
|
1969
2009
|
|
|
1970
|
-
|
|
2010
|
+
```text
|
|
2011
|
+
⛔ {repair_id} — CONTRADICTION — {directive_text}
|
|
2012
|
+
A rec actively violates this directive. `replace_recommendation` will regenerate the rec
|
|
2013
|
+
under the constraint. Confirm by replying `resolve {repair_id}` explicitly.
|
|
2014
|
+
```
|
|
1971
2015
|
|
|
1972
|
-
|
|
2016
|
+
**Verifier-generator separation**: the audit's verifier model is automatically resolved by the server to a different family than whichever model generated the recs — agents don't need to manage this; it's enforced at the API. The audit's attestation digest records both model ids for post-hoc auditability.
|
|
1973
2017
|
|
|
1974
2018
|
#### Step 10 — Generate the build brief
|
|
1975
2019
|
|
|
@@ -1992,15 +2036,15 @@ Call `mcp__ritual__generate_build_brief` with:
|
|
|
1992
2036
|
- `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.
|
|
1993
2037
|
- `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.
|
|
1994
2038
|
|
|
1995
|
-
Returns the
|
|
2039
|
+
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).
|
|
1996
2040
|
|
|
1997
|
-
##### 10b —
|
|
2041
|
+
##### 10b — Status polling (CLI Tenet #8)
|
|
1998
2042
|
|
|
1999
|
-
`generate_build_brief`
|
|
2043
|
+
`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.
|
|
2000
2044
|
|
|
2001
|
-
**Don't
|
|
2045
|
+
**Don't treat the GENERATING response as the brief, and don't re-call generate to "check".** Poll the status:
|
|
2002
2046
|
|
|
2003
|
-
1.
|
|
2047
|
+
1. After `generate_build_brief` returns `GENERATING` (or on the rare local timeout), call `mcp__ritual__get_build_brief_status(exploration_id, icp)`.
|
|
2004
2048
|
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.
|
|
2005
2049
|
3. Exit conditions:
|
|
2006
2050
|
|
|
@@ -2176,6 +2220,7 @@ Branch by user response. The CTA on screen is `go`, but accept these as synonyms
|
|
|
2176
2220
|
|
|
2177
2221
|
**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.
|
|
2178
2222
|
|
|
2223
|
+
<!-- lite:skip-start reason="optional UX brief review is not part of lite" -->
|
|
2179
2224
|
#### Step 10.5 — Optional UX brief review (entered ONLY when the user picks `ux-review` at Step 10d)
|
|
2180
2225
|
|
|
2181
2226
|
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`).
|
|
@@ -2269,6 +2314,8 @@ Steps:
|
|
|
2269
2314
|
|
|
2270
2315
|
**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.
|
|
2271
2316
|
|
|
2317
|
+
<!-- lite:skip-end -->
|
|
2318
|
+
<!-- lite:keep-start -->
|
|
2272
2319
|
#### Step 11 — Implement
|
|
2273
2320
|
|
|
2274
2321
|
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.
|
|
@@ -2359,9 +2406,23 @@ The user is now in plan mode (from Step 11.0.5). The agent must:
|
|
|
2359
2406
|
|
|
2360
2407
|
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.
|
|
2361
2408
|
|
|
2362
|
-
2. **
|
|
2409
|
+
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:
|
|
2410
|
+
|
|
2411
|
+
> **Scope contract — your plan must honour this (it will be audited):**
|
|
2412
|
+
> - **MUST cover** (one or more plan steps each, and cite the requirement): {each `scopeContractResolved.inScope[].text`}
|
|
2413
|
+
> - **Do NOT implement — deferred to a LATER PR** (out of scope for this change): {each `deferred[].text`}
|
|
2414
|
+
> - **Do NOT cross — non-goals**: {each `antiGoals[].text`}
|
|
2415
|
+
> - **Open questions — do NOT silently implement; flag if you must touch**: {each `discoveryGates[].text`}
|
|
2416
|
+
|
|
2417
|
+
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.
|
|
2418
|
+
|
|
2419
|
+
3. **Produce a numbered implementation plan** that:
|
|
2420
|
+
- 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),
|
|
2421
|
+
- implements **none** of the deferred items and crosses **none** of the non-goals,
|
|
2422
|
+
- puts the RBs, any verification contradictions, and any UX "new work" surfaces at the top,
|
|
2423
|
+
- names the specific files / functions / new modules each step touches — concrete enough that the user can spot a mistake before any edit.
|
|
2363
2424
|
|
|
2364
|
-
|
|
2425
|
+
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`).
|
|
2365
2426
|
|
|
2366
2427
|
##### 11.1.5 — Optional: save the implementation plan as a markdown artifact
|
|
2367
2428
|
|
|
@@ -2404,6 +2465,87 @@ Save this plan to `IMPLEMENTATION-PLAN.md` before coding? (y/N)
|
|
|
2404
2465
|
|
|
2405
2466
|
**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.
|
|
2406
2467
|
|
|
2468
|
+
<!-- lite:skip-start reason="optional plan-fidelity audit is not part of lite" -->
|
|
2469
|
+
##### 11.1.6 — Optional: audit the plan against the brief (Audit 3 / plan-fidelity)
|
|
2470
|
+
|
|
2471
|
+
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.
|
|
2472
|
+
|
|
2473
|
+
**Gate behavior by build mode** (from Step 0.1's `auditMode`):
|
|
2474
|
+
|
|
2475
|
+
- **`normal` (default):** offer it; default is to skip (most plans are faithful).
|
|
2476
|
+
- **`audited`:** recommend it (default yes).
|
|
2477
|
+
- **`strict`:** run it automatically (no prompt), and treat an `anti_goal_violation` as blocking.
|
|
2478
|
+
|
|
2479
|
+
**Rendering contract — verbatim (normal / audited modes):**
|
|
2480
|
+
|
|
2481
|
+
```text
|
|
2482
|
+
Plan ready — audit it against the brief before coding?
|
|
2483
|
+
|
|
2484
|
+
Ritual can check this plan against BUILD-BRIEF.md's scope contract — flagging
|
|
2485
|
+
anything the plan drops (a brief requirement no step covers), sneaks in
|
|
2486
|
+
(out-of-scope work), or that crosses a non-goal — before you write code.
|
|
2487
|
+
|
|
2488
|
+
Reply `audit-plan` to run it, or `proceed` to start implementing.
|
|
2489
|
+
```
|
|
2490
|
+
|
|
2491
|
+
[USER PAUSE] Branch on response:
|
|
2492
|
+
|
|
2493
|
+
- **`audit-plan`** (or auto, in `strict` mode): call
|
|
2494
|
+
`mcp__ritual__audit_plan(exploration_id, plan_content)` where `plan_content`
|
|
2495
|
+
is the implementation plan plan mode just produced (the same text you'd save to
|
|
2496
|
+
`IMPLEMENTATION-PLAN.md`). The server normalizes it to plan operations and runs
|
|
2497
|
+
R6 against the brief's scope contract. It's async — the tool polls to
|
|
2498
|
+
completion and returns a thin payload:
|
|
2499
|
+
- `audit_status: "ok"` (no divergences) → tell the user the plan is faithful to
|
|
2500
|
+
the brief and continue to Step 11.2.
|
|
2501
|
+
- `audit_status: "needs_attention"` → render each divergence (`divergence_kind`
|
|
2502
|
+
+ the `plan_op` and/or `brief_reference` it concerns + `rationale`). Group by
|
|
2503
|
+
kind: **missing_brief_decision** ("the brief asked for X; no plan step covers
|
|
2504
|
+
it" — computed deterministically from coverage), **out_of_scope_addition**
|
|
2505
|
+
("step N does X, which maps to nothing in the brief"), **premature_implementation**
|
|
2506
|
+
("step N implements X, which the brief deferred to a LATER phase/PR — not this
|
|
2507
|
+
one"), **scope_creep** ("step N covers X but does substantially more"). Then
|
|
2508
|
+
pause: *"Revise the plan to address these (back to plan mode), or proceed and
|
|
2509
|
+
accept the divergences? Reply `revise` or `proceed`."*
|
|
2510
|
+
- `audit_status: "blocked"` (an `anti_goal_violation`) → surface it prominently:
|
|
2511
|
+
*"⚠ The plan advances something the brief explicitly forbids: {evidence}. This
|
|
2512
|
+
crosses a non-goal you set during discovery."* In `strict` mode this blocks —
|
|
2513
|
+
require `revise` or an explicit `override` with a one-line justification. In
|
|
2514
|
+
other modes, strongly recommend `revise`.
|
|
2515
|
+
- On `revise`: the audit response carries a ready-to-paste **`revision_directive`**
|
|
2516
|
+
(assembled from the structured `revisions[]`, blockers first — each is a
|
|
2517
|
+
`request_plan_revision` repair keyed to a specific divergence). Feed that
|
|
2518
|
+
directive **verbatim** back into plan mode as the revision agenda (back to
|
|
2519
|
+
Step 11.1, keeping the scope contract from 11.1's step 2 in force), let plan
|
|
2520
|
+
mode produce a revised plan, then **re-run `audit_plan` on the revised plan**.
|
|
2521
|
+
This is the runtime repair loop: `audit_plan` → `revise` → `audit_plan`.
|
|
2522
|
+
- **Cap it at 2 revision rounds.** If divergences remain after the 2nd
|
|
2523
|
+
revision, stop looping and surface the residual divergences to the user with
|
|
2524
|
+
a decision: *"These divergences persist after 2 revisions — accept them
|
|
2525
|
+
(they'll be logged), or stop here? Reply `accept` or `pause`."* Don't churn.
|
|
2526
|
+
- On `proceed` / `override` / `accept`: continue to Step 11.2. Treat each
|
|
2527
|
+
accepted divergence as a **`confirm_intentional_divergence`** — record it as a
|
|
2528
|
+
Step 12 `sync_implementation` decision (`area` = the requirement/anti-goal,
|
|
2529
|
+
`choice` = "intentionally diverged: {why}", `source_recommendation_id` = the
|
|
2530
|
+
`brief_reference.id`) so the override is captured in lineage rather than lost.
|
|
2531
|
+
A persistent *anti-goal violation* the user keeps overriding is a signal the
|
|
2532
|
+
BRIEF (or its anti-goals) is wrong — surface that, don't just bury it.
|
|
2533
|
+
- **`proceed`** (or anything else): skip the audit and continue to Step 11.2. Do
|
|
2534
|
+
not re-prompt.
|
|
2535
|
+
|
|
2536
|
+
**Rules:**
|
|
2537
|
+
|
|
2538
|
+
- **Requires a READY BuildBrief with a scope contract.** Briefs synthesized before
|
|
2539
|
+
the scope-contract feature lack one; if `audit_plan` returns a 400 about a
|
|
2540
|
+
missing contract, regenerate the brief (`generate_build_brief force:true`) or
|
|
2541
|
+
skip the audit — don't block the build on it.
|
|
2542
|
+
- **Advisory, not auto-repair.** R6 surfaces divergences; the fix is always a
|
|
2543
|
+
human-in-the-loop plan revision or an explicit accept. Never silently rewrite
|
|
2544
|
+
the plan.
|
|
2545
|
+
- **Don't dump the raw normalized plan ops** into the chat — surface the
|
|
2546
|
+
divergences (the signal), not the methodology.
|
|
2547
|
+
|
|
2548
|
+
<!-- lite:skip-end -->
|
|
2407
2549
|
##### 11.2 — Implement
|
|
2408
2550
|
|
|
2409
2551
|
1. Use the standard coding-loop tools (Edit/Write/Bash/etc.) to execute the accepted plan.
|
|
@@ -2451,40 +2593,55 @@ If the user says "y" / "push" / "open PR":
|
|
|
2451
2593
|
3. `gh pr create --base <default-branch> --title <…> --body <…>`.
|
|
2452
2594
|
4. Surface the PR URL to the user.
|
|
2453
2595
|
|
|
2596
|
+
**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.
|
|
2597
|
+
|
|
2454
2598
|
**PR body template:**
|
|
2455
2599
|
|
|
2456
2600
|
```markdown
|
|
2457
|
-
##
|
|
2601
|
+
## What this PR does
|
|
2458
2602
|
|
|
2459
|
-
<2-3
|
|
2603
|
+
<2-3 plain sentences: the change + the problem it solves, derived from the build brief's Goal>
|
|
2460
2604
|
|
|
2461
|
-
##
|
|
2605
|
+
## Where to look (review order)
|
|
2462
2606
|
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
| … | | |
|
|
2607
|
+
1. `<path>` — <the load-bearing change; start here>
|
|
2608
|
+
2. `<path>` — <how it integrates>
|
|
2609
|
+
3. `<path>` — <schema/data changes, if any>
|
|
2610
|
+
<ordered load-bearing → plumbing, so review time goes where it matters>
|
|
2468
2611
|
|
|
2469
|
-
##
|
|
2612
|
+
## Why / key decisions
|
|
2470
2613
|
|
|
2471
|
-
- <
|
|
2472
|
-
- <coverage notes if non-trivial>
|
|
2614
|
+
- <decision + the trade-off / alternative rejected — the 1-3 calls a reviewer might second-guess, taken from the brief's decisions>
|
|
2473
2615
|
|
|
2474
|
-
##
|
|
2616
|
+
## How to verify
|
|
2475
2617
|
|
|
2476
|
-
-
|
|
2477
|
-
-
|
|
2478
|
-
- 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)*
|
|
2479
|
-
- Deferrals intentionally punted: <count, with one-line each>
|
|
2618
|
+
- Automated: <test files + how to run them>
|
|
2619
|
+
- Manual: <steps a reviewer runs locally to see it work>
|
|
2480
2620
|
|
|
2481
|
-
|
|
2621
|
+
## Scope & follow-ups
|
|
2622
|
+
|
|
2623
|
+
- In scope: <what this PR delivers>
|
|
2624
|
+
- Out of scope / deferred: <intentional punts, one line each — so reviewers don't flag them as gaps>
|
|
2625
|
+
|
|
2626
|
+
## Risk / blast radius
|
|
2627
|
+
|
|
2628
|
+
- <backward-compat, migration ordering, perf — what could break in prod>
|
|
2629
|
+
|
|
2630
|
+
## Ritual lineage
|
|
2631
|
+
|
|
2632
|
+
- Exploration: [<exploration name>](<EXPLORATION_URL>) · Build brief: `BUILD-BRIEF.md` (committed for reviewer reference) · Requirements satisfied: <N/M>
|
|
2633
|
+
- Implementation plan: see `IMPLEMENTATION-PLAN.md` *(only if Step 11.1.5 wrote it)*
|
|
2634
|
+
|
|
2635
|
+
Ritual-Exploration: <exploration_id>
|
|
2482
2636
|
|
|
2483
2637
|
🪷 Generated via [Ritual](https://ritual.work) — closing the loop with `sync_implementation` after merge.
|
|
2484
2638
|
```
|
|
2485
2639
|
|
|
2640
|
+
> **`<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.
|
|
2641
|
+
|
|
2486
2642
|
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.
|
|
2487
2643
|
|
|
2644
|
+
<!-- lite:keep-end -->
|
|
2488
2645
|
#### Step 12 — Close the loop with `sync_implementation`
|
|
2489
2646
|
|
|
2490
2647
|
##### 12.0 — What this step does (in product terms)
|
|
@@ -2523,7 +2680,7 @@ Call `mcp__ritual__sync_implementation` with:
|
|
|
2523
2680
|
- `deferrals[]` — for things you intentionally punted (`rb_id`, `description`, `reason`, `severity`, `related_files[]`, `related_modules[]`)
|
|
2524
2681
|
- `gate_verdict`, `adherence_rate` — your own self-reported quality signals
|
|
2525
2682
|
|
|
2526
|
-
The A1.5 snapshot column auto-captures each linked recommendation's status at the moment of sync — so if you implemented
|
|
2683
|
+
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.
|
|
2527
2684
|
|
|
2528
2685
|
When sync_implementation succeeds, the response includes:
|
|
2529
2686
|
|
|
@@ -2555,7 +2712,7 @@ any touched file to trace this back later.
|
|
|
2555
2712
|
|
|
2556
2713
|
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.
|
|
2557
2714
|
|
|
2558
|
-
If any anchor's `recommendationStatusAtImplementation` is NOT `approved` (i.e. the
|
|
2715
|
+
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):
|
|
2559
2716
|
|
|
2560
2717
|
```text
|
|
2561
2718
|
⚠ {M} of the recommendations were implemented while still in {status}
|
|
@@ -2632,7 +2789,85 @@ Reply `1`, `2`, or `3`. Reply `pause` to stop here.
|
|
|
2632
2789
|
|
|
2633
2790
|
If the saved payload's `commits[]` matches current git state, proceed silently to the retry.
|
|
2634
2791
|
|
|
2635
|
-
|
|
2792
|
+
<!-- lite:keep-start -->
|
|
2793
|
+
#### Step 13 — Suggest the next job to be done
|
|
2794
|
+
|
|
2795
|
+
The loop just closed (Step 12). Rather than stop cold and make the user
|
|
2796
|
+
re-bootstrap context for whatever they do next, offer the **next best job to be
|
|
2797
|
+
done** — a NEW discovery exploration in THIS workspace, so the knowledge graph,
|
|
2798
|
+
deferrals, and prior explorations you just built keep compounding. This is
|
|
2799
|
+
forward motion, never required work.
|
|
2800
|
+
|
|
2801
|
+
##### 13.1 — Generate the suggestion set
|
|
2802
|
+
|
|
2803
|
+
Call `mcp__ritual__suggest_next_job` with `{ exploration_id }` (the
|
|
2804
|
+
just-finished exploration). It returns 1 primary + up to 2 alternatives. Each is
|
|
2805
|
+
a NEW exploration that runs its own discovery — it is **never** "go implement the
|
|
2806
|
+
recommendations you already have" (that's the coding agent's job — `/ritual
|
|
2807
|
+
resume` on this same exploration). Each suggestion carries:
|
|
2808
|
+
|
|
2809
|
+
- `jtbd` + `label` — the job, already picked
|
|
2810
|
+
- `reasoning` — the concrete signal it cites (a deferral, an unaddressed recommendation, or the natural lifecycle continuation)
|
|
2811
|
+
- `descriptionSeed` — a first-person "what to explore" framing to pre-fill the next exploration's problem box
|
|
2812
|
+
- `recommendedPersona`, `sourceRecommendationId`, `id`
|
|
2813
|
+
|
|
2814
|
+
Also returned: `recommendationsAddressed` (false ⇒ this exploration still has
|
|
2815
|
+
clear-to-implement work that ships via `resume`, not a next job).
|
|
2816
|
+
|
|
2817
|
+
- **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.
|
|
2818
|
+
|
|
2819
|
+
##### 13.2 — Present the picker
|
|
2820
|
+
|
|
2821
|
+
**[USER PAUSE]** Render the standard list-picker (primary first, marked ★):
|
|
2822
|
+
|
|
2823
|
+
```text
|
|
2824
|
+
Next job to be done
|
|
2825
|
+
|
|
2826
|
+
{exploration name} is shipped and logged. To keep building on what this
|
|
2827
|
+
workspace now knows, here's the next discovery worth running:
|
|
2828
|
+
|
|
2829
|
+
★ 1. {primary label}
|
|
2830
|
+
{primary reasoning}
|
|
2831
|
+
|
|
2832
|
+
2. {alt1 label}
|
|
2833
|
+
{alt1 reasoning}
|
|
2834
|
+
|
|
2835
|
+
3. {alt2 label}
|
|
2836
|
+
{alt2 reasoning}
|
|
2837
|
+
|
|
2838
|
+
Reply `1`, `2`, or `3` to start it — the job's already picked, so you'll go
|
|
2839
|
+
straight to framing what to explore. Reply `skip` to stop here.
|
|
2840
|
+
```
|
|
2841
|
+
|
|
2842
|
+
Only render lines for the suggestions actually returned (there may be just a
|
|
2843
|
+
primary, or a primary + 1). If `recommendationsAddressed` is `false`, add ONE
|
|
2844
|
+
line below the picker — lean on the coding agent, don't turn Ritual into a
|
|
2845
|
+
backlog manager:
|
|
2846
|
+
|
|
2847
|
+
```text
|
|
2848
|
+
({N} item{s} from this exploration are clear to implement — say `resume` to continue shipping them here.)
|
|
2849
|
+
```
|
|
2850
|
+
|
|
2851
|
+
**[USER PAUSE — required, do not auto-answer]** Wait for the user's reply.
|
|
2852
|
+
|
|
2853
|
+
##### 13.2.1 — On pick (`1` / `2` / `3`)
|
|
2854
|
+
|
|
2855
|
+
The picked suggestion is a NEW exploration in the SAME workspace with the job
|
|
2856
|
+
already chosen — so **advance, don't re-bootstrap**:
|
|
2857
|
+
|
|
2858
|
+
1. Skip the work-item / job pick entirely (Steps 0–4) — `jtbd` is already set by the suggestion.
|
|
2859
|
+
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.
|
|
2860
|
+
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).
|
|
2861
|
+
- 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.
|
|
2862
|
+
4. Continue the normal flow from **Step 7 (discovery)**.
|
|
2863
|
+
|
|
2864
|
+
##### 13.2.2 — On `skip`
|
|
2865
|
+
|
|
2866
|
+
Acknowledge and drop to 13.3. The suggestion set is persisted — a later `ritual
|
|
2867
|
+
graph status` or re-run of `/ritual build` in this workspace can surface it
|
|
2868
|
+
again; nothing is lost.
|
|
2869
|
+
|
|
2870
|
+
##### 13.3 — Follow-up pointer
|
|
2636
2871
|
|
|
2637
2872
|
If they want to check the state at any time, point them at:
|
|
2638
2873
|
|
|
@@ -2640,9 +2875,10 @@ If they want to check the state at any time, point them at:
|
|
|
2640
2875
|
|
|
2641
2876
|
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.
|
|
2642
2877
|
|
|
2878
|
+
<!-- lite:keep-end -->
|
|
2643
2879
|
### Failure modes & recovery
|
|
2644
2880
|
|
|
2645
|
-
**Discovery generation hangs (>5 min polling without `ready: true`)**: ask the user — wait longer
|
|
2881
|
+
**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.
|
|
2646
2882
|
|
|
2647
2883
|
**Agentic run fails or stalls**: surface the error, offer retry or stop.
|
|
2648
2884
|
|
|
@@ -2660,7 +2896,7 @@ This subcommand exclusively uses Ritual MCP tools, in the order they appear:
|
|
|
2660
2896
|
4. `mcp__ritual__suggest_high_leverage_problems` (Step 1.5 step 6b — option 3, "help me find the highest-leverage thing")
|
|
2661
2897
|
5. `mcp__ritual__check_exploration_overlap` (Step 1.5 step 8 — pre-creation overlap detection before "start fresh")
|
|
2662
2898
|
5a. `mcp__ritual__archive_exploration` (Step 1.5 step 6a — soft-delete a duplicate/misfire when user picks `delete N` from the resume menu)
|
|
2663
|
-
6.
|
|
2899
|
+
6. ~~`mcp__ritual__list_templates`~~ — **REMOVED 2026-05-21 (CLI 0.9.0+).** Step 2 is now server-side template resolution; the tool is no longer registered on the MCP surface. Do not call it. See Step 2 § "Rewritten 2026-05-21" for the rationale.
|
|
2664
2900
|
7. `mcp__ritual__generate_considerations` (Step 4)
|
|
2665
2901
|
8. `mcp__ritual__refine_considerations` (Step 4.2, iteration only)
|
|
2666
2902
|
9. `mcp__ritual__generate_problem_statement` (Step 5)
|
|
@@ -2684,19 +2920,25 @@ This subcommand exclusively uses Ritual MCP tools, in the order they appear:
|
|
|
2684
2920
|
24. `mcp__ritual__generate_build_brief` (Step 10a)
|
|
2685
2921
|
24a. `mcp__ritual__get_build_brief_status` (Step 10b — timeout-recovery polling, OR proactive cache-hit check before 10a)
|
|
2686
2922
|
24d. `mcp__ritual__sync_brief_review` (Step 10b.5 — sync `BUILD-BRIEF-VERIFICATION.md` to KG; AND Step 10.5 — sync `UX-REVIEW.md` to KG)
|
|
2687
|
-
24b. `mcp__ritual__add_knowledge_source` (Step
|
|
2923
|
+
24b. `mcp__ritual__add_knowledge_source` (Step 6.2 — register staged knowledge sources after `create_exploration` returns `exploration_id`; staging happens at Step 3.5)
|
|
2688
2924
|
24c. `mcp__ritual__list_knowledge_sources` (used inline by Step 3.5 to show already-attached refs on resume; also called by `/ritual context-pulse` CP2 for Reference Grounding count)
|
|
2925
|
+
24e. `mcp__ritual__audit_recommendations` (Step 9.6 — start an audit chain on the (anti-goals, typed recs+reqs, R4) triple; cli 0.10.0+)
|
|
2926
|
+
24f. `mcp__ritual__apply_repair` (Step 9.6 — apply or waive a structured repair instruction returned by an audit iteration; cli 0.10.0+)
|
|
2927
|
+
24g. `mcp__ritual__get_audit_chain` (Step 9.6 — fetch the full chain trail for review/lineage; cli 0.10.0+)
|
|
2689
2928
|
25. `mcp__ritual__sync_implementation` (Step 12)
|
|
2929
|
+
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)
|
|
2930
|
+
|
|
2931
|
+
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`).
|
|
2690
2932
|
|
|
2691
|
-
|
|
2933
|
+
**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.
|
|
2692
2934
|
|
|
2693
2935
|
### After this subcommand
|
|
2694
2936
|
|
|
2695
2937
|
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.
|
|
2696
2938
|
|
|
2697
2939
|
Variants:
|
|
2698
|
-
-
|
|
2699
|
-
-
|
|
2940
|
+
- 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).
|
|
2941
|
+
- 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).
|
|
2700
2942
|
- 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.)
|
|
2701
2943
|
|
|
2702
2944
|
---
|