@ritualai/cli 0.7.8 → 0.7.9

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.
@@ -39,12 +39,63 @@ When **not** to use:
39
39
 
40
40
  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
41
 
42
+ **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.
43
+
42
44
  ---
43
45
 
44
46
  ### CLI and async guardrails
45
47
 
46
48
  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
49
 
50
+ #### Step 0 — Permission mode check (pre-flight)
51
+
52
+ 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.
53
+
54
+ 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.
55
+
56
+ How to detect (per-agent):
57
+
58
+ | Agent | Indicator |
59
+ |---|---|
60
+ | **Claude Code** | TUI footer shows `auto-accept edits` or `bypass permissions`. Toggled with **Shift+Tab**. |
61
+ | **Cursor** | "Auto" / "Yolo" toggle in the Composer/Agent panel. |
62
+ | **Codex** | `--full-auto` CLI flag or the equivalent setting in the IDE extension. |
63
+ | **Kiro** | Per-server `autoApprove[]` arrays in `mcp.json`, plus any global "auto" toggle in the Agent panel. |
64
+ | **Windsurf / VS Code Copilot / Gemini CLI** | Each has its own auto-accept mode in settings. |
65
+
66
+ 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.
67
+
68
+ **If auto-mode is on (or you're uncertain), surface this before Step 1:**
69
+
70
+ ```text
71
+ Heads up — looks like your coding agent is in auto-mode for this session.
72
+
73
+ Ritual's build flow needs ~5 real decisions from you across the next
74
+ 20–30 minutes:
75
+ · which workspace to use
76
+ · how to scope the problem
77
+ · which discovery questions matter for your case
78
+ · which recommendations to accept
79
+ · whether the build brief is ready to implement
80
+
81
+ Auto-mode tends to speed past these. The output will look like a
82
+ normal Ritual exploration but won't actually reflect your input —
83
+ the recommendations will be plausible-but-not-yours.
84
+
85
+ ──────────────────────────────────────────────────────────────────
86
+ Recommended: turn off auto-mode before continuing.
87
+ · Claude Code: Shift+Tab to cycle back to "default"
88
+ · Other agents: see your agent's settings or CLI flag
89
+ ──────────────────────────────────────────────────────────────────
90
+
91
+ 1. Pause — I'll turn off auto-mode, then say "go"
92
+ 2. Continue anyway (I want speed over alignment for this run)
93
+ ```
94
+
95
+ **[USER PAUSE — required, do not auto-answer]** Wait for an actual user message before proceeding.
96
+
97
+ 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.
98
+
48
99
  #### Step 1
49
100
  #### Step 1 — Pick a workspace
50
101
 
@@ -102,7 +153,7 @@ If there are **zero existing explorations** and `raw_input = null`, do not say "
102
153
 
103
154
  ```text
104
155
  Ritual build
105
- ● Context ○ Scope ○ Discovery ○ Recommendations ○ Build brief ○ Implementation
156
+ ● Context ○ Scope ○ Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
106
157
 
107
158
  Using workspace: {workspaceName}.
108
159
 
@@ -137,7 +188,7 @@ Steps:
137
188
  >
138
189
  > **{state_glyph} {state_label}**
139
190
  > - **{name}** — {short scope summary, first 80 chars of problemStatement}
140
- > - {recommendationCount} rec{s} ({accepted}/{total} approved), {decisionsCount} decision{s} logged, {openDeferralsCount} open deferral{s}
191
+ > - {recommendationCount} rec{s} ({accepted}/{total} approved{implementationSegment}), {openDeferralsCount} open deferral{s}
141
192
  > - {state-specific call-to-action — see table below}
142
193
  >
143
194
  > Recommended: resume one if it matches this work.
@@ -149,7 +200,7 @@ Steps:
149
200
  >
150
201
  > **{state_glyph} {state_label}**
151
202
  > - **{name}** — {short scope summary, first 80 chars of problemStatement}
152
- > - {recommendationCount} rec{s} ({accepted}/{total} approved), {decisionsCount} decision{s} logged, {openDeferralsCount} open deferral{s}
203
+ > - {recommendationCount} rec{s} ({accepted}/{total} approved{implementationSegment}), {openDeferralsCount} open deferral{s}
153
204
  > - {state-specific call-to-action — see table below}
154
205
  >
155
206
  > Reply with:
@@ -158,6 +209,20 @@ Steps:
158
209
  > - a feature/problem description to start fresh
159
210
  > - `none` to exit
160
211
 
212
+ **`{implementationSegment}` resolution rule** — derive from `implementationStatus.implementationRecord` on the listing response:
213
+
214
+ | Condition | Render |
215
+ |---|---|
216
+ | No `ImplementationRecord` | `` (empty — drop the segment) |
217
+ | Has record but `prUrl` is null | ` · synced (no PR linked)` |
218
+ | `prStatus = merged` | ` · implemented in PR #{prNumber}` |
219
+ | `prStatus = open` or `draft` | ` · implementing in PR #{prNumber} [{prStatus}]` |
220
+ | `prStatus = closed` (not merged) | ` · abandoned (PR #{prNumber} closed)` |
221
+
222
+ In markdown-rendering agents, hyperlink `PR #{prNumber}` to `prUrl` so users can click through. In plaintext agents, append `prUrl` on the next line.
223
+
224
+ **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.
225
+
161
226
  State badge → user-facing label + call-to-action:
162
227
 
163
228
  | Glyph | State | User-facing label | Suggested next action |
@@ -427,7 +492,7 @@ If a `CONTEXT-<slug>.md` is found AND its `## The ask` section close-matches the
427
492
  - **Surface a compact note**:
428
493
  > Code recon
429
494
  > Found `CONTEXT-<slug>.md` from `/ritual context-pulse`.
430
- > Using {N} candidate files + {M} prior KG decisions as the recon base. Override with `recon: refresh`.
495
+ > Using {N} candidate files + {M} related prior exploration{s} as the recon base. Override with `recon: refresh`.
431
496
  - Proceed directly to 3.2.
432
497
 
433
498
  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.
@@ -691,22 +756,24 @@ LLM call, ~5–10s. Returns 5–6 sub-problems — different framing axes the sy
691
756
 
692
757
  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
758
 
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 team decisions shaped this draft.
759
+ **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
760
 
696
761
  > Reading the codebase I overlapped with 3 prior Ritual explorations on these files:
697
- > - **"Anonymous checkout opt-in"** (shipped 2026-04-12) 2 decisions, 1 deferral
698
- > - **"Payment-method routing"** (shipped 2026-03-22) — 4 decisions
699
- > - **"Session-data persistence"** (shipped 2026-02-08) — 1 decision
762
+ > - **"Anonymous checkout opt-in"** (shipped 2026-04-12) · 1 open deferral
763
+ > - **"Payment-method routing"** (shipped 2026-03-22)
764
+ > - **"Session-data persistence"** (shipped 2026-02-08)
700
765
  >
701
766
  > I factored those into the sub-problems below.
702
767
 
768
+ (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.)
769
+
703
770
  If `implementationCount === 0`: don't mention the KG check (silent — would just be noise on a cold KG).
704
771
 
705
772
  **[USER PAUSE]** Present as `Problems to solve for`, never as versioned sub-problem headings:
706
773
 
707
774
  ```text
708
775
  Ritual build
709
- ✓ Context ● Scope ○ Discovery ○ Recommendations ○ Build brief ○ Implementation
776
+ ✓ Context ● Scope ○ Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
710
777
 
711
778
  Problems to solve for
712
779
 
@@ -839,7 +906,7 @@ Store `exploration_id`. Move the progress header from Scope to Discovery:
839
906
 
840
907
  ```text
841
908
  Ritual build
842
- ✓ Context ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation
909
+ ✓ Context ✓ Scope ● Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
843
910
 
844
911
  Exploration created. Track progress at https://dev.ritualapp.cloud/e/{exploration_id}
845
912
 
@@ -916,16 +983,49 @@ The state contains `matters[]`, each with `id`, `name`, and `questions[]`. Walk
916
983
  ```text
917
984
  Discovery area: {matter.name}
918
985
 
919
- Pick the questions Ritual should answer before recommendations.
920
- Choose `all`, numbers like `1,3`, or `skip`.
986
+ 1. {question 1}
987
+ 2. {question 2}
988
+ ...
989
+
990
+ Pick the questions Ritual should answer for this area. Reply with:
921
991
 
922
- 1. {question 1}
923
- 2. {question 2}
924
- ...
992
+ · `suggest` help me pick the top 3–4 highest-leverage questions for this area
993
+ · numbers like `1,3,5` — pick specifically
994
+ · `skip` — this area isn't relevant to the current scope
925
995
  ```
926
996
 
927
997
  **[USER PAUSE]** Wait per matter.
928
998
 
999
+ ###### "suggest" handling
1000
+
1001
+ When the user replies `suggest` for a matter, propose which questions to send to `accept_discovery_questions` rather than asking again. Selection rule:
1002
+
1003
+ - **Pick the top 3–4 questions most likely to shape the recommendations** based on the problem statement, the 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.
1004
+ - If the matter has **fewer than 4 questions**, pick all of them.
1005
+ - If the matter has **4 to 7 questions**, pick 3.
1006
+ - If the matter has **8+ questions**, pick 4.
1007
+
1008
+ After picking, tell the user which ones were suggested so they can see and override:
1009
+
1010
+ ```text
1011
+ Suggested picks for "{matter.name}":
1012
+ ✓ {question N} — {one-line why this matters}
1013
+ ✓ {question M} — {one-line why this matters}
1014
+ ✓ {question P} — {one-line why this matters}
1015
+
1016
+ Reply `redo` to suggest a different set, `numbers` to override (e.g. `2,5,7`), or `next` to continue.
1017
+ ```
1018
+
1019
+ `next` is the default — if the user just hits enter or says "looks good," proceed. Do not pause for explicit confirmation if the user already said `suggest`; the assist is the action, not a preview the user has to re-approve.
1020
+
1021
+ ###### "skip" handling
1022
+
1023
+ Treat the matter as not requiring questions. Don't call `accept_discovery_questions` for it. The unpicked questions feed Step 7.4.5's classification check.
1024
+
1025
+ ###### Removed: `all` (the old fourth option)
1026
+
1027
+ 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.
1028
+
929
1029
  ##### 7.4 — Commit picks per-matter
930
1030
 
931
1031
  For each matter where the user picked at least one question, call `mcp__ritual__accept_discovery_questions` with:
@@ -1338,7 +1438,7 @@ Intermediate commits can skip the footer. The final commit IS the linkage anchor
1338
1438
  **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
1439
 
1340
1440
  ```
1341
- ✓ Implementation done — {exploration name}
1441
+ ✓ Implementation done (your agent) — {exploration name}
1342
1442
  Branch: {branch}, {N} commits, {M} files changed
1343
1443
  Tests: {tests_added} added, all passing
1344
1444
  RBs satisfied: {comma-joined list of RB-N from the brief, ALL or a count}
@@ -1399,12 +1499,12 @@ Before asking for permission, frame the call in language the user can act on. `s
1399
1499
 
1400
1500
  > I'm about to log this implementation into the workspace's knowledge graph. After this:
1401
1501
  > - The exploration's state flips to ✓ done (or ⚠ implemented-ahead if any recs weren't approved when shipped).
1402
- > - The {N} architectural decisions you made get linked back to the recommendations that motivated them — so future `/ritual build` calls touching `{first 2 files}` will see your decisions as priorContext.
1502
+ > - The implementation gets linked back to the recommendations it implements — so future `/ritual build` calls touching `{first 2 files}` will see this implementation as priorContext.
1403
1503
  > - The {M} open deferrals you intentionally punted get logged with their reasons — peers can see them in `/ritual lineage` on these files later.
1404
1504
  >
1405
- > **OK to log? (y / hold off / let me adjust the decision list first)**
1505
+ > **OK to log? (y / hold off / let me adjust the list first)**
1406
1506
 
1407
- 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).
1507
+ 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
1508
 
1409
1509
  ##### 12.1 — Make the call
1410
1510
 
@@ -1428,15 +1528,17 @@ When sync_implementation succeeds, the response includes:
1428
1528
  **Surface ALL of this to the user**, not just "ok logged." This is the visible signal that the loop closed. Format:
1429
1529
 
1430
1530
  > ✓ Logged implementation for **{exploration name}**
1431
- > - {decisionsCount} decision{s} registered: {first 2 decisions, e.g. "auth: OAuth not SAML; data-model: tenant-scoped indexes"}
1531
+ > - Implemented: {first 2 area:choice pairs from the `decisions[]` payload, e.g. "auth: OAuth not SAML; data-model: tenant-scoped indexes"}
1432
1532
  > - {deferralsCount} deferral{s} registered: {first 1, e.g. "[major] Rate-limit per-tenant — out of scope for v1"}
1433
1533
  > - View: {webUrl}
1434
1534
  >
1435
1535
  > Future `/ritual build` calls touching `{first 2 of filesChanged}` will now see this implementation in their priorContext block.
1436
1536
 
1437
- If any decision's `recommendationStatusAtImplementation` is NOT `approved` (i.e. the Branch B path), add a callout:
1537
+ 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.
1538
+
1539
+ If any anchor's `recommendationStatusAtImplementation` is NOT `approved` (i.e. the Branch B path), add a callout — still frame in implementation/recommendation terms:
1438
1540
 
1439
- > ⚠ {M} decision{s} implemented while their source recommendation was still in **{status}** — the exploration now shows `implemented_ahead`. An admin should review + accept the recs to close the gap.
1541
+ > ⚠ {M} of the recommendations were implemented while still in **{status}** state — the exploration now shows `implemented_ahead`. An admin should review + accept the recs to close the gap.
1440
1542
 
1441
1543
  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
1544
 
@@ -1446,9 +1548,44 @@ User-visible:
1446
1548
 
1447
1549
  > `sync_implementation` failed: {error summary}
1448
1550
  > Saved the intended sync payload to `.ritual/pending-sync/<exploration-id>.json`.
1449
- > Retry later with the same payload; no implementation decisions were lost.
1551
+ > Retry later with the same payload; nothing about your implementation was lost.
1552
+ >
1553
+ > (Run `/ritual resume` later to see + retry pending syncs.)
1554
+
1555
+ 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):
1556
+
1557
+ ```bash
1558
+ mkdir -p .ritual/pending-sync
1559
+ [ -f .ritual/pending-sync/.gitignore ] || echo '*' > .ritual/pending-sync/.gitignore
1560
+ [ -f .ritual/pending-sync/.gitignore ] && ! grep -q '^!\.gitignore$' .ritual/pending-sync/.gitignore && echo '!.gitignore' >> .ritual/pending-sync/.gitignore
1561
+ ```
1562
+
1563
+ 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.
1564
+
1565
+ ##### 12.2 — Staleness check before retry
1566
+
1567
+ 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."
1568
+
1569
+ Before re-invoking `sync_implementation` on a saved payload:
1570
+
1571
+ 1. Read the payload's `commits[]` (each has a `sha`).
1572
+ 2. Run `git log --pretty=format:%H` against the payload's `branch`.
1573
+ 3. Compare: if there are commit SHAs in `git log` that AREN'T in the payload's `commits[]`, the payload is stale.
1574
+
1575
+ If stale, surface to the user:
1576
+
1577
+ > ⚠ This pending sync was saved {N} day(s) ago. Since then you've added {M} more commit(s) to `{branch}` that aren't in the saved payload.
1578
+ >
1579
+ > Retrying as-is would log a partial picture (decisions from when the failure happened, but missing the {M} new commits).
1580
+ >
1581
+ > Options:
1582
+ > 1. **Retry as-is** — log what was saved; you can sync the new commits in a follow-up.
1583
+ > 2. **Regenerate** — re-run Step 12 from scratch with the current state; discards the saved payload.
1584
+ > 3. **Show me** — print the {M} new commits so I can decide.
1585
+
1586
+ **[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
1587
 
1451
- Create `.ritual/pending-sync/` if needed. Keep the pending-sync file git-tracked unless the repo has a different convention for generated workflow state.
1588
+ If the saved payload's `commits[]` matches current git state, proceed silently to the retry.
1452
1589
 
1453
1590
  #### Step 13 — Optional follow-up
1454
1591
 
@@ -113,9 +113,12 @@ Use engineer-facing language in CLI output:
113
113
  | `Step 1.5`, `Step 7.4.5`, `Step CP3` | natural labels such as "existing work check", "question picking", "build brief" |
114
114
  | raw recon dump | recon digest |
115
115
  | "I inferred…" | direct default + override path |
116
+ | **`decisions` / `decision` as a label or count** (e.g. "5 decisions logged", "decision list", "the N decisions you made") | Frame as **the implementation itself**. Recommendations get *implemented*; the artifacts of that implementation are surfaced inline (specific choices, deferrals, files touched) rather than as a labeled count. The underlying API parameter is still `decisions[]`, but the user sees "your implementation" / "what you implemented" / inline content. |
116
117
 
117
118
  Internal step labels are allowed inside reference docs and implementation notes. Translate them before showing text to users.
118
119
 
120
+ **Why the `decisions` rule (2026-05-13):** Earlier copy surfaced `5 decisions logged` and `Decision: <text>` as status badges. Users read those as a parallel concept to recommendations, which inflated the cognitive surface. The lifecycle the user actually tracks is `recommendation → approved → implemented`. The decision artifacts exist (and are still surfaced explicitly by `/ritual lineage`, where decision-on-file archeology IS the subcommand's purpose), but they are NOT a headline concept in `/ritual build` or `/ritual resume`. When the user is about to authorize `sync_implementation`, frame the moment as "log this implementation" — not "log these N decisions."
121
+
119
122
  ## Dense list format
120
123
 
121
124
  When showing high-leverage candidates, recommendations, lineage events, or other dense lists, use labeled blocks:
@@ -143,7 +146,7 @@ For no-arg `/ritual build` with zero explorations, do not frame `/ritual context
143
146
 
144
147
  ```text
145
148
  Ritual build
146
- ● Context ○ Scope ○ Discovery ○ Recommendations ○ Build brief ○ Implementation
149
+ ● Context ○ Scope ○ Discovery ○ Recommendations ○ Build brief ○ Implementation (Your agent)
147
150
 
148
151
  Using workspace: {workspaceName}.
149
152
 
@@ -27,6 +27,51 @@ If the workspace has **zero explorations**: tell the user politely and pivot.
27
27
 
28
28
  End the flow here. Don't bounce them into `/ritual build` automatically — explicit user intent beats implicit handoff.
29
29
 
30
+ #### Step R1.5 — Check for pending syncs (if any)
31
+
32
+ Before showing the in-flight exploration list, glance at `.ritual/pending-sync/` to surface any `sync_implementation` calls that failed in past sessions. These are the cleanest "you left something undone" signal — more concrete than an exploration's state badge alone.
33
+
34
+ Quick scan:
35
+
36
+ ```bash
37
+ ls .ritual/pending-sync/*.json 2>/dev/null
38
+ ```
39
+
40
+ If the directory doesn't exist or has no `.json` files: proceed silently to R2. Most invocations land here.
41
+
42
+ If there ARE pending syncs:
43
+
44
+ 1. Read each `.json` file. Extract `explorationId`, `branch`, `commits[].sha` count, and the file's mtime ("saved Xd ago").
45
+
46
+ 2. For each, do a **quick staleness probe** — same shape as `/ritual build` Step 12.2:
47
+
48
+ ```bash
49
+ # In the payload's branch, are there commits not in payload.commits[]?
50
+ git log {branch} --pretty=format:%H 2>/dev/null
51
+ ```
52
+
53
+ 3. Surface the list before the regular exploration picker:
54
+
55
+ ```text
56
+ You have {N} pending sync{s} from past sessions:
57
+
58
+ 1. **{exploration name}**
59
+ Saved {Xd} ago · {commitsCount} commit{s} · branch `{branch}`
60
+ {stalenessBadge} ← "✓ still current" | "⚠ {M} new commits since save"
61
+
62
+ 2. ...
63
+
64
+ Resolve before resuming? (Y/n)
65
+ ```
66
+
67
+ **[USER PAUSE — required, do not auto-answer]** Wait for reply.
68
+
69
+ 4. If user says **yes**: for each pending sync (in order), apply the same flow as `/ritual build` Step 12.2's staleness check — retry as-is / regenerate / show new commits. Once resolved, delete the corresponding `.ritual/pending-sync/<id>.json` (succeeded) or leave it for later (deferred). Then continue to R2.
70
+
71
+ 5. If user says **no**: proceed to R2 silently. The pending syncs aren't going anywhere; the user can clear them later via `/ritual resume` again.
72
+
73
+ The point: a pending sync is a stronger signal than "this exploration's state badge says ready" because the user's own code-tracking failed mid-flight. Surfacing them first means the user resolves obviously-broken state before being asked to pick a new thing to work on.
74
+
30
75
  #### Step R2 — Surface in-flight explorations with state badges
31
76
 
32
77
  Call `mcp__ritual__list_explorations(workspace_id)`. Sort by most-recently-updated. Drop archived. Cap at 5 in the user-facing summary.