@ritualai/cli 0.7.8 → 0.7.10
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/init.js +74 -45
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.js +20 -18
- package/dist/commands/login.js.map +1 -1
- package/dist/lib/identity-banner.js +2 -1
- package/dist/lib/identity-banner.js.map +1 -1
- package/dist/lib/oidc.js +19 -10
- package/dist/lib/oidc.js.map +1 -1
- package/dist/lib/welcome-banner.js +9 -12
- package/dist/lib/welcome-banner.js.map +1 -1
- package/dist/lib/workspace-flow.js +11 -5
- package/dist/lib/workspace-flow.js.map +1 -1
- package/package.json +1 -1
- package/skills/claude-code/ritual/references/async-polling.md +43 -9
- package/skills/claude-code/ritual/references/build-flow.md +818 -130
- package/skills/claude-code/ritual/references/cli-output-contract.md +185 -9
- package/skills/claude-code/ritual/references/context-pulse-flow.md +3 -3
- package/skills/claude-code/ritual/references/discovery-classification.md +3 -3
- package/skills/claude-code/ritual/references/resume-flow.md +47 -0
- package/skills/codex/ritual/references/async-polling.md +43 -9
- package/skills/codex/ritual/references/build-flow.md +818 -130
- package/skills/codex/ritual/references/cli-output-contract.md +185 -9
- package/skills/codex/ritual/references/context-pulse-flow.md +3 -3
- package/skills/codex/ritual/references/discovery-classification.md +3 -3
- package/skills/codex/ritual/references/resume-flow.md +47 -0
- package/skills/cursor/ritual/references/async-polling.md +43 -9
- package/skills/cursor/ritual/references/build-flow.md +818 -130
- package/skills/cursor/ritual/references/cli-output-contract.md +185 -9
- package/skills/cursor/ritual/references/context-pulse-flow.md +3 -3
- package/skills/cursor/ritual/references/discovery-classification.md +3 -3
- package/skills/cursor/ritual/references/resume-flow.md +47 -0
- package/skills/gemini/ritual/references/async-polling.md +43 -9
- package/skills/gemini/ritual/references/build-flow.md +818 -130
- package/skills/gemini/ritual/references/cli-output-contract.md +185 -9
- package/skills/gemini/ritual/references/context-pulse-flow.md +3 -3
- package/skills/gemini/ritual/references/discovery-classification.md +3 -3
- package/skills/gemini/ritual/references/resume-flow.md +47 -0
- package/skills/kiro/ritual/references/async-polling.md +43 -9
- package/skills/kiro/ritual/references/build-flow.md +818 -130
- package/skills/kiro/ritual/references/cli-output-contract.md +185 -9
- package/skills/kiro/ritual/references/context-pulse-flow.md +3 -3
- package/skills/kiro/ritual/references/discovery-classification.md +3 -3
- package/skills/kiro/ritual/references/resume-flow.md +47 -0
- package/skills/vscode/ritual/references/async-polling.md +43 -9
- package/skills/vscode/ritual/references/build-flow.md +818 -130
- package/skills/vscode/ritual/references/cli-output-contract.md +185 -9
- package/skills/vscode/ritual/references/context-pulse-flow.md +3 -3
- package/skills/vscode/ritual/references/discovery-classification.md +3 -3
- package/skills/vscode/ritual/references/resume-flow.md +47 -0
|
@@ -12,17 +12,23 @@ The Ritual data model uses product-research terminology. This skill translates t
|
|
|
12
12
|
|---|---|
|
|
13
13
|
| **scope** | `problemStatement` |
|
|
14
14
|
| **sub-problem** | `consideration` |
|
|
15
|
-
| **
|
|
15
|
+
| **Area** (NOT "matter") | `matter` |
|
|
16
16
|
| **discovery question** | `question` |
|
|
17
17
|
| **recommendation** | `recommendation` |
|
|
18
18
|
|
|
19
19
|
When the user says "tighten the scope," call `generate_problem_statement(...)` with their refinement. When you tell the user "I picked these sub-problems," you mean the items you put in `considerations[]`. The tools don't change; only the language to the user does.
|
|
20
20
|
|
|
21
|
+
**On "Area" vs "matter":** the API field is `matter` for historical reasons. The user-facing label is **Area** because it's plainer and reads less research-y in a developer flow. NEVER surface "matter" or "matter.name" in user-facing copy — use "Area" / "Area name" instead.
|
|
22
|
+
|
|
21
23
|
|
|
22
24
|
### Runtime contracts
|
|
23
25
|
|
|
24
26
|
Before running this flow, apply `references/cli-output-contract.md` and `references/async-polling.md`. Keep raw recon internal, pass the `codebase_context_packet` downstream, and show the user only the compact `recon_digest`.
|
|
25
27
|
|
|
28
|
+
**Build rail is load-bearing.** Every top-level user-facing message below MUST begin with the 6-stage build rail per `references/cli-output-contract.md` § Build progress anchor. Examples in this file show the rail in context; the canonical stage table + `progressHeader(stage)` spec lives in the output contract. Do not drop the rail to save space.
|
|
29
|
+
|
|
30
|
+
For narrow/mobile chat surfaces, use the **compact progress anchor** defined in `references/cli-output-contract.md` § Build progress anchor (the `Ritual build · 2/6 Scope` chip) instead of forcing the full six-stage rail to wrap. Same contract, different rendering.
|
|
31
|
+
|
|
26
32
|
### When to use
|
|
27
33
|
|
|
28
34
|
- The user describes a new feature, refactor, migration, or implementation-heavy change that needs planning before coding
|
|
@@ -39,13 +45,63 @@ When **not** to use:
|
|
|
39
45
|
|
|
40
46
|
Use explicit **[USER PAUSE]** only at decision gates. Pause when the user must choose among options, approve creation or acceptance, resolve ambiguity, authorize implementation, accept cost/time, or provide missing non-code context. Do **not** pause for status-only steps, safe defaults, internal recon, or silent checks.
|
|
41
47
|
|
|
48
|
+
**Pauses are not optional even in auto-mode.** See Step 0 below — when the host agent has auto-accept / bypass-permissions enabled, the SKILL must still honor every `[USER PAUSE]` as a hard stop. Inferring an answer from context, choosing a default, or pressing on without an actual user reply defeats the build flow's value: Ritual is producing aligned recommendations because the human shaped the inputs, not because the agent guessed plausibly.
|
|
49
|
+
|
|
42
50
|
---
|
|
43
51
|
|
|
44
52
|
### CLI and async guardrails
|
|
45
53
|
|
|
46
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.
|
|
47
55
|
|
|
48
|
-
#### Step
|
|
56
|
+
#### Step 0 — Permission mode check (pre-flight)
|
|
57
|
+
|
|
58
|
+
Before any tool call on a fresh `/ritual build` invocation, check whether the host coding agent is running in **auto-accept** or **bypass-permissions** mode. Different agents call this different things, but the behavioral signature is the same: the agent has been told it can skip per-action confirmations and keep moving.
|
|
59
|
+
|
|
60
|
+
Why this matters: `/ritual build` is built around ~5 real human decisions (workspace, scope, discovery question picks, recommendation acceptance, implementation approval). Each is a `[USER PAUSE]` later in this flow. Auto-mode collapses those gates — the agent defaults each answer and races through. The resulting exploration looks normal but doesn't reflect the user's judgment, which is the entire reason `/ritual build` exists rather than going straight to code.
|
|
61
|
+
|
|
62
|
+
How to detect (per-agent):
|
|
63
|
+
|
|
64
|
+
| Agent | Indicator |
|
|
65
|
+
|---|---|
|
|
66
|
+
| **Claude Code** | TUI footer shows `auto-accept edits` or `bypass permissions`. Toggled with **Shift+Tab**. |
|
|
67
|
+
| **Cursor** | "Auto" / "Yolo" toggle in the Composer/Agent panel. |
|
|
68
|
+
| **Codex** | `--full-auto` CLI flag or the equivalent setting in the IDE extension. |
|
|
69
|
+
| **Kiro** | Per-server `autoApprove[]` arrays in `mcp.json`, plus any global "auto" toggle in the Agent panel. |
|
|
70
|
+
| **Windsurf / VS Code Copilot / Gemini CLI** | Each has its own auto-accept mode in settings. |
|
|
71
|
+
|
|
72
|
+
If the agent cannot detect this with confidence (the indicator surface differs by version), default to **asking the user** at the start of every `/ritual build`. The check is cheap; a wasted build is not.
|
|
73
|
+
|
|
74
|
+
**If auto-mode is on (or you're uncertain), surface this before Step 1:**
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
Heads up — looks like your coding agent is in auto-mode for this session.
|
|
78
|
+
|
|
79
|
+
Ritual's build flow needs ~5 real decisions from you across the next
|
|
80
|
+
20–30 minutes:
|
|
81
|
+
· which workspace to use
|
|
82
|
+
· how to scope the problem
|
|
83
|
+
· which discovery questions matter for your case
|
|
84
|
+
· which recommendations to accept
|
|
85
|
+
· whether the build brief is ready to implement
|
|
86
|
+
|
|
87
|
+
Auto-mode tends to speed past these. The output will look like a
|
|
88
|
+
normal Ritual exploration but won't actually reflect your input —
|
|
89
|
+
the recommendations will be plausible-but-not-yours.
|
|
90
|
+
|
|
91
|
+
──────────────────────────────────────────────────────────────────
|
|
92
|
+
Recommended: turn off auto-mode before continuing.
|
|
93
|
+
· Claude Code: Shift+Tab to cycle back to "default"
|
|
94
|
+
· Other agents: see your agent's settings or CLI flag
|
|
95
|
+
──────────────────────────────────────────────────────────────────
|
|
96
|
+
|
|
97
|
+
1. Pause — I'll turn off auto-mode, then say "go"
|
|
98
|
+
2. Continue anyway (I want speed over alignment for this run)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**[USER PAUSE — required, do not auto-answer]** Wait for an actual user message before proceeding.
|
|
102
|
+
|
|
103
|
+
Regardless of which option the user picks, treat every subsequent `[USER PAUSE]` in this flow as a hard stop. Do not infer answers from context, do not pick a "reasonable default," do not press on without an actual user reply. The user picking option 2 means *they accept the trade-off* — it does NOT grant you permission to auto-answer the gates that come next.
|
|
104
|
+
|
|
49
105
|
#### Step 1 — Pick a workspace
|
|
50
106
|
|
|
51
107
|
Resolution order:
|
|
@@ -102,7 +158,7 @@ If there are **zero existing explorations** and `raw_input = null`, do not say "
|
|
|
102
158
|
|
|
103
159
|
```text
|
|
104
160
|
Ritual build
|
|
105
|
-
● Context ○ Scope ○ Discovery ○ Recommendations ○ Build brief ○ Implementation
|
|
161
|
+
● Context ○ Scope ○ Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
|
|
106
162
|
|
|
107
163
|
Using workspace: {workspaceName}.
|
|
108
164
|
|
|
@@ -137,7 +193,7 @@ Steps:
|
|
|
137
193
|
>
|
|
138
194
|
> **{state_glyph} {state_label}**
|
|
139
195
|
> - **{name}** — {short scope summary, first 80 chars of problemStatement}
|
|
140
|
-
> - {recommendationCount} rec{s} ({accepted}/{total} approved
|
|
196
|
+
> - {recommendationCount} rec{s} ({accepted}/{total} approved{implementationSegment}), {openDeferralsCount} open deferral{s}
|
|
141
197
|
> - {state-specific call-to-action — see table below}
|
|
142
198
|
>
|
|
143
199
|
> Recommended: resume one if it matches this work.
|
|
@@ -149,7 +205,7 @@ Steps:
|
|
|
149
205
|
>
|
|
150
206
|
> **{state_glyph} {state_label}**
|
|
151
207
|
> - **{name}** — {short scope summary, first 80 chars of problemStatement}
|
|
152
|
-
> - {recommendationCount} rec{s} ({accepted}/{total} approved
|
|
208
|
+
> - {recommendationCount} rec{s} ({accepted}/{total} approved{implementationSegment}), {openDeferralsCount} open deferral{s}
|
|
153
209
|
> - {state-specific call-to-action — see table below}
|
|
154
210
|
>
|
|
155
211
|
> Reply with:
|
|
@@ -158,6 +214,20 @@ Steps:
|
|
|
158
214
|
> - a feature/problem description to start fresh
|
|
159
215
|
> - `none` to exit
|
|
160
216
|
|
|
217
|
+
**`{implementationSegment}` resolution rule** — derive from `implementationStatus.implementationRecord` on the listing response:
|
|
218
|
+
|
|
219
|
+
| Condition | Render |
|
|
220
|
+
|---|---|
|
|
221
|
+
| No `ImplementationRecord` | `` (empty — drop the segment) |
|
|
222
|
+
| Has record but `prUrl` is null | ` · synced (no PR linked)` |
|
|
223
|
+
| `prStatus = merged` | ` · implemented in PR #{prNumber}` |
|
|
224
|
+
| `prStatus = open` or `draft` | ` · implementing in PR #{prNumber} [{prStatus}]` |
|
|
225
|
+
| `prStatus = closed` (not merged) | ` · abandoned (PR #{prNumber} closed)` |
|
|
226
|
+
|
|
227
|
+
In markdown-rendering agents, hyperlink `PR #{prNumber}` to `prUrl` so users can click through. In plaintext agents, append `prUrl` on the next line.
|
|
228
|
+
|
|
229
|
+
**Rationale** — promotes recommendations to the visible noun and folds the previously-separate "decisions logged" count into the recommendation lifecycle. `Implemented` means "this exploration's approved recs shipped as code, here's the PR" — a stronger user-facing signal than a raw decision count. Decisions still exist as the underlying KG primitive (and are still surfaced explicitly by `/ritual lineage`), but they're no longer a headline concept in the build/resume status line.
|
|
230
|
+
|
|
161
231
|
State badge → user-facing label + call-to-action:
|
|
162
232
|
|
|
163
233
|
| Glyph | State | User-facing label | Suggested next action |
|
|
@@ -416,6 +486,17 @@ Proceed to Step 3 once a template is selected. No extra confirmation is required
|
|
|
416
486
|
|
|
417
487
|
Before generating considerations, gather codebase context so the sub-problems land specific to *this* code, not generic. The goal is not to show the user every fact you found; the goal is to ground downstream MCP calls and expose only decision-relevant findings in the CLI.
|
|
418
488
|
|
|
489
|
+
**Capability Boundary Check (load-bearing):** If recon detects a mismatch between the user's ask and what THIS repo can actually implement — typically because the feature spans systems (backend service, mobile app, billing provider, email worker, schema migrations) that aren't present in the current checkout — DO NOT invent the missing systems and DO NOT continue as if the repo is complete. Run the boundary-check pause described in § 3.2 below before proceeding to scope. Frame the missing half as a normal architecture boundary, not a failure: *"This repo looks like the frontend side of a larger feature,"* not *"I could not find backend dependencies."* The user has not done anything wrong; the agent is asking how to scope the work.
|
|
490
|
+
|
|
491
|
+
Common boundary mismatches to detect:
|
|
492
|
+
|
|
493
|
+
- Full-stack feature ask + frontend-only repo (UI present, no API/service code)
|
|
494
|
+
- Mobile feature ask + no API client contract or backend
|
|
495
|
+
- Billing/payments feature + no payment service / subscription code
|
|
496
|
+
- Email/notification feature + no worker / job / email-provider integration
|
|
497
|
+
- Auth/session feature + no user mutation / session backend
|
|
498
|
+
- Data/analytics feature + no schema, migration, or storage layer
|
|
499
|
+
|
|
419
500
|
##### 3.0 — Check for a pre-build context seed
|
|
420
501
|
|
|
421
502
|
Before doing fresh recon, check whether the user already seeded one via `/ritual context-pulse`. Glob for `CONTEXT-*.md` at the repo root.
|
|
@@ -427,7 +508,7 @@ If a `CONTEXT-<slug>.md` is found AND its `## The ask` section close-matches the
|
|
|
427
508
|
- **Surface a compact note**:
|
|
428
509
|
> Code recon
|
|
429
510
|
> Found `CONTEXT-<slug>.md` from `/ritual context-pulse`.
|
|
430
|
-
> Using {N} candidate files + {M} prior
|
|
511
|
+
> Using {N} candidate files + {M} related prior exploration{s} as the recon base. Override with `recon: refresh`.
|
|
431
512
|
- Proceed directly to 3.2.
|
|
432
513
|
|
|
433
514
|
If no seed file is found, OR the seed's `## The ask` doesn't match the current `raw_input`, do fresh recon. For mismatch, mention the ignored seed in one line and do not delete it.
|
|
@@ -519,12 +600,12 @@ If no seed file is found, OR the seed's `## The ask` doesn't match the current `
|
|
|
519
600
|
- No `guest_session_id` column was found in the inspected conversion models; scope may need to use the actual guest attribution identifiers.
|
|
520
601
|
```
|
|
521
602
|
|
|
522
|
-
Example `recon_digest
|
|
603
|
+
Example `recon_digest` — single-path case (low ambiguity):
|
|
523
604
|
|
|
524
605
|
```text
|
|
525
|
-
Code recon
|
|
606
|
+
Code recon
|
|
526
607
|
|
|
527
|
-
|
|
608
|
+
Repo signals:
|
|
528
609
|
- `apps/conversions/abstract_models.py` — append-only conversion events.
|
|
529
610
|
- `apps/conversions/outbox.py` — async publish/retry lifecycle.
|
|
530
611
|
- `apps/order/models.py` — raw guest email surface.
|
|
@@ -535,16 +616,128 @@ If no seed file is found, OR the seed's `## The ask` doesn't match the current `
|
|
|
535
616
|
Scope correction:
|
|
536
617
|
- I did not find `guest_session_id` in the inspected models.
|
|
537
618
|
|
|
538
|
-
|
|
619
|
+
Pulse: Reasoning Readiness ~55% · Context Debt 45% (initial ask + code recon)
|
|
620
|
+
|
|
621
|
+
Next: attach PRDs/tickets if they should shape scope, or `proceed` to continue.
|
|
539
622
|
```
|
|
540
623
|
|
|
624
|
+
Example `recon_digest` — ambiguity case (multiple plausible interpretations):
|
|
625
|
+
|
|
626
|
+
When recon surfaces two materially different product/implementation paths for the same ask, name them both, **mark one as recommended with a one-line reason**, and pause with a concrete reply syntax. Do not expose raw tier labels (use the translations from `references/cli-output-contract.md`).
|
|
627
|
+
|
|
628
|
+
```text
|
|
629
|
+
Code recon
|
|
630
|
+
|
|
631
|
+
Repo signals:
|
|
632
|
+
- `GatewayForm` already supports "create account before checkout," but
|
|
633
|
+
redirects away from checkout to `customer:register`. There is no inline
|
|
634
|
+
or post-order account path today.
|
|
635
|
+
- Guest checkout is already wired through order placement:
|
|
636
|
+
`CheckoutSessionData.set_guest_email()`, `AbstractOrder.guest_email`, and
|
|
637
|
+
`build_submission()` preserve guest identity.
|
|
638
|
+
- `RegisterUserMixin` is the reusable account-creation surface:
|
|
639
|
+
user creation, `user_registered`, login, and registration email.
|
|
640
|
+
- `OrderPlacementMixin` and `post_checkout` are the clean hooks for
|
|
641
|
+
creating or claiming an account at order placement.
|
|
642
|
+
|
|
643
|
+
Constraint:
|
|
644
|
+
- Oscar's dynamic class loading via `get_class()` is the extension
|
|
645
|
+
pattern here. Implement with subclass-overridable views/mixins, not
|
|
646
|
+
monkey-patches.
|
|
647
|
+
|
|
648
|
+
Ambiguity to resolve:
|
|
649
|
+
"Join while booking" maps to two plausible features.
|
|
650
|
+
|
|
651
|
+
1. Inline registration at checkout
|
|
652
|
+
Let new customers register on the checkout page itself instead of
|
|
653
|
+
being redirected to `/accounts/register/`.
|
|
654
|
+
|
|
655
|
+
2. Post-order account creation — recommended
|
|
656
|
+
Let guests place the order as today, then claim the order by
|
|
657
|
+
setting a password on the thank-you page. Preserves guest checkout
|
|
658
|
+
and fits Oscar's `OrderPlacementMixin` / `post_checkout` hooks.
|
|
659
|
+
|
|
660
|
+
Pulse: Reasoning Readiness ~35% · Context Debt 65% (scope not locked yet)
|
|
661
|
+
|
|
662
|
+
Next: reply `2` for the recommended post-order path, `1` for inline
|
|
663
|
+
registration, or describe a different intent. Reply `pause` to stop here.
|
|
664
|
+
```
|
|
665
|
+
|
|
666
|
+
Notes on the ambiguity-case shape:
|
|
667
|
+
- **"Repo signals"** (not "Found" or "Key surfaces") signals these are the evidence behind the recommendation.
|
|
668
|
+
- **Recommendation goes after the option name on the SAME line**, with a single concise reason on the line below. This keeps the options scannable in a decision moment.
|
|
669
|
+
- **`Next:` is a single line** ending in a concrete reply syntax (`reply N`), not an open-ended question. Lead with the recommended default; the escape hatch comes last.
|
|
670
|
+
- **The pulse line uses the user-facing label**, never the raw tier identifier.
|
|
671
|
+
|
|
672
|
+
Example `recon_digest` — Capability Boundary Check (feature spans systems not in this repo):
|
|
673
|
+
|
|
674
|
+
When the user's ask requires capabilities that aren't present in this repo (frontend-only repo asked for full-stack feature, mobile repo with no API contract, etc.), surface the boundary as a normal architecture fact and give the user three concrete scoping options. NEVER continue as if the repo can implement the missing half; NEVER invent the missing systems.
|
|
675
|
+
|
|
676
|
+
```text
|
|
677
|
+
Code recon
|
|
678
|
+
|
|
679
|
+
Action needed
|
|
680
|
+
|
|
681
|
+
This feature likely spans another repo or service.
|
|
682
|
+
Add the backend/API context, or choose a narrower scope.
|
|
683
|
+
|
|
684
|
+
Repo boundary:
|
|
685
|
+
- This repo contains the checkout UI and guest checkout flow.
|
|
686
|
+
- I found no backend account-creation endpoint, user/order linking
|
|
687
|
+
mutation, email job, or migration layer.
|
|
688
|
+
- So the full "join while booking" feature likely spans this repo plus
|
|
689
|
+
an API/backend service.
|
|
690
|
+
|
|
691
|
+
Can build here:
|
|
692
|
+
- Checkout/thank-you page UI
|
|
693
|
+
- Password capture or account-claim form
|
|
694
|
+
- API client integration point
|
|
695
|
+
- Mocked frontend tests
|
|
696
|
+
- Empty/error/success states
|
|
697
|
+
|
|
698
|
+
Needs outside context:
|
|
699
|
+
- Endpoint that creates or claims the account
|
|
700
|
+
- Contract for linking a guest order to a user
|
|
701
|
+
- Auth/session behavior after claim
|
|
702
|
+
- Email/verification behavior, if required
|
|
703
|
+
|
|
704
|
+
How should I scope this?
|
|
705
|
+
|
|
706
|
+
1. Frontend-only
|
|
707
|
+
Build the UI against an existing API. I'll ask for the endpoint/
|
|
708
|
+
contract next.
|
|
709
|
+
|
|
710
|
+
2. Contract-first — recommended if the API is not settled
|
|
711
|
+
Define the API contract and frontend integration here, then produce
|
|
712
|
+
a backend build brief for the missing service work.
|
|
713
|
+
|
|
714
|
+
3. Add backend repo/context
|
|
715
|
+
Pause here while you point me at the backend repo or docs, then I'll
|
|
716
|
+
recon the full path.
|
|
717
|
+
|
|
718
|
+
Pulse: Reasoning Readiness ~30% · Context Debt 70% (repo boundary unresolved)
|
|
719
|
+
|
|
720
|
+
Next: reply `2` for contract-first, `1` for frontend-only, or `3` to add
|
|
721
|
+
backend context. If you already know the API, paste the endpoint or
|
|
722
|
+
contract and I'll continue.
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
Notes on the boundary-check shape:
|
|
726
|
+
- **Lead with an "Action needed" callout block** that names the boundary in one sentence + the user's choice in one sentence. This is a load-bearing decision gate — leading with the callout (rather than the data) makes the gate pop in scrollback. Use this callout style only for boundary checks and other high-importance gates; ordinary recon stays in the standard `recon_digest` shape.
|
|
727
|
+
- **"Repo boundary:" not "I couldn't find…"** — frame the missing half as an architecture fact, not as a failure or as something the user did wrong. The agent is asking how to scope, not reporting an error.
|
|
728
|
+
- **"Can build here:" + "Needs outside context:"** are paired sections — they tell the user the explicit IN/OUT split for THIS repo so they can make an informed scoping decision. Don't merge them into one bullet list.
|
|
729
|
+
- **Three scoping options, recommendation on option 2 by default** — frontend-only / contract-first / add-context covers the realistic decision space. Mark "Contract-first" as recommended when the API surface is not yet defined; mark "Frontend-only" recommended when the user signaled they already have a stable API.
|
|
730
|
+
- **The pulse line stays parenthetical** with a user-facing reason (`repo boundary unresolved`), per the Pulse tier labels rule in `references/cli-output-contract.md`.
|
|
731
|
+
- **Internal classification (not user-facing):** track each candidate piece against the boundary as `in_repo_buildable`, `external_dependency_known`, `external_dependency_unknown`, `needs_additional_repo`, or `contract_first_candidate`. These shape how downstream scoring + build-brief generation handle the missing half once the user picks an option. None of these labels should appear in user-facing copy.
|
|
732
|
+
|
|
541
733
|
##### 3.2 — Surface the digest and continue
|
|
542
734
|
|
|
543
735
|
Surface only `recon_digest` by default. Do **not** dump `raw_recon_notes` or the full `codebase_context_packet` to the CLI unless the user asks for detail.
|
|
544
736
|
|
|
545
737
|
Pause only if:
|
|
546
738
|
- recon contradicts the user's stated scope,
|
|
547
|
-
- there are multiple plausible implementation areas and choosing wrong would waste work,
|
|
739
|
+
- there are multiple plausible implementation areas and choosing wrong would waste work (use the ambiguity-case `recon_digest` shape above),
|
|
740
|
+
- **recon shows the feature spans systems not in this repo** (use the Capability Boundary Check `recon_digest` shape above — frontend-only repo, missing API/service, etc.),
|
|
548
741
|
- a legal/product/business constraint is required before generation,
|
|
549
742
|
- the user explicitly asked to review recon before continuing.
|
|
550
743
|
|
|
@@ -581,21 +774,22 @@ Knowledge sources are a feature multiplier, not a mandatory gate. Ask for PRDs/t
|
|
|
581
774
|
- the feature has legal, privacy, billing, permissions, enterprise, analytics, migration, or compliance constraints,
|
|
582
775
|
- code recon found implementation surfaces but not product intent.
|
|
583
776
|
|
|
584
|
-
When triggered, frame references as an optional booster, not a mandatory phase. The happy path is to continue.
|
|
777
|
+
When triggered, frame references as an optional booster, not a mandatory phase. The happy path is to continue. Keep the prompt tight — the user's decision here is simply "attach context or continue":
|
|
585
778
|
|
|
586
779
|
```text
|
|
587
780
|
Optional: add non-code context before scope generation.
|
|
588
781
|
|
|
589
|
-
Because this touches {
|
|
590
|
-
|
|
591
|
-
Next: we'll generate a list of suggested problems to pick from.
|
|
782
|
+
Because this touches {constraint}, PRDs, tickets, designs, incidents, or
|
|
783
|
+
customer requests may change what we prioritize.
|
|
592
784
|
|
|
593
|
-
|
|
785
|
+
Reply `go` to continue with code context only.
|
|
594
786
|
Or paste files/text/URLs to attach context first.
|
|
595
|
-
|
|
787
|
+
Reply `pause` to stop here.
|
|
596
788
|
```
|
|
597
789
|
|
|
598
|
-
Accept
|
|
790
|
+
Accept (alias) `go`, `g`, `generate`, `continue`, `skip`, `next`, or `none` as proceed. Per `references/cli-output-contract.md` § Surface-aware continuation prompts, do NOT treat empty input as proceed inside agent chat — chat surfaces can't reliably observe an empty message. Wait only if the user provides refs, asks a question, or types `pause` / `stop`.
|
|
791
|
+
|
|
792
|
+
Process language like *"Next: we'll generate a list of suggested problems to pick from"* used to live here — removed because the decision at this moment is "attach context or continue," not a preview of what comes next. The follow-up step's framing belongs in the follow-up step, not stacked on this prompt.
|
|
599
793
|
|
|
600
794
|
If none of the triggers apply, do **not** block. Print a non-blocking line and proceed:
|
|
601
795
|
|
|
@@ -691,22 +885,24 @@ LLM call, ~5–10s. Returns 5–6 sub-problems — different framing axes the sy
|
|
|
691
885
|
|
|
692
886
|
The coding agent's packet is context, not authority. Do not pre-rank or collapse the generated sub-problems based only on the agent hypotheses. Let MCP/template/KG output determine the candidate considerations; use the packet to make them specific, evidenced, and grounded.
|
|
693
887
|
|
|
694
|
-
**If the response includes `kg_context_used` with `implementationCount > 0`:** surface this to the user BEFORE presenting the considerations. It's the visible signal that prior
|
|
888
|
+
**If the response includes `kg_context_used` with `implementationCount > 0`:** surface this to the user BEFORE presenting the considerations. It's the visible signal that prior shipped work shaped this draft.
|
|
695
889
|
|
|
696
890
|
> Reading the codebase I overlapped with 3 prior Ritual explorations on these files:
|
|
697
|
-
> - **"Anonymous checkout opt-in"** (shipped 2026-04-12)
|
|
698
|
-
> - **"Payment-method routing"** (shipped 2026-03-22)
|
|
699
|
-
> - **"Session-data persistence"** (shipped 2026-02-08)
|
|
891
|
+
> - **"Anonymous checkout opt-in"** (shipped 2026-04-12) · 1 open deferral
|
|
892
|
+
> - **"Payment-method routing"** (shipped 2026-03-22)
|
|
893
|
+
> - **"Session-data persistence"** (shipped 2026-02-08)
|
|
700
894
|
>
|
|
701
895
|
> I factored those into the sub-problems below.
|
|
702
896
|
|
|
897
|
+
(Drop the per-exploration decision count from this listing — recommendations + ship status are the user-facing signals, not decision counts. Keep `· N open deferral{s}` when `deferrals > 0` since open deferrals are scope-warning notes the user cares about. If `deferrals === 0`, just show `(shipped {date})` with no trailing segment.)
|
|
898
|
+
|
|
703
899
|
If `implementationCount === 0`: don't mention the KG check (silent — would just be noise on a cold KG).
|
|
704
900
|
|
|
705
901
|
**[USER PAUSE]** Present as `Problems to solve for`, never as versioned sub-problem headings:
|
|
706
902
|
|
|
707
903
|
```text
|
|
708
904
|
Ritual build
|
|
709
|
-
✓ Context ● Scope ○ Discovery ○ Recommendations ○ Build brief ○ Implementation
|
|
905
|
+
✓ Context ● Scope ○ Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
|
|
710
906
|
|
|
711
907
|
Problems to solve for
|
|
712
908
|
|
|
@@ -730,6 +926,8 @@ Reply with:
|
|
|
730
926
|
|
|
731
927
|
Only the title line gets the number. Put a blank line between candidates. Do not show version labels like `(v1)` in CLI output.
|
|
732
928
|
|
|
929
|
+
**Why `all` is allowed here but NOT in discovery question picking:** sub-problem selection is a SCOPE-LOCKING decision — picking `all` means "the full surfaced scope is what we're solving for," which is a legitimate, declarative choice (often the right one when the agent has surfaced a tight 3-5 sub-problem set). Discovery question picking is INVESTIGATION TRIAGE — picking `all` there is a low-signal "I haven't discriminated yet" answer that pollutes the answer set and weakens readiness scoring. The removal of `all` in Step 7.3 is discovery-specific; don't propagate it backwards to Step 4.
|
|
930
|
+
|
|
733
931
|
##### 4.2 Iteration loop
|
|
734
932
|
|
|
735
933
|
If the user asks for a refinement (anything that isn't "all" / specific picks / "these are good"):
|
|
@@ -788,7 +986,7 @@ References:
|
|
|
788
986
|
Source: {exploration title or id}{ optional ': https://dev.ritualapp.cloud/e/{exploration_id}' if available}
|
|
789
987
|
- {reference}
|
|
790
988
|
|
|
791
|
-
|
|
989
|
+
Reply `use` to use this frame and review discovery questions.
|
|
792
990
|
Or reply with edits, e.g. `tighten`, `broaden`, `focus on outbox`, `drop dashboard`, or `pause`.
|
|
793
991
|
```
|
|
794
992
|
|
|
@@ -796,7 +994,8 @@ Rules:
|
|
|
796
994
|
- Do not show the old versioned scope heading.
|
|
797
995
|
- Do not show `Engineering problem:` as the heading; use `Problem frame`.
|
|
798
996
|
- Do not say `ship it` unless the user used that language first.
|
|
799
|
-
-
|
|
997
|
+
- Visible CTA is `use`. Accept `lock`, `l`, `go`, `continue`, or `next` as aliases for backwards-compat — do NOT display them. Per `references/cli-output-contract.md` § Surface-aware continuation prompts, do NOT treat empty input as proceed inside agent chat.
|
|
998
|
+
- `lock` is demoted to alias only: "lock" sounded final/irrevocable for a frame that's very much iterable; `use` carries the right tone.
|
|
800
999
|
|
|
801
1000
|
##### 5.2 Iteration loop
|
|
802
1001
|
|
|
@@ -815,13 +1014,13 @@ The returned text becomes the new current draft. Show it using the same `Problem
|
|
|
815
1014
|
|
|
816
1015
|
When the user locks the frame, store the final text as `problem_statement` for Step 6.
|
|
817
1016
|
|
|
818
|
-
**Pulse (Step 5 done):** Emit a pulse — feature clarity just jumped. Compute per `/ritual context-pulse` § Step CP3. Render full if this crosses Raw ask → Under-specified, else compact.
|
|
1017
|
+
**Pulse (Step 5 done):** Emit a pulse — feature clarity just jumped. Compute per `/ritual context-pulse` § Step CP3. Render full if this crosses Raw ask → Under-specified, else compact. Translate raw tier labels into user-facing copy per `references/cli-output-contract.md` § Pulse tier labels — never expose `RAW_ASK` / `UNDER_SPECIFIED` / etc. directly.
|
|
819
1018
|
|
|
820
1019
|
#### Step 6 — Create the exploration
|
|
821
1020
|
|
|
822
1021
|
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)`.
|
|
823
1022
|
|
|
824
|
-
Do not add another confirmation if the user just
|
|
1023
|
+
Do not add another confirmation if the user just accepted the problem frame. Create the exploration immediately after the user replies `use`/`proceed`. If a name is ambiguous, **choose the shortest clear noun phrase and continue without pausing** — the name is editable later and shouldn't become a decision gate. Do NOT rely on "proceed on Enter" or empty input in agent chat (see `references/cli-output-contract.md` § Surface-aware continuation prompts).
|
|
825
1024
|
|
|
826
1025
|
User-visible before the call, if needed:
|
|
827
1026
|
|
|
@@ -839,7 +1038,7 @@ Store `exploration_id`. Move the progress header from Scope to Discovery:
|
|
|
839
1038
|
|
|
840
1039
|
```text
|
|
841
1040
|
Ritual build
|
|
842
|
-
✓ Context ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation
|
|
1041
|
+
✓ Context ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
|
|
843
1042
|
|
|
844
1043
|
Exploration created. Track progress at https://dev.ritualapp.cloud/e/{exploration_id}
|
|
845
1044
|
|
|
@@ -892,13 +1091,18 @@ Then summarize the created siblings in the dense-list format. Do not pause after
|
|
|
892
1091
|
|
|
893
1092
|
#### Step 7 — Discovery questions
|
|
894
1093
|
|
|
895
|
-
Longest phase because generation is async + the user picks per-
|
|
1094
|
+
Longest phase because generation is async + the user picks per-Area. (Internally the API field is `matter_id`; user-facing copy always says Area.)
|
|
896
1095
|
|
|
897
1096
|
##### 7.1 — Kick off
|
|
898
1097
|
|
|
899
|
-
Call `mcp__ritual__suggest_discovery_questions(exploration_id)`. Returns immediately with `task_id`. Tell the user:
|
|
1098
|
+
Call `mcp__ritual__suggest_discovery_questions(exploration_id)`. Returns immediately with `task_id`. Tell the user with the full rail (we just entered the Discovery phase):
|
|
900
1099
|
|
|
901
|
-
|
|
1100
|
+
```text
|
|
1101
|
+
Ritual build
|
|
1102
|
+
✓ Context ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
|
|
1103
|
+
|
|
1104
|
+
Generating discovery questions for each area…
|
|
1105
|
+
```
|
|
902
1106
|
|
|
903
1107
|
##### 7.2 — Poll until ready
|
|
904
1108
|
|
|
@@ -907,33 +1111,185 @@ Loop:
|
|
|
907
1111
|
- If `ready: false`, wait 5 seconds, poll again
|
|
908
1112
|
- If `ready: true`, exit loop
|
|
909
1113
|
|
|
910
|
-
Don't poll faster than every 5 seconds. Follow the global polling rule above: single `Bash sleep 5` per iteration and a one-line update every ~3 polls (~15s).
|
|
1114
|
+
Don't poll faster than every 5 seconds. Follow the global polling rule above: single `Bash sleep 5` per iteration and a one-line update every ~3 polls (~15s). Polling heartbeats are exempt from the Build rail rule per `references/cli-output-contract.md` § Build progress anchor — does NOT apply to.
|
|
1115
|
+
|
|
1116
|
+
##### 7.3 — Area-first picker (Areas index → drill into an Area → return to index)
|
|
1117
|
+
|
|
1118
|
+
The state contains `matters[]`, each with `id`, `name`, and `questions[]`. Internally these are `matter`s; user-facing copy ALWAYS calls them **Areas**.
|
|
1119
|
+
|
|
1120
|
+
DO NOT lead with a curated cross-area question list. It reads as the agent having pre-selected the answer and asking the user to rubber-stamp; the user's job at this moment is scanning the space and picking where to spend investigation. Use a two-level picker: Areas index first, then per-Area question detail, then back to the index with status markers.
|
|
1121
|
+
|
|
1122
|
+
###### 7.3.0 — Compute per-Area recommendations + the global shortlist (internal, not user-facing)
|
|
1123
|
+
|
|
1124
|
+
Two computations happen before the index renders. Both stay internal — they show up as counts on the index, not as auto-applied picks.
|
|
1125
|
+
|
|
1126
|
+
**Per-Area recommended counts** (what to suggest when the user drills into an Area):
|
|
1127
|
+
|
|
1128
|
+
- 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.
|
|
1129
|
+
- Area has **< 4 questions**: all are recommended.
|
|
1130
|
+
- Area has **4–7 questions**: top 3 are recommended.
|
|
1131
|
+
- Area has **8+ questions**: top 4 are recommended.
|
|
1132
|
+
|
|
1133
|
+
**Global shortlist** (what `accept shortlist` accepts when used from the index):
|
|
1134
|
+
|
|
1135
|
+
- Pick **6–10 questions TOTAL across all Areas**, biased toward questions most likely to change recommendations.
|
|
1136
|
+
- 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).
|
|
1137
|
+
- Cap at 10 even when the per-Area recommended sets sum to more. The point of the shortlist is to give the user a clean "the highest-signal triage set across the whole space" — picking 24–32 questions because 8 Areas each have 3–4 recommended brings back the "no triage signal" problem under a new name.
|
|
1138
|
+
- If the per-Area recommended sets sum to ≤10, the shortlist IS just the union (no further trimming).
|
|
911
1139
|
|
|
912
|
-
|
|
1140
|
+
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.
|
|
913
1141
|
|
|
914
|
-
|
|
1142
|
+
###### 7.3.1 — Areas index (landing)
|
|
1143
|
+
|
|
1144
|
+
Full rail + intro + numbered Areas list with `{recommended} recommended · {total} total` per Area. NO question text on this screen — just the surface map. This is the first message of the picker; the rail has already been emitted, so subsequent area-detail messages use the in-phase chip.
|
|
915
1145
|
|
|
916
1146
|
```text
|
|
917
|
-
|
|
1147
|
+
Ritual build
|
|
1148
|
+
✓ Context ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
|
|
918
1149
|
|
|
919
|
-
|
|
920
|
-
Choose `all`, numbers like `1,3`, or `skip`.
|
|
1150
|
+
Question picking
|
|
921
1151
|
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
1152
|
+
Ritual generated questions across {N} areas for the {M} locked sub-problems:
|
|
1153
|
+
{first sub-problem name} + {second sub-problem name}.
|
|
1154
|
+
|
|
1155
|
+
Pick an Area to review. I'll show the 3–4 questions most likely to change
|
|
1156
|
+
the implementation plan.
|
|
1157
|
+
|
|
1158
|
+
Areas:
|
|
1159
|
+
|
|
1160
|
+
1. {Area name 1} {N} recommended · {N} total
|
|
1161
|
+
2. {Area name 2} {N} recommended · {N} total
|
|
1162
|
+
3. {Area name 3} {N} recommended · {N} total
|
|
1163
|
+
...
|
|
1164
|
+
|
|
1165
|
+
Reply with an Area number, `accept shortlist`, or `skip discovery`.
|
|
1166
|
+
Inside an Area, use `show more` to see the rest.
|
|
925
1167
|
```
|
|
926
1168
|
|
|
927
|
-
|
|
1169
|
+
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).
|
|
1170
|
+
|
|
1171
|
+
**Why `accept shortlist`, not `accept recommended`:**
|
|
1172
|
+
|
|
1173
|
+
- "Recommended" is ambiguous (recommended per Area? globally? by category? recommended *recs* later in the flow?). The discovery picker uses **shortlist** explicitly because the shortlist is global (6–10 questions across all Areas, computed in § 7.3.0) — distinct from per-Area recommended counts shown alongside each Area, and distinct from the later `accept recommended` action that accepts implementation themes in Step 9.
|
|
1174
|
+
- This creates a clean vocabulary split: **discovery = `accept shortlist`** (questions), **recommendations = `accept recommended`** (themes).
|
|
1175
|
+
|
|
1176
|
+
**Don't advertise global `show all` at the index.** Showing every question across every Area can be a screen-flooding wall. The escape hatch the user actually needs is **`show more` inside an Area** (lazy expansion per Area), not a global dump. Accept `show all` as a reply but don't list it as a visible CTA on the index.
|
|
1177
|
+
|
|
1178
|
+
###### 7.3.2 — Area detail (one Area's questions)
|
|
1179
|
+
|
|
1180
|
+
When the user picks an Area number, show that Area's **top recommended questions** by default. Hold the rest behind `show more`. In-phase chip, NOT full rail (rail was emitted on the index).
|
|
1181
|
+
|
|
1182
|
+
```text
|
|
1183
|
+
Question picking · {Area name}
|
|
1184
|
+
|
|
1185
|
+
Showing {N} recommended questions out of {total}.
|
|
1186
|
+
|
|
1187
|
+
1. {question 1, wrapped readably}
|
|
1188
|
+
|
|
1189
|
+
2. {question 2, wrapped readably}
|
|
1190
|
+
|
|
1191
|
+
3. {question 3, wrapped readably}
|
|
1192
|
+
|
|
1193
|
+
Reply with numbers like `1,2` to pick, `show more` to see all {total},
|
|
1194
|
+
or `skip` to leave this Area without picks.
|
|
1195
|
+
```
|
|
1196
|
+
|
|
1197
|
+
`show more` reveals the rest of the questions, formatted in two groups (Recommended / More):
|
|
1198
|
+
|
|
1199
|
+
```text
|
|
1200
|
+
Question picking · {Area name}
|
|
1201
|
+
|
|
1202
|
+
Recommended:
|
|
1203
|
+
|
|
1204
|
+
1. {recommended question 1}
|
|
1205
|
+
2. {recommended question 2}
|
|
1206
|
+
3. {recommended question 3}
|
|
1207
|
+
|
|
1208
|
+
More questions:
|
|
1209
|
+
|
|
1210
|
+
4. {non-recommended question 1}
|
|
1211
|
+
5. {non-recommended question 2}
|
|
1212
|
+
6. {non-recommended question 3}
|
|
1213
|
+
7. {non-recommended question 4}
|
|
1214
|
+
...
|
|
1215
|
+
|
|
1216
|
+
Reply with numbers like `1,2,5`, or `skip`.
|
|
1217
|
+
```
|
|
1218
|
+
|
|
1219
|
+
###### 7.3.3 — Return to Areas index with status markers
|
|
1220
|
+
|
|
1221
|
+
After the user picks for an Area (or skips), return to the Areas index with status markers reflecting what's been resolved. Use `✓` for picked, `–` for skipped, `□` for not-yet-touched. NEVER use strikethrough — it renders inconsistently across terminals.
|
|
1222
|
+
|
|
1223
|
+
```text
|
|
1224
|
+
Question picking
|
|
1225
|
+
|
|
1226
|
+
Areas:
|
|
1227
|
+
|
|
1228
|
+
✓ 1. {Area name 1} {N} picked
|
|
1229
|
+
□ 2. {Area name 2} {N} recommended · {N} total
|
|
1230
|
+
□ 3. {Area name 3} {N} recommended · {N} total
|
|
1231
|
+
– 4. {Area name 4} skipped
|
|
1232
|
+
...
|
|
1233
|
+
|
|
1234
|
+
Reply with another Area number, or `done` to investigate the {total picked}
|
|
1235
|
+
picked questions. Reply `pause` to stop here.
|
|
1236
|
+
```
|
|
928
1237
|
|
|
929
|
-
|
|
1238
|
+
When EVERY Area has been resolved (picked or skipped), shift the CTA from "another Area number" to:
|
|
930
1239
|
|
|
931
|
-
|
|
1240
|
+
```text
|
|
1241
|
+
All Areas reviewed. Reply `done` to investigate the {total picked}
|
|
1242
|
+
picked questions. Reply `pause` to stop here.
|
|
1243
|
+
```
|
|
1244
|
+
|
|
1245
|
+
###### 7.3.4 — Power paths from the index
|
|
1246
|
+
|
|
1247
|
+
- **`accept shortlist`** (from the index, before picking any Area): accept the 6–10-question global shortlist computed in § 7.3.0. Group those by their owning Area, then call `accept_discovery_questions` once per Area (in parallel per § 7.4) with the shortlisted IDs for that Area. Skip straight to Step 7.4 commit + Step 7.4.5 classification. This is intentionally NOT "top 3–4 of every Area" — that would scale to 24–32 picks on a wide exploration and reintroduce the "no triage signal" problem the area-first picker exists to fix.
|
|
1248
|
+
- `show all` (from the index): accepted as a reply but NOT advertised on the CTA line. Expands into a single long list view across all Areas. Use only when the user explicitly asks — the area-first index is the default.
|
|
1249
|
+
- `skip discovery` (from the index, before any picks): treat ALL Areas as skipped. The classification check in Step 7.4.5 will surface this as a deliberate choice.
|
|
1250
|
+
|
|
1251
|
+
###### 7.3.5 — What NOT to say
|
|
1252
|
+
|
|
1253
|
+
- 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.
|
|
1254
|
+
- DO NOT use `Press Enter` anywhere in this picker (see § Surface-aware continuation prompts).
|
|
1255
|
+
- DO NOT say `lock` for the picking confirmation; use `done` from the index.
|
|
1256
|
+
- DO NOT show full question text in the index — only Area names + counts.
|
|
1257
|
+
|
|
1258
|
+
###### Legacy alias notes
|
|
1259
|
+
|
|
1260
|
+
- `suggest` (legacy per-Area shortcut) is now the implicit per-Area recommendation — the index already shows recommended counts and `accept shortlist` is the global power path. If a user still types `suggest` inside an Area, treat it as "pick the recommended set for this Area."
|
|
1261
|
+
- `accept recommended` (legacy global shortcut): if a user types this, treat it as `accept shortlist`. Surface a one-line note that the discovery-stage token is `accept shortlist` (questions); `accept recommended` is reserved for Step 9's theme acceptance.
|
|
1262
|
+
- `all` (legacy fourth option) remains removed (see § Removed below).
|
|
1263
|
+
|
|
1264
|
+
###### Removed: `all` (the old fourth option)
|
|
1265
|
+
|
|
1266
|
+
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.
|
|
1267
|
+
|
|
1268
|
+
##### 7.4 — Commit picks (one call per Area, dispatched in parallel)
|
|
1269
|
+
|
|
1270
|
+
For each Area where the user picked at least one question, call `mcp__ritual__accept_discovery_questions` with:
|
|
932
1271
|
- `state_id` (from the discovery state)
|
|
933
|
-
- `matter_id`
|
|
934
|
-
- `question_ids[]` (the picks for THIS
|
|
1272
|
+
- `matter_id` (the API field; user-facing this is the Area)
|
|
1273
|
+
- `question_ids[]` (the picks for THIS Area)
|
|
1274
|
+
|
|
1275
|
+
The API enforces per-matter atomicity — there is no cross-matter batch endpoint today (filed as backlog: `accept_discovery_questions_batch`). To minimize wall-clock latency when the user picked across many Areas, **dispatch the per-Area calls in parallel** with `Promise.all` rather than awaiting each one sequentially:
|
|
1276
|
+
|
|
1277
|
+
```ts
|
|
1278
|
+
// Parallel, NOT sequential.
|
|
1279
|
+
await Promise.all(
|
|
1280
|
+
pickedAreas.map((area) =>
|
|
1281
|
+
accept_discovery_questions(state_id, area.matter_id, area.question_ids),
|
|
1282
|
+
),
|
|
1283
|
+
);
|
|
1284
|
+
```
|
|
935
1285
|
|
|
936
|
-
|
|
1286
|
+
User-facing: emit ONE status line for the whole commit, not one per Area:
|
|
1287
|
+
|
|
1288
|
+
```text
|
|
1289
|
+
Saving picks across {N} Areas…
|
|
1290
|
+
```
|
|
1291
|
+
|
|
1292
|
+
If any individual call fails, log the Area name + error inline and continue with the rest — partial success is acceptable here. The next step's classification check will surface anything that didn't land.
|
|
937
1293
|
|
|
938
1294
|
##### 7.4.5 — Classify unpicked areas when the signal warrants it
|
|
939
1295
|
|
|
@@ -946,15 +1302,24 @@ After question picking, check for scope mismatch only when one of these triggers
|
|
|
946
1302
|
|
|
947
1303
|
If no trigger fires, proceed silently to anti-goals.
|
|
948
1304
|
|
|
949
|
-
If a trigger fires, summarize the pattern in plain language and ask the user to classify unpicked areas:
|
|
1305
|
+
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:
|
|
950
1306
|
|
|
951
1307
|
```text
|
|
1308
|
+
Ritual build
|
|
1309
|
+
✓ Context ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
|
|
1310
|
+
|
|
1311
|
+
Scope check
|
|
1312
|
+
|
|
1313
|
+
{One-line summary of which pattern fired — e.g. "You picked 4 of 32 questions, mostly in retention."}
|
|
1314
|
+
|
|
952
1315
|
How should I treat the unpicked areas?
|
|
953
1316
|
|
|
954
|
-
1. Out of scope — tighten the current scope around what you picked.
|
|
955
|
-
2. Later phase — keep the broad scope, but mark unpicked areas as phase-later candidates.
|
|
956
|
-
3. Open questions — keep the broad scope and treat unpicked areas as context debt.
|
|
957
|
-
4. Pick more — return to question picking before continuing.
|
|
1317
|
+
1. Out of scope — tighten the current scope around what you picked.
|
|
1318
|
+
2. Later phase — keep the broad scope, but mark unpicked areas as phase-later candidates.
|
|
1319
|
+
3. Open questions — keep the broad scope and treat unpicked areas as context debt.
|
|
1320
|
+
4. Pick more — return to question picking before continuing.
|
|
1321
|
+
|
|
1322
|
+
Reply with `1`, `2`, `3`, or `4`. Reply `pause` to stop here.
|
|
958
1323
|
```
|
|
959
1324
|
|
|
960
1325
|
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.
|
|
@@ -989,13 +1354,19 @@ The agentic pipeline runs sourcing → answers → recommendations. For engineer
|
|
|
989
1354
|
For `engineering`, `delivery`, and `operations` roles, show:
|
|
990
1355
|
|
|
991
1356
|
```text
|
|
992
|
-
|
|
1357
|
+
Ritual build
|
|
1358
|
+
✓ Context ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
|
|
993
1359
|
|
|
994
|
-
|
|
995
|
-
|
|
1360
|
+
Run discovery
|
|
1361
|
+
|
|
1362
|
+
Ritual will source answers for the picked questions, then generate
|
|
1363
|
+
recommendations. This usually takes a few minutes.
|
|
1364
|
+
|
|
1365
|
+
Reply `run` to continue.
|
|
1366
|
+
Reply `pause` to stop here.
|
|
996
1367
|
```
|
|
997
1368
|
|
|
998
|
-
|
|
1369
|
+
Visible CTA is `run`. Accept `r`, `go`, `continue`, or `next` as aliases. Per `references/cli-output-contract.md` § Surface-aware continuation prompts, do NOT treat empty input as proceed inside agent chat.
|
|
999
1370
|
|
|
1000
1371
|
Call `mcp__ritual__start_agentic_run` with:
|
|
1001
1372
|
- `scope_type: 'exploration'`
|
|
@@ -1004,17 +1375,23 @@ Call `mcp__ritual__start_agentic_run` with:
|
|
|
1004
1375
|
For `product`, `design`, or explicitly PRD-style flows, answer review may be useful. Offer two choices without time estimates:
|
|
1005
1376
|
|
|
1006
1377
|
```text
|
|
1007
|
-
|
|
1378
|
+
Ritual build
|
|
1379
|
+
✓ Context ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
|
|
1380
|
+
|
|
1381
|
+
Run discovery
|
|
1008
1382
|
|
|
1009
|
-
|
|
1010
|
-
2. Run through recommendations — fastest path to a recommendation set.
|
|
1383
|
+
How do you want to run discovery?
|
|
1011
1384
|
|
|
1012
|
-
|
|
1385
|
+
1. Stop after answers — review and refine the generated answers
|
|
1386
|
+
before recommendations.
|
|
1387
|
+
2. Run through recommendations — fastest path to a recommendation set.
|
|
1388
|
+
|
|
1389
|
+
Reply `1` or `2`. Reply `pause` to stop here.
|
|
1013
1390
|
```
|
|
1014
1391
|
|
|
1015
1392
|
If they pick 1, call `start_agentic_run` with `stop_after: 'answers'` and continue to Step 8.5 when it pauses. If they pick 2, call without `stop_after` and continue to Step 9 when complete.
|
|
1016
1393
|
|
|
1017
|
-
Poll `mcp__ritual__get_agentic_run(run_id)` using `references/async-polling.md`:
|
|
1394
|
+
Poll `mcp__ritual__get_agentic_run(run_id)` using `references/async-polling.md`: **`Bash sleep 5` (always 5 — never escalate to 15/20/25)** per iteration, then a fresh status call. Even if the run takes 2+ minutes, the sleep value stays 5; the harness blocks chained-shorter-sleeps-at-increasing-N just like it blocks `sleep ≥ 30`. Agentic runs CAN exceed 5 min for large explorations — if you see status still running past ~5 min of polling, switch to the `Monitor` + `until <check>; do sleep 2; done` pattern from `references/async-polling.md` § Long waits. Print progress only when `progress_pct` or `current_step` changes, or every ~3 polls if unchanged:
|
|
1018
1395
|
|
|
1019
1396
|
> Agentic run: {progress_pct}% — {current_step}
|
|
1020
1397
|
|
|
@@ -1025,11 +1402,58 @@ When `status` is `PAUSED_FOR_REVIEW` (product/design answer-review mode only): c
|
|
|
1025
1402
|
|
|
1026
1403
|
If user wants to abort mid-flight: `mcp__ritual__cancel_agentic_run(run_id)`.
|
|
1027
1404
|
|
|
1028
|
-
#### Step 8.5 —
|
|
1405
|
+
#### Step 8.5 — Run Agentic Exploration (product/design answer-review mode only)
|
|
1406
|
+
|
|
1407
|
+
When the pipeline pauses at `PAUSED_FOR_REVIEW`, the exploration is at step `REVIEWING_ANSWERS`. Every Area's questions have v1 answers + at least one clarifying question per consideration, but nothing has been committed for recommendation generation yet.
|
|
1408
|
+
|
|
1409
|
+
**The agent walks the user through each question one at a time as part of the running agentic exploration.** Render the full rail at the **landing** (the first answer-review message), then use the in-phase chip on subsequent per-question views.
|
|
1410
|
+
|
|
1411
|
+
**On naming:** this step is **Run Agentic Exploration** in user-facing copy and section headings — NOT "Per-answer iteration" (the old internal label). The phase the user is in is "the agentic exploration is running and pausing for your input on each answer before recommendations generate." That's what the heading should say.
|
|
1412
|
+
|
|
1413
|
+
Landing (first question, full rail + intro):
|
|
1414
|
+
|
|
1415
|
+
```text
|
|
1416
|
+
Ritual build
|
|
1417
|
+
✓ Context ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
|
|
1418
|
+
|
|
1419
|
+
Run Agentic Exploration
|
|
1029
1420
|
|
|
1030
|
-
|
|
1421
|
+
Ritual drafted answers for {totalQuestions} questions across {N} Areas.
|
|
1422
|
+
For each question, you can submit the v1 answer or iterate with a
|
|
1423
|
+
follow-up. When all questions are submitted, Ritual generates
|
|
1424
|
+
recommendations.
|
|
1031
1425
|
|
|
1032
|
-
|
|
1426
|
+
────────────────────────────────────────────────────────────────────
|
|
1427
|
+
|
|
1428
|
+
Discovery — question 1 of {total}: {Area name}
|
|
1429
|
+
|
|
1430
|
+
Q: {question.text}
|
|
1431
|
+
|
|
1432
|
+
v1 answer:
|
|
1433
|
+
{currentDraft, first 400 chars …}
|
|
1434
|
+
|
|
1435
|
+
My follow-up: {first consideration's latest assistant message}
|
|
1436
|
+
|
|
1437
|
+
Reply `submit` to lock in v1, or reply with text to iterate.
|
|
1438
|
+
Reply `pause` to stop here.
|
|
1439
|
+
```
|
|
1440
|
+
|
|
1441
|
+
Each subsequent per-question view uses the in-phase chip only (no full rail):
|
|
1442
|
+
|
|
1443
|
+
```text
|
|
1444
|
+
Discovery — question 2 of {total}: {Area name}
|
|
1445
|
+
|
|
1446
|
+
Q: {question.text}
|
|
1447
|
+
|
|
1448
|
+
v1 answer:
|
|
1449
|
+
{...}
|
|
1450
|
+
|
|
1451
|
+
My follow-up: {...}
|
|
1452
|
+
|
|
1453
|
+
Reply `submit` or reply with text to iterate.
|
|
1454
|
+
```
|
|
1455
|
+
|
|
1456
|
+
For each question's loop:
|
|
1033
1457
|
|
|
1034
1458
|
1. **Fetch the state.** Call `mcp__ritual__get_answer_state({ question_id })`. Returns:
|
|
1035
1459
|
- The question text
|
|
@@ -1037,20 +1461,10 @@ When the pipeline pauses at `PAUSED_FOR_REVIEW`, the exploration is at step `REV
|
|
|
1037
1461
|
- The considerations (sub-aspects) with their chat sessions
|
|
1038
1462
|
- The latest assistant message per consideration — this is the **first clarifying question** the answer engine already generated during Phase 3
|
|
1039
1463
|
|
|
1040
|
-
2. **Present
|
|
1464
|
+
2. **Present using the landing-or-chip shape above.** Two choices, that's it (no "skip"):
|
|
1041
1465
|
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
> **Q:** {question.text}
|
|
1045
|
-
>
|
|
1046
|
-
> **v1 answer:**
|
|
1047
|
-
> {currentDraft, first 400 chars …}
|
|
1048
|
-
>
|
|
1049
|
-
> **My follow-up:** {first consideration's latest assistant message}
|
|
1050
|
-
>
|
|
1051
|
-
> Two options:
|
|
1052
|
-
> 1. **submit** — you're happy with v1; lock it in and move to the next question
|
|
1053
|
-
> 2. **iterate** — answer my follow-up OR tell me what's wrong with v1 (free-text). I'll regenerate.
|
|
1466
|
+
- **submit** — happy with v1; lock it in and move to the next question
|
|
1467
|
+
- **iterate** (any free-text reply) — answers the follow-up OR explains what's wrong with v1; the answer engine regenerates
|
|
1054
1468
|
|
|
1055
1469
|
3. **Branch on user's choice:**
|
|
1056
1470
|
|
|
@@ -1072,55 +1486,211 @@ When the pipeline pauses at `PAUSED_FOR_REVIEW`, the exploration is at step `REV
|
|
|
1072
1486
|
|
|
1073
1487
|
**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.
|
|
1074
1488
|
|
|
1075
|
-
#### Step 9 — Review and accept recommendations (role-aware)
|
|
1489
|
+
#### Step 9 — Review and accept recommendations (grouped, role-aware)
|
|
1490
|
+
|
|
1491
|
+
Call `mcp__ritual__get_recommendations(exploration_id)`. Response is an array of recommendations. Each rec includes:
|
|
1076
1492
|
|
|
1077
|
-
|
|
1493
|
+
- top-level: `id`, `title`, `content` (summary), `status`, `priority`, `points`, `confidence`
|
|
1494
|
+
- `metadata.category.name` — **the load-bearing grouping key** (one rec → one category)
|
|
1495
|
+
- `metadata.acceptance_criteria[]` — concrete pass conditions
|
|
1496
|
+
- `metadata.explainability` — `rationale` (chained `→` arrow string), `faq_references[]`, `problem_alignment`, `inferred_elements`, optional `initial_input_analysis`
|
|
1497
|
+
- `metadata.labels[]` — secondary tags
|
|
1078
1498
|
|
|
1079
1499
|
**Role model — load-bearing**: only **admins** can accept recommendations (call `accept_recommendations`). **Collaborators** can read, comment, and proceed to implement, but they cannot move recs from `draft`/`pending_review` to `approved`. Respect this so a collaborator running `/ritual build` doesn't hit a 403 mid-flow and lose context.
|
|
1080
1500
|
|
|
1081
1501
|
If you don't already know the user's role on this workspace, prefer the workspace member endpoint or cached role from `/ritual init`. When unavailable, ask plainly: *"Are you the workspace admin or a collaborator?"* Do not attempt acceptance blindly unless the user explicitly says to accept.
|
|
1082
1502
|
|
|
1083
|
-
|
|
1503
|
+
**Vocabulary**: do NOT use "Reasoning chain" or "reasoning_chain" in user-facing copy. The user-visible label is **"Why this"** — a 4-line Problem / Discovery / Tradeoff / Recommendation breakdown derived from the rationale field. "Reasoning chain" sounds like internal model chain-of-thought; "Why this" is product-native.
|
|
1504
|
+
|
|
1505
|
+
##### 9.1 — Landing screen: grouped category summary + compact scope
|
|
1506
|
+
|
|
1507
|
+
The recommendations review is the most-read screen in the whole build flow. Two design rules:
|
|
1508
|
+
|
|
1509
|
+
1. **Group by `metadata.category.name`.** NEVER show a flat numbered 1..N list. The category is the organizing unit; recommendations are stable `R1..RN` IDs assigned in order of appearance ACROSS categories (top-to-bottom, NOT per-category — so a user can say `detail R7` unambiguously without naming the category).
|
|
1510
|
+
2. **Compact scope reference at top.** Show a single-line compressed version of the problem statement so the user can read recommendations against what they were optimized for. Support `show scope` to expand to full.
|
|
1511
|
+
|
|
1512
|
+
Full rail at the landing (Recommendations stage opens):
|
|
1084
1513
|
|
|
1085
1514
|
```text
|
|
1086
|
-
Ritual
|
|
1515
|
+
Ritual build
|
|
1516
|
+
✓ Context ✓ Scope ✓ Discovery ● Recommendations ○ Build brief ○ Implementation (Your agent)
|
|
1517
|
+
|
|
1518
|
+
Scope:
|
|
1519
|
+
{one-line compressed scope — ~80-120 chars; truncate the full problem
|
|
1520
|
+
statement at a natural clause boundary, no ellipsis}
|
|
1521
|
+
|
|
1522
|
+
Recommendations ready
|
|
1087
1523
|
|
|
1088
|
-
|
|
1089
|
-
Signal: discovery has completed and recommendations now exist for this scope.
|
|
1524
|
+
{N} recommendations across {K} categories.
|
|
1090
1525
|
|
|
1091
|
-
1. {
|
|
1526
|
+
1. {Category 1 name}
|
|
1527
|
+
R1 {title}
|
|
1528
|
+
R2 {title}
|
|
1092
1529
|
|
|
1093
|
-
{
|
|
1530
|
+
2. {Category 2 name}
|
|
1531
|
+
R3 {title}
|
|
1532
|
+
R4 {title}
|
|
1533
|
+
R5 {title}
|
|
1094
1534
|
|
|
1095
|
-
|
|
1535
|
+
3. {Category 3 name}
|
|
1536
|
+
R6 {title}
|
|
1096
1537
|
|
|
1097
|
-
|
|
1538
|
+
...
|
|
1539
|
+
|
|
1540
|
+
Pulse: Reasoning Readiness ~88% · Context Debt 12% · +26% (implementation-ready)
|
|
1541
|
+
|
|
1542
|
+
Recommended: reply `accept recommended` to approve these {N} and generate
|
|
1543
|
+
the build brief.
|
|
1098
1544
|
|
|
1099
|
-
|
|
1545
|
+
Or reply `detail R7`, `change R3: <edit>`, `drop R8`, `add <topic>`, or `hold`.
|
|
1100
1546
|
```
|
|
1101
1547
|
|
|
1102
|
-
|
|
1548
|
+
Notes:
|
|
1549
|
+
|
|
1550
|
+
- **Categories are numbered `1..K`** (their position on the page). **Recommendations get stable `R1..RN` IDs** across the whole set. The numbering is for reading orientation; the user references recs by `R{N}`, not by category number.
|
|
1551
|
+
- **One blank line between categories**; titles indent at 3 spaces (so the eye lands on the category name first, then the R-IDs scan down).
|
|
1552
|
+
- **Pulse uses full labels** per `references/cli-output-contract.md` § Pulse tier labels.
|
|
1553
|
+
- **`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.
|
|
1554
|
+
- **`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). 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."
|
|
1555
|
+
|
|
1556
|
+
##### 9.2 — `show scope` handling
|
|
1103
1557
|
|
|
1104
|
-
|
|
1558
|
+
When the user replies `show scope`, expand to the full problem statement (no rail repetition — this is a sub-view inside the same phase, use the in-phase chip):
|
|
1105
1559
|
|
|
1106
|
-
|
|
1560
|
+
```text
|
|
1561
|
+
Recommendations · Scope (full)
|
|
1562
|
+
|
|
1563
|
+
{full problemStatement, wrapped at terminal width}
|
|
1564
|
+
|
|
1565
|
+
Reply `back` to return to the recommendations list, or any of the regular
|
|
1566
|
+
recommendation actions.
|
|
1567
|
+
```
|
|
1107
1568
|
|
|
1108
|
-
|
|
1109
|
-
|
|
1569
|
+
##### 9.3 — Detail card (when user replies `detail R{N}`)
|
|
1570
|
+
|
|
1571
|
+
In-phase chip + focused single-rec card. Use the LABELED-BLOCK shape per `references/cli-output-contract.md` § Dense list format. The "Why this" block REPLACES the `rationale` chained-arrow string — render it as 4 named lines, not the literal `Problem → Discovery → Tradeoff → Recommendation` arrow chain (which is the LLM's internal scratchpad shape, not user-facing).
|
|
1572
|
+
|
|
1573
|
+
```text
|
|
1574
|
+
Recommendations — R7
|
|
1575
|
+
|
|
1576
|
+
R7. {title}
|
|
1577
|
+
|
|
1578
|
+
Category:
|
|
1579
|
+
{metadata.category.name}
|
|
1580
|
+
|
|
1581
|
+
Recommendation:
|
|
1582
|
+
{content — direct, actionable summary; 2-4 sentences}
|
|
1583
|
+
|
|
1584
|
+
Why this:
|
|
1585
|
+
- Problem: {one-line distillation from metadata.explainability.problem_alignment}
|
|
1586
|
+
- Discovery: {one-line distillation from metadata.explainability.faq_references[0].insight}
|
|
1587
|
+
- Tradeoff: {one-line distillation from rationale's "Tradeoffs (...)" segment}
|
|
1588
|
+
- Recommendation: {one-line distillation from rationale's "Recommendation (...)" segment}
|
|
1589
|
+
|
|
1590
|
+
Tactics:
|
|
1591
|
+
- {short imperative — derived from metadata.acceptance_criteria where actionable}
|
|
1592
|
+
- {short imperative}
|
|
1593
|
+
- {short imperative}
|
|
1594
|
+
|
|
1595
|
+
Acceptance criteria:
|
|
1596
|
+
- {metadata.acceptance_criteria[0]}
|
|
1597
|
+
- {metadata.acceptance_criteria[1]}
|
|
1598
|
+
- {metadata.acceptance_criteria[N]}
|
|
1599
|
+
|
|
1600
|
+
References:
|
|
1601
|
+
- {file path or RB id from metadata.explainability.faq_references / referenced_faq_ids}
|
|
1602
|
+
- {reference}
|
|
1603
|
+
|
|
1604
|
+
Reply `drop R7`, `change R7: <edit>`, or `back`.
|
|
1605
|
+
|
|
1606
|
+
To move forward, reply `accept recommended` from the summary.
|
|
1607
|
+
If you only want a subset, `drop` the recs you don't want first, then `accept recommended`.
|
|
1608
|
+
```
|
|
1609
|
+
|
|
1610
|
+
Notes on the detail card:
|
|
1611
|
+
|
|
1612
|
+
- **Single-rec accept is NOT a visible CTA here** — the SKILL deliberately omits `accept R7`. The backing API only supports accept-all (`accept_recommendations`) today; surfacing `accept R7` would teach the user a command the system can't fulfill. When a single-rec accept endpoint lands (see backlog), re-introduce it here.
|
|
1613
|
+
- 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.
|
|
1614
|
+
- `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").
|
|
1615
|
+
- `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).
|
|
1616
|
+
- `back` returns to the landing summary, NOT to a new fetch — the agent should cache the recs from the landing call and re-render.
|
|
1617
|
+
|
|
1618
|
+
##### 9.4 — Action handling
|
|
1619
|
+
|
|
1620
|
+
Visible CTAs in 9.1 / 9.3 map to MCP/API actions. Some are direct, some require interpretation. The agent maps free-text replies to these actions:
|
|
1621
|
+
|
|
1622
|
+
| User reply | Action | Backing call |
|
|
1623
|
+
|---|---|---|
|
|
1624
|
+
| `accept recommended` | Accept ALL recs currently on screen | `mcp__ritual__accept_recommendations(exploration_id)` (admin only — see Branch B) |
|
|
1625
|
+
| `detail R{N}` | Render the detail card for that rec | None (in-memory) |
|
|
1626
|
+
| `accept R{N}` (from detail) | Mark that single rec approved | **No direct single-rec API today — NOT shown as a visible CTA.** If user types it anyway, explain: "I can accept all 11 now via `accept recommended`, or you can `drop` the ones you don't want first." See backlog. |
|
|
1627
|
+
| `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 |
|
|
1628
|
+
| `drop R{N}` | Mark that rec rejected | `update_recommendation` with status=rejected, OR add a "deliberately excluded" note for the brief generator |
|
|
1629
|
+
| `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 |
|
|
1630
|
+
| `show scope` | Expand the scope reference | None (in-memory) |
|
|
1631
|
+
| `hold` | Stop here without accepting | None (exits the flow; user can resume later) |
|
|
1632
|
+
|
|
1633
|
+
Don't display all aliases. Display the four most-likely-needed: `accept recommended`, `detail R{N}`, `drop R{N}`, `hold`. Show `change R{N}: <edit>` and `add <topic>` in the detail card or as a one-line hint when the landing screen is presented for the second time (the user knows the basics by then).
|
|
1634
|
+
|
|
1635
|
+
**Backlog notes** (referenced for the agent so it doesn't over-promise):
|
|
1636
|
+
- Single-rec `accept R7` from the detail card doesn't have a direct API endpoint — today the user can either accept ALL or none. Surface this honestly: "I can accept all 11 now, or you can drop the ones you don't want and then accept the rest."
|
|
1637
|
+
- `add <topic>` requires a regenerate with a pinned topic — that's a forthcoming `regenerate_recommendation` improvement; until then it's a full regeneration cycle.
|
|
1638
|
+
|
|
1639
|
+
##### 9.A — Branch A: admin replies `accept recommended`
|
|
1640
|
+
|
|
1641
|
+
Call `mcp__ritual__accept_recommendations(exploration_id)`. Response includes counts (`promoted`, `alreadyApproved`, `skipped`, `transitionedToComplete`). Show the full rail at this completion state — Recommendations is done, Build brief comes next:
|
|
1642
|
+
|
|
1643
|
+
```text
|
|
1644
|
+
Ritual build
|
|
1645
|
+
✓ Context ✓ Scope ✓ Discovery ✓ Recommendations ● Build brief ○ Implementation (Your agent)
|
|
1646
|
+
|
|
1647
|
+
Accepted {N} recommendations.
|
|
1648
|
+
|
|
1649
|
+
View: https://dev.ritualapp.cloud/e/{exploration_id}
|
|
1650
|
+
|
|
1651
|
+
Next: generating the build brief…
|
|
1652
|
+
```
|
|
1110
1653
|
|
|
1111
1654
|
**Pulse (recommendations accepted):** Emit a pulse — this is almost always a state-tier crossing into **Recommendation-ready**. Render full.
|
|
1112
1655
|
|
|
1113
|
-
Continue to Step 9.5.
|
|
1656
|
+
Continue to Step 9.5 (`Wait for requirements`).
|
|
1114
1657
|
|
|
1115
|
-
|
|
1658
|
+
##### 9.B — Branch B: user is a collaborator (no admin acceptance available)
|
|
1116
1659
|
|
|
1117
|
-
|
|
1660
|
+
Same landing screen as 9.1, but the action block changes — collaborators can request admin review instead of accepting directly:
|
|
1118
1661
|
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1662
|
+
```text
|
|
1663
|
+
Ritual build
|
|
1664
|
+
✓ Context ✓ Scope ✓ Discovery ● Recommendations ○ Build brief ○ Implementation (Your agent)
|
|
1665
|
+
|
|
1666
|
+
Scope:
|
|
1667
|
+
{compact scope}
|
|
1668
|
+
|
|
1669
|
+
Admin acceptance pending
|
|
1670
|
+
|
|
1671
|
+
These recommendations are in {status — draft / pending_review}. Only an
|
|
1672
|
+
admin can formally accept them.
|
|
1673
|
+
|
|
1674
|
+
1. {Category 1}
|
|
1675
|
+
R1 {title}
|
|
1676
|
+
R2 {title}
|
|
1677
|
+
|
|
1678
|
+
...
|
|
1679
|
+
|
|
1680
|
+
Recommended: reply `request admin review` to send these for approval.
|
|
1681
|
+
Or reply `detail R7`, `change R3: <edit>`, `drop R8`, or `hold`.
|
|
1682
|
+
|
|
1683
|
+
(If your team allows it, you can continue to implementation before admin
|
|
1684
|
+
acceptance — Ritual will mark the exploration as `implemented_ahead` so
|
|
1685
|
+
the admin can reconcile later. Reply `continue` to take that path.)
|
|
1686
|
+
```
|
|
1687
|
+
|
|
1688
|
+
Note the THREE-tier CTA structure for collaborators:
|
|
1689
|
+
1. `request admin review` — the recommended path (notifies admin, no implementation yet)
|
|
1690
|
+
2. `continue` — implement-ahead-of-acceptance (logs as `implemented_ahead`; admin can reconcile later)
|
|
1691
|
+
3. `hold` — stop entirely
|
|
1692
|
+
|
|
1693
|
+
The `request admin review` action maps to the workspace notification endpoint (or falls back to a Slack/email DM the agent surfaces as a copyable message). The `implemented_ahead` path is documented in Step 11 / 12.
|
|
1124
1694
|
|
|
1125
1695
|
If the user picks `continue`, proceed to Step 9.5. The `sync_implementation` call in Step 12 will automatically snapshot the rec status via the A1.5 column.
|
|
1126
1696
|
|
|
@@ -1145,8 +1715,9 @@ Steps:
|
|
|
1145
1715
|
```
|
|
1146
1716
|
|
|
1147
1717
|
Polling rules in this harness:
|
|
1148
|
-
-
|
|
1718
|
+
- **`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.
|
|
1149
1719
|
- **Update the user every ~3 polls** with a "still generating…" line so they know you haven't stalled.
|
|
1720
|
+
- If polling crosses ~5 minutes, switch to the `Monitor` + `until <check>; do sleep 2; done` pattern from `references/async-polling.md` § Long waits.
|
|
1150
1721
|
|
|
1151
1722
|
3. **Exit conditions:**
|
|
1152
1723
|
|
|
@@ -1265,15 +1836,29 @@ When the brief content is in hand (from generate OR polling), **don't dump 300 l
|
|
|
1265
1836
|
|
|
1266
1837
|
##### 10d — Confirm and proceed (CLI Tenet #2, #12)
|
|
1267
1838
|
|
|
1268
|
-
End Step 10 with a single recommended action plus a cheap escape hatch — never a 3-way option bloom.
|
|
1839
|
+
End Step 10 with a single recommended action plus a cheap escape hatch — never a 3-way option bloom. Full rail (this is a decision gate that closes the Build brief phase):
|
|
1840
|
+
|
|
1841
|
+
```text
|
|
1842
|
+
Ritual build
|
|
1843
|
+
✓ Context ✓ Scope ✓ Discovery ✓ Recommendations ● Build brief ○ Implementation (Your agent)
|
|
1269
1844
|
|
|
1270
|
-
|
|
1845
|
+
Build brief ready
|
|
1846
|
+
|
|
1847
|
+
`BUILD-BRIEF.md` is on disk. Skim the RBs + anchors, then decide:
|
|
1848
|
+
|
|
1849
|
+
· `go` — ready to implement; move to coding
|
|
1850
|
+
· `refine` — something's off; tell me what and I'll regenerate
|
|
1851
|
+
· `drill {N}` — drill into RB-{N} before deciding
|
|
1852
|
+
|
|
1853
|
+
Reply `pause` to stop here.
|
|
1854
|
+
```
|
|
1271
1855
|
|
|
1272
|
-
Branch by user response:
|
|
1856
|
+
Branch by user response. Accept `go`, `y`, `yes`, `proceed`, `continue`, `next` as the visible-CTA path (do not display all aliases):
|
|
1273
1857
|
|
|
1274
|
-
-
|
|
1275
|
-
-
|
|
1276
|
-
-
|
|
1858
|
+
- **`go` / proceed / yes / y**: continue to Step 11.
|
|
1859
|
+
- **`refine`**: ask what's off, then call `generate_build_brief` with `force: true` after applying their feedback to the exploration (typically a recommendation re-accept or a requirement adjustment via the web UI).
|
|
1860
|
+
- **`drill {N}`**: open RB-{N} in the markdown, discuss inline, then loop back to the gate above.
|
|
1861
|
+
- **`pause`**: stop here. The brief is on disk; the user can resume with `/ritual resume`.
|
|
1277
1862
|
|
|
1278
1863
|
**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.
|
|
1279
1864
|
|
|
@@ -1281,6 +1866,21 @@ Branch by user response:
|
|
|
1281
1866
|
|
|
1282
1867
|
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.
|
|
1283
1868
|
|
|
1869
|
+
The Implementation phase landing — full rail (the rail moves to Implementation for the first time):
|
|
1870
|
+
|
|
1871
|
+
```text
|
|
1872
|
+
Ritual build
|
|
1873
|
+
✓ Context ✓ Scope ✓ Discovery ✓ Recommendations ✓ Build brief ● Implementation (Your agent)
|
|
1874
|
+
|
|
1875
|
+
Implementation (Your agent)
|
|
1876
|
+
|
|
1877
|
+
The build brief is on disk. From here, your agent codes against the
|
|
1878
|
+
RB list. Ritual will track commits via the `Ritual-Exploration:` trailer
|
|
1879
|
+
so they link back to this exploration when you sync.
|
|
1880
|
+
|
|
1881
|
+
Next: I'll create a feature branch, then start on RB-1.
|
|
1882
|
+
```
|
|
1883
|
+
|
|
1284
1884
|
##### 11.0 — Branch strategy (CLI Tenet #13)
|
|
1285
1885
|
|
|
1286
1886
|
**Never commit to `main` / `master` from an agent workflow.** Before writing a single line of code:
|
|
@@ -1338,7 +1938,7 @@ Intermediate commits can skip the footer. The final commit IS the linkage anchor
|
|
|
1338
1938
|
**Don't dump a per-file changelog into the chat.** The full diff lives in `git diff <branch>..HEAD` and the eventual PR body. The CLI summary should be **≤ 8 lines** and surface only what's load-bearing for the user's next decision:
|
|
1339
1939
|
|
|
1340
1940
|
```
|
|
1341
|
-
✓ Implementation done — {exploration name}
|
|
1941
|
+
✓ Implementation done (your agent) — {exploration name}
|
|
1342
1942
|
Branch: {branch}, {N} commits, {M} files changed
|
|
1343
1943
|
Tests: {tests_added} added, all passing
|
|
1344
1944
|
RBs satisfied: {comma-joined list of RB-N from the brief, ALL or a count}
|
|
@@ -1395,16 +1995,29 @@ If the user is implementing manually: hand off the brief + the branch-strategy n
|
|
|
1395
1995
|
|
|
1396
1996
|
##### 12.0 — What this step does (in product terms)
|
|
1397
1997
|
|
|
1398
|
-
Before asking for permission, frame the call in language the user can act on. `sync_implementation` is not just an API call — it's the moment the workspace's knowledge graph absorbs what you just shipped.
|
|
1998
|
+
Before asking for permission, frame the call in language the user can act on. `sync_implementation` is not just an API call — it's the moment the workspace's knowledge graph absorbs what you just shipped. Full rail (this is a top-level decision gate that ends the build flow):
|
|
1399
1999
|
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
> **OK to log? (y / hold off / let me adjust the decision list first)**
|
|
2000
|
+
```text
|
|
2001
|
+
Ritual build
|
|
2002
|
+
✓ Context ✓ Scope ✓ Discovery ✓ Recommendations ✓ Build brief ● Implementation (Your agent)
|
|
2003
|
+
|
|
2004
|
+
Log implementation
|
|
1406
2005
|
|
|
1407
|
-
|
|
2006
|
+
I'm about to log this implementation into the workspace's knowledge graph. After this:
|
|
2007
|
+
|
|
2008
|
+
· The exploration's state flips to ✓ done (or ⚠ implemented-ahead if
|
|
2009
|
+
any recs weren't approved when shipped).
|
|
2010
|
+
· The implementation gets linked back to the recommendations it
|
|
2011
|
+
implements — so future `/ritual build` calls touching
|
|
2012
|
+
`{first 2 of filesChanged}` will see this implementation as priorContext.
|
|
2013
|
+
· The {M} open deferrals you intentionally punted get logged with
|
|
2014
|
+
their reasons — peers can see them in `/ritual lineage` on these
|
|
2015
|
+
files later.
|
|
2016
|
+
|
|
2017
|
+
Reply `log` to confirm, `hold off`, or `adjust` to edit the list first.
|
|
2018
|
+
```
|
|
2019
|
+
|
|
2020
|
+
This framing replaces "I need to call sync_implementation, OK?" — which is jargon. The user should know what they're approving in product terms (CLI Tenet #4 — cite the specific signal). Note the vocabulary rule in `cli-output-contract.md` — do not surface "decisions" / "{N} decisions" as a user-facing label here; frame the moment as logging the **implementation** itself.
|
|
1408
2021
|
|
|
1409
2022
|
##### 12.1 — Make the call
|
|
1410
2023
|
|
|
@@ -1425,30 +2038,105 @@ When sync_implementation succeeds, the response includes:
|
|
|
1425
2038
|
- `decisionsCount`, `deferralsCount` — totals for the summary line
|
|
1426
2039
|
- `webUrl` — clickable link to the exploration's implementation record in the web UI
|
|
1427
2040
|
|
|
1428
|
-
**Surface ALL of this to the user**, not just "ok logged." This is the visible signal that the loop closed.
|
|
2041
|
+
**Surface ALL of this to the user**, not just "ok logged." This is the visible signal that the loop closed. Full rail (this is the completion state for the whole `/ritual build` flow):
|
|
1429
2042
|
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
2043
|
+
```text
|
|
2044
|
+
Ritual build
|
|
2045
|
+
✓ Context ✓ Scope ✓ Discovery ✓ Recommendations ✓ Build brief ✓ Implementation (Your agent)
|
|
2046
|
+
|
|
2047
|
+
✓ Logged implementation for {exploration name}
|
|
2048
|
+
|
|
2049
|
+
· Implemented: {first 2 area:choice pairs from decisions[],
|
|
2050
|
+
e.g. "auth: OAuth not SAML; data-model: tenant-scoped indexes"}
|
|
2051
|
+
· {deferralsCount} deferral{s} registered: {first 1, e.g. "[major]
|
|
2052
|
+
Rate-limit per-tenant — out of scope for v1"}
|
|
2053
|
+
· View: {webUrl}
|
|
1436
2054
|
|
|
1437
|
-
|
|
2055
|
+
Future `/ritual build` calls touching `{first 2 of filesChanged}` will
|
|
2056
|
+
now see this implementation in their priorContext block.
|
|
2057
|
+
|
|
2058
|
+
Next: nothing required — the loop is closed. Run `/ritual lineage` on
|
|
2059
|
+
any touched file to trace this back later.
|
|
2060
|
+
```
|
|
1438
2061
|
|
|
1439
|
-
|
|
2062
|
+
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.
|
|
2063
|
+
|
|
2064
|
+
If any anchor's `recommendationStatusAtImplementation` is NOT `approved` (i.e. the Branch B path), add a callout — still frame in implementation/recommendation terms. Append this block BELOW the completion message (no separate rail; the rail is already rendered at the top):
|
|
2065
|
+
|
|
2066
|
+
```text
|
|
2067
|
+
⚠ {M} of the recommendations were implemented while still in {status}
|
|
2068
|
+
state — the exploration now shows `implemented_ahead`. An admin should
|
|
2069
|
+
review + accept the recs to close the gap.
|
|
2070
|
+
```
|
|
1440
2071
|
|
|
1441
2072
|
The closing sentence is the most important one: it tells the user **what just happened in the system** in product-level terms. Without it, sync_implementation feels like a write-only black hole. With it, the user understands they just contributed to the workspace's memory.
|
|
1442
2073
|
|
|
1443
2074
|
**If `sync_implementation` fails:** do not drop the structured implementation data. Write the intended payload to `.ritual/pending-sync/<exploration-id>.json` and tell the user exactly what was not logged.
|
|
1444
2075
|
|
|
1445
|
-
User-visible:
|
|
2076
|
+
User-visible (full rail — sync failure is a top-level state):
|
|
2077
|
+
|
|
2078
|
+
```text
|
|
2079
|
+
Ritual build
|
|
2080
|
+
✓ Context ✓ Scope ✓ Discovery ✓ Recommendations ✓ Build brief ● Implementation (Your agent)
|
|
2081
|
+
|
|
2082
|
+
Sync failed (recoverable)
|
|
2083
|
+
|
|
2084
|
+
`sync_implementation` failed: {error summary}
|
|
2085
|
+
|
|
2086
|
+
Saved the intended sync payload to `.ritual/pending-sync/<exploration-id>.json`.
|
|
2087
|
+
Nothing about your implementation was lost — the failure is on the
|
|
2088
|
+
logging side, not the code side.
|
|
2089
|
+
|
|
2090
|
+
Next: run `/ritual resume` later to see + retry pending syncs, or
|
|
2091
|
+
re-run `sync_implementation` now if the cause was transient.
|
|
2092
|
+
```
|
|
2093
|
+
|
|
2094
|
+
Create `.ritual/pending-sync/` if needed. **Ensure the directory is gitignored** — the saved payload contains `decisions[].rationale` text the user typed and commit-level data that shouldn't end up in shared repo history. On the first failed sync, also write `.ritual/pending-sync/.gitignore` with `*` so the directory itself is committed but its contents aren't (gives teammates the breadcrumb that pending syncs exist without leaking contents):
|
|
2095
|
+
|
|
2096
|
+
```bash
|
|
2097
|
+
mkdir -p .ritual/pending-sync
|
|
2098
|
+
[ -f .ritual/pending-sync/.gitignore ] || echo '*' > .ritual/pending-sync/.gitignore
|
|
2099
|
+
[ -f .ritual/pending-sync/.gitignore ] && ! grep -q '^!\.gitignore$' .ritual/pending-sync/.gitignore && echo '!.gitignore' >> .ritual/pending-sync/.gitignore
|
|
2100
|
+
```
|
|
2101
|
+
|
|
2102
|
+
That two-line `.gitignore` (`*` then `!.gitignore`) follows the standard pattern: ignore everything in this directory EXCEPT the gitignore file itself. Most teams already use this idiom for `.cache/`, `node_modules/`, etc.
|
|
2103
|
+
|
|
2104
|
+
##### 12.2 — Staleness check before retry
|
|
2105
|
+
|
|
2106
|
+
When retrying a pending sync from `.ritual/pending-sync/<id>.json`, the user may have committed more code since the failure. The saved payload's `commits[]` is a frozen snapshot — re-uploading it after additional commits land would mis-attribute the new work as "not part of this exploration."
|
|
2107
|
+
|
|
2108
|
+
Before re-invoking `sync_implementation` on a saved payload:
|
|
2109
|
+
|
|
2110
|
+
1. Read the payload's `commits[]` (each has a `sha`).
|
|
2111
|
+
2. Run `git log --pretty=format:%H` against the payload's `branch`.
|
|
2112
|
+
3. Compare: if there are commit SHAs in `git log` that AREN'T in the payload's `commits[]`, the payload is stale.
|
|
2113
|
+
|
|
2114
|
+
If stale, surface to the user with the full rail (top-level decision gate):
|
|
2115
|
+
|
|
2116
|
+
```text
|
|
2117
|
+
Ritual build
|
|
2118
|
+
✓ Context ✓ Scope ✓ Discovery ✓ Recommendations ✓ Build brief ● Implementation (Your agent)
|
|
2119
|
+
|
|
2120
|
+
Pending sync is stale
|
|
2121
|
+
|
|
2122
|
+
This pending sync was saved {N} day(s) ago. Since then you've added
|
|
2123
|
+
{M} more commit(s) to `{branch}` that aren't in the saved payload.
|
|
2124
|
+
Retrying as-is would log a partial picture — the work done since the
|
|
2125
|
+
failure would NOT be attributed to this exploration.
|
|
2126
|
+
|
|
2127
|
+
Options:
|
|
2128
|
+
|
|
2129
|
+
1. Retry as-is — log what was saved; you can sync the new commits later.
|
|
2130
|
+
2. Regenerate — re-run from scratch with the current state. This is
|
|
2131
|
+
usually right when there's been substantive work since the failure.
|
|
2132
|
+
3. Show me — print the {M} new commits so I can decide.
|
|
2133
|
+
|
|
2134
|
+
Reply `1`, `2`, or `3`. Reply `pause` to stop here.
|
|
2135
|
+
```
|
|
1446
2136
|
|
|
1447
|
-
|
|
1448
|
-
> Saved the intended sync payload to `.ritual/pending-sync/<exploration-id>.json`.
|
|
1449
|
-
> Retry later with the same payload; no implementation decisions were lost.
|
|
2137
|
+
**[USER PAUSE — required, do not auto-answer]** Wait for response. Option 2 is usually right when there's been substantive work; option 1 is fine for small follow-up commits the user wants attributed to the next sync.
|
|
1450
2138
|
|
|
1451
|
-
|
|
2139
|
+
If the saved payload's `commits[]` matches current git state, proceed silently to the retry.
|
|
1452
2140
|
|
|
1453
2141
|
#### Step 13 — Optional follow-up
|
|
1454
2142
|
|