@azure-id/orc 2.0.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/CHANGELOG.md +401 -0
  2. package/README-id.md +52 -23
  3. package/README.md +50 -22
  4. package/bin/build-agents.js +24 -25
  5. package/bin/clear-logs.js +620 -0
  6. package/bin/cli.js +1155 -158
  7. package/bin/fix.js +459 -0
  8. package/bin/gotcha.js +288 -8
  9. package/bin/habit.js +1538 -1453
  10. package/bin/mockrun-catalog.js +3 -0
  11. package/bin/onboarding-content.js +2 -1
  12. package/bin/pricing.json +28 -21
  13. package/bin/trace-write.js +869 -657
  14. package/bin/verify-contracts.js +108 -27
  15. package/bin/verify-package.js +17 -6
  16. package/bin/webui/api.js +125 -6
  17. package/bin/webui/css/panels/hookui.css +79 -0
  18. package/bin/webui/fixtures/behaviour.js +30 -0
  19. package/bin/webui/fixtures/extra.js +9 -9
  20. package/bin/webui/fixtures/flow.js +81 -81
  21. package/bin/webui/fixtures/hookui.js +506 -431
  22. package/bin/webui/fixtures/index.js +32 -3
  23. package/bin/webui/fixtures/knowledge.js +2 -2
  24. package/bin/webui/fixtures/maintenance.js +123 -42
  25. package/bin/webui/fixtures/rules.js +1007 -1002
  26. package/bin/webui/fixtures/settings.js +6 -7
  27. package/bin/webui/fixtures/stats.js +9 -6
  28. package/bin/webui/fixtures/wait.js +98 -97
  29. package/bin/webui/i18n/en/behaviour.json +13 -0
  30. package/bin/webui/i18n/en/hookui.json +290 -194
  31. package/bin/webui/i18n/en/maintenance.json +71 -52
  32. package/bin/webui/i18n/en/settings.json +60 -60
  33. package/bin/webui/i18n/id/behaviour.json +13 -0
  34. package/bin/webui/i18n/id/hookui.json +290 -194
  35. package/bin/webui/i18n/id/maintenance.json +71 -52
  36. package/bin/webui/i18n/id/settings.json +60 -60
  37. package/bin/webui/js/05-banners.js +181 -172
  38. package/bin/webui/js/06-edit.js +193 -183
  39. package/bin/webui/js/panels/behaviour.js +77 -12
  40. package/bin/webui/js/panels/hookui.js +2196 -1691
  41. package/bin/webui/js/panels/maintenance.js +336 -235
  42. package/bin/webui/js/panels/settings.js +726 -719
  43. package/mock-run/INDEX.md +1 -0
  44. package/mock-run/extra-slots.md +1 -1
  45. package/mock-run/habits.md +1 -1
  46. package/mock-run/orc-aftermath.md +392 -392
  47. package/mock-run/orc-budget.md +29 -33
  48. package/mock-run/orc-cli.md +200 -200
  49. package/mock-run/orc-explain.md +86 -86
  50. package/mock-run/orc-extra.md +389 -392
  51. package/mock-run/orc-fix.md +87 -0
  52. package/mock-run/orc-pattern.md +112 -112
  53. package/mock-run/orc.md +157 -157
  54. package/package.json +1 -1
  55. package/templates/agents/MODEL-MAPPING.md +32 -29
  56. package/templates/agents/orc-analyze-mini-sonnet-5-high.md +2 -2
  57. package/templates/agents/{orc-claude-writer-opus-5-med.md → orc-claude-writer-opus-5-low.md} +4 -4
  58. package/templates/agents/orc-executor-haiku-4-5.md +1 -1
  59. package/templates/agents/orc-executor-opus-5-low.md +1 -1
  60. package/templates/agents/orc-executor-sonnet-4-6-high.md +1 -1
  61. package/templates/agents/orc-executor-sonnet-4-6-med.md +1 -1
  62. package/templates/agents/orc-executor-sonnet-5-high.md +2 -2
  63. package/templates/agents/orc-executor-sonnet-5-low.md +155 -0
  64. package/templates/agents/orc-executor-sonnet-5-med.md +155 -0
  65. package/templates/agents/orc-pattern-codifier-sonnet-5-high.md +2 -2
  66. package/templates/agents/orc-planner-mini-sonnet-5-high.md +2 -2
  67. package/templates/agents/orc-retro-sonnet-5-high.md +2 -2
  68. package/templates/agents/{orc-reviewer-opus-5-med.md → orc-reviewer-opus-5-low.md} +4 -4
  69. package/templates/agents/{orc-wiki-scanner-opus-5-med.md → orc-wiki-scanner-opus-5-low.md} +3 -3
  70. package/templates/agents/orc-wiki-scanner-sonnet-5-high.md +2 -2
  71. package/templates/commands/orc-fix.md +18 -0
  72. package/templates/commands/orc-wiki.md +64 -64
  73. package/templates/hooks/README.md +75 -7
  74. package/templates/hooks/orc-session-hook.js +78 -3
  75. package/templates/hooks/orc-statusline-render.js +317 -23
  76. package/templates/hooks/orc-statusline.js +162 -49
  77. package/templates/hooks/orc-subagent-line.js +23 -5
  78. package/templates/hooks/orc-weather-fetch.js +123 -0
  79. package/templates/skills/_shared/extra-dispatch.md +5 -5
  80. package/templates/skills/_shared/gotchas.md +27 -7
  81. package/templates/skills/_shared/habits.md +2 -2
  82. package/templates/skills/_shared/opus5-only.md +14 -14
  83. package/templates/skills/_shared/phases/review.md +2 -2
  84. package/templates/skills/_shared/phases/trace-verbs.md +17 -3
  85. package/templates/skills/_shared/phases/trace.md +136 -136
  86. package/templates/skills/_shared/review-slice.md +28 -1
  87. package/templates/skills/_shared/wait.md +1 -0
  88. package/templates/skills/orc/README.md +2 -2
  89. package/templates/skills/orc/SKILL.md +1 -1
  90. package/templates/skills/orc/config.md +25 -27
  91. package/templates/skills/orc/examples/full-run-mock.md +2 -1
  92. package/templates/skills/orc/references/effort-and-mode.md +17 -17
  93. package/templates/skills/orc/references/preflight-report.md +3 -3
  94. package/templates/skills/orc/references/ultra-mode.md +1 -1
  95. package/templates/skills/orc/schemas/checkpoint.md +122 -122
  96. package/templates/skills/orc/subskills/orc-review-verify/SKILL.md +3 -3
  97. package/templates/skills/orc/subskills/orc-review-verify/core.md +1 -1
  98. package/templates/skills/orc-analyze/SKILL.md +4 -2
  99. package/templates/skills/orc-claude/SKILL.md +14 -14
  100. package/templates/skills/orc-claude/examples/claude-run-mock.md +65 -65
  101. package/templates/skills/orc-diy/SKILL.md +5 -5
  102. package/templates/skills/orc-fast/SKILL.md +8 -6
  103. package/templates/skills/orc-fix/SKILL.md +110 -0
  104. package/templates/skills/orc-mini/SKILL.md +4 -4
  105. package/templates/skills/orc-mini/examples/mini-run-mock.md +4 -2
  106. package/templates/skills/orc-quick/README.md +1 -1
  107. package/templates/skills/orc-quick/SKILL.md +2 -2
  108. package/templates/skills/orc-quick/references/dispatch-gate.md +3 -2
  109. package/templates/skills/orc-quick/references/gh-mode.md +4 -2
  110. package/templates/skills/orc-retro/SKILL.md +1 -1
  111. package/templates/skills/orc-retro/examples/retro-mock.md +16 -16
  112. package/templates/skills/orc-wiki/README.md +325 -325
  113. package/templates/skills/orc-wiki/SKILL.md +195 -195
  114. package/templates/skills/orc-wiki/examples/wiki-run-mock.md +37 -37
  115. package/templates/skills/orc-wiki/references/extra.md +2 -2
  116. package/templates/skills/orc-wiki/references/partial-refresh.md +276 -271
  117. package/templates/skills/orc-wiki/references/phases/phase-0.md +1 -1
  118. package/templates/skills/orc-wiki/references/phases/phase-2.md +3 -3
  119. package/templates/skills/orc-wiki/references/phases/phase-3c.md +3 -2
  120. package/templates/agents/orc-claude-writer-opus-4-8-high.md +0 -48
  121. package/templates/agents/orc-wiki-scanner-opus-4-8-high.md +0 -74
@@ -108,7 +108,7 @@ clamp 0..100 → the RESOLVED table (below).
108
108
 
109
109
  **Which table (highest wins):** `opus5_only: true` (the 2-band Opus-5-only
110
110
  preset: `[0,90)` low · `[90,100]` medium) → `rubric_bands_override`
111
- (hand-written rows) → the default 6-band table. All three are in `config.md`.
111
+ (hand-written rows) → the default 5-band table. All three are in `config.md`.
112
112
  The formula, the facets and the risk floor are IDENTICAL in every case — only
113
113
  the score→agent mapping changes. Three consequences worth stating so nobody
114
114
  re-derives them per run:
@@ -123,14 +123,14 @@ re-derives them per run:
123
123
  Show the user the full table (task, the facet vector, the arithmetic
124
124
  `B+N+L+T+fan+U = raw`, any risk floor, final, override+reason if any, dispatched
125
125
  model) BEFORE dispatching — an un-shown number is not a scored number. **Head it
126
- with the RESOLVED table's name** (`6-band default` / `Opus-5-only ladder
126
+ with the RESOLVED table's name** (`5-band default` / `Opus-5-only ladder
127
127
  (opus5_only)` / `custom (rubric_bands_override)`): the same logic
128
128
  applies to the mapping as to the number.
129
129
 
130
130
  **Extra (v0.50.0, `extra_enabled`) adds a `via` column and can make the head a
131
131
  PAIR.** An Extra route row is an OVERLAY that outranks the tables above **only
132
132
  for the scores it covers**, so a run can genuinely be running two tables at once
133
- and the head names both (`6-band default + extra rows [0,30) [30,70)`). The
133
+ and the head names both (`5-band default + extra rows [0,30) [30,70)`). The
134
134
  column reads `claude` or `extra:<profile> (<engine>)` and comes from
135
135
  `orc extra resolve --json` — the formula, the facets and the risk floor are
136
136
  untouched, and **the score is computed before the routing, never after it**. Two
@@ -170,14 +170,14 @@ the band is what matters. Compare a new task to these facet-by-facet.
170
170
 
171
171
  | Task | breadth·novelty·logic·test · fan_in/out · unc | Arithmetic | Band |
172
172
  |---|---|---|---|
173
- | Rename a config key across 4 files + its test | 5·mechanical·none·update-existing · 0/0 · low | 10+0+0+4 = **14** | haiku [0,30) |
174
- | New CRUD endpoint following a sibling route | 3·imitate·branching·new-tests · 1/0 · low | 6+8+8+8+5 = **35** | sonnet-4-6-med [30,40) |
175
- | Bug fix across 2 files with a repro test | 3·imitate·branching·new-tests · 0/0 · medium | 6+8+8+8+6 = **36** | sonnet-4-6-med [30,40) |
176
- | Isolated component from the design system | 3·new-surface·branching·new-tests · 0/0 · low | 6+18+8+8 = **40** | sonnet-4-6-high [40,55) |
177
- | Notification model + enum other tasks consume | 3·new-surface·stateful·new-tests · 0/3 · low | 6+18+16+8+9 = **57** | sonnet-5-high [55,65) |
178
- | Service-layer refactor behind a stable interface | 5·imitate·stateful·update-existing · 0/3 · medium | 10+8+16+4+9+6 = **53** | sonnet-4-6-high [40,55) |
179
- | Add role check to payment-refund endpoint | 3·imitate·branching·new-tests · 0/0 · low · **risk=[auth,money]** | 30 raw → **floor 70** | opus-5-low [65,90) |
180
- | Migrate orders table to split-name + backfill | 6·new-surface·stateful·new-tests · 1/3 · high · **risk=[migration,data-integrity]** | 15+18+16+8+5+9+12 = 83 (floor 70) → **83** | opus-5-low [65,90) |
173
+ | Rename a config key across 4 files + its test | 5·mechanical·none·update-existing · 0/0 · low | 10+0+0+4 = **14** | sonnet-5-low [0,21) |
174
+ | New CRUD endpoint following a sibling route | 3·imitate·branching·new-tests · 1/0 · low | 6+8+8+8+5 = **35** | sonnet-5-high [31,41) |
175
+ | Bug fix across 2 files with a repro test | 3·imitate·branching·new-tests · 0/0 · medium | 6+8+8+8+6 = **36** | sonnet-5-high [31,41) |
176
+ | Isolated component from the design system | 3·new-surface·branching·new-tests · 0/0 · low | 6+18+8+8 = **40** | sonnet-5-high [31,41) |
177
+ | Notification model + enum other tasks consume | 3·new-surface·stateful·new-tests · 0/3 · low | 6+18+16+8+9 = **57** | opus-5-low [41,90) |
178
+ | Service-layer refactor behind a stable interface | 5·imitate·stateful·update-existing · 0/3 · medium | 10+8+16+4+9+6 = **53** | opus-5-low [41,90) |
179
+ | Add role check to payment-refund endpoint | 3·imitate·branching·new-tests · 0/0 · low · **risk=[auth,money]** | 30 raw → **floor 70** | opus-5-low [41,90) |
180
+ | Migrate orders table to split-name + backfill | 6·new-surface·stateful·new-tests · 1/3 · high · **risk=[migration,data-integrity]** | 15+18+16+8+5+9+12 = 83 (floor 70) → **83** | opus-5-low [41,90) |
181
181
 
182
182
  Two disciplines the vectors encode: (1) a small diff is NOT a low score when a
183
183
  cited `risk` facet forces the floor (the refund row — 30 raw, floored to 70); (2)
@@ -188,15 +188,15 @@ applies it silently.
188
188
  ## Model ladder → the single score→model table
189
189
 
190
190
  The score→model mapping is NOT hardcoded here — it lives in `config.md` as ONE
191
- canonical 6-band table (there is no longer a narrow/wide preset). Read config at
191
+ canonical 5-band table (there is no longer a narrow/wide preset). Read config at
192
192
  run start and map each task's final score through that table (or
193
193
  `rubric_bands_override`). The orchestrator dispatches the executor agent BY NAME;
194
194
  it does not request a raw model. `rubric_bands` sets only how many bands the
195
195
  rubric REPORTS (score granularity), never which table is used.
196
196
 
197
- The 6 bands (see config.md for the exact edges): `haiku-4-5` [0,30) ·
198
- `sonnet-4-6-med` [30,40) · `sonnet-4-6-high` [40,55) · `sonnet-5-high` [55,65) ·
199
- `opus-5-low` [65,90) · `opus-5-med` [90,100]. Effort tiers rank
197
+ The 5 bands (see config.md for the exact edges): `sonnet-5-low` [0,21) ·
198
+ `sonnet-5-med` [21,31) · `sonnet-5-high` [31,41) · `opus-5-low` [41,90) ·
199
+ `opus-5-med` [90,100]. Effort tiers rank
200
200
  `low < medium < high < xhigh < max`.
201
201
 
202
202
  ## Fixed model assignments (not scored)
@@ -204,14 +204,14 @@ The 6 bands (see config.md for the exact edges): `haiku-4-5` [0,30) ·
204
204
  - **Orchestrator (you):** Opus 4.8 high — or Opus 5.5 / Fable 5 at medium+, the
205
205
  two models that clear the guard from medium up. Never downgrade yourself.
206
206
  - **Review** — Superpowers path: Sonnet 4.6, medium. OpenSpec/self path:
207
- Opus 5.5, medium (`orc-reviewer-opus-5-med`).
207
+ Opus 5.5, low (`orc-reviewer-opus-5-low`; medium until v2.1.0).
208
208
  - **Verify:** Opus 5.5, medium (`orc-verifier-opus-5-med`).
209
209
  - **Analyst:** Opus 5.5, high. **Planner:** Opus 5.5, medium. **Test author:**
210
210
  Opus 5.5, medium. **Combiner:** Opus 5.5, high. **Ultra advisor/judge:** Opus 5.5,
211
211
  xhigh — every core fixed role is pinned to Opus 5.5 as of v0.34.0.
212
212
  - **Merge-conflict resolver:** Opus 4.8, medium.
213
213
 
214
- Note: every band in the table above is a real dispatch target (haiku through
214
+ Note: every band in the table above is a real dispatch target (sonnet-5 through
215
215
  opus-5). If a model tier is unavailable in the environment, fall back UP to the
216
216
  next capable tier (never silently substitute a different family/effort).
217
217
 
@@ -25,7 +25,7 @@ after: src/payments — 2 shipped files rewritten within 30 days of run stor
25
25
  crosslink: 2 boundaries (payments-api) — advisory
26
26
  extra: ON — 4 of 9 tasks foreign · deepseek/deepseek-v4-flash via api [0,30)
27
27
  · glm/glm-4.7 via cli [30,70) · 2 held back (risk: auth, money)
28
- scoring: 6-band default table
28
+ scoring: 5-band default table
29
29
  tdd: 3 tasks with tests (T3, T6, T9) · 2 covered-by-existing · 2 no-behavior
30
30
  skipped: R4 translation strings (no-behavior) · R7 file split
31
31
  (covered-by-existing → test/api/health.test.js:41)
@@ -100,7 +100,7 @@ waves: 3 planned — will pause after wave 2 (batch_pause_every=2)
100
100
  `EXTRA orphan` line from `trace_extras[]` once you have reported it.
101
101
 
102
102
  Canonical: `../../_shared/extra-dispatch.md`.
103
- - **scoring:** which executor table RESOLVED for this run — `6-band default
103
+ - **scoring:** which executor table RESOLVED for this run — `5-band default
104
104
  table` · `Opus-5-only ladder (opus5_only)` · `custom
105
105
  (rubric_bands_override, <n> rows)`. An un-shown table is as unaccountable as
106
106
  an un-shown number, and the Opus-5-only ladder in particular means EVERY
@@ -109,7 +109,7 @@ waves: 3 planned — will pause after wave 2 (batch_pause_every=2)
109
109
  append ` · all fixed roles forced to Opus 5.5` and name any selector it
110
110
  shadowed (a `rubric_bands_override` present but INERT) — a setting
111
111
  the user tuned and the run then ignored has to be said out loud. With Extra in
112
- play the table is a COMPOSITE and reads as one (`6-band default table + extra
112
+ play the table is a COMPOSITE and reads as one (`5-band default table + extra
113
113
  rows [0,30) [30,70)`) — Extra is an overlay, so naming only one of the two would
114
114
  be naming the wrong half for every covered score.
115
115
  - **tdd:** ALWAYS printed on a lane whose TDD policy is on — BOTH branches, not
@@ -17,7 +17,7 @@ Apply at Phase 0, on top of the normal config resolution:
17
17
  - `pattern_findings` = on · `generate_tests` = on · `security_review` = on.
18
18
  - Executor **tier floor**: remap the resolved score→model table so no task
19
19
  dispatches below `orc-executor-sonnet-5-high`; bands at/above the opus
20
- boundary (65) rise to at least `orc-executor-opus-5-low`. The floor only ever
20
+ boundary (41) rise to at least `orc-executor-opus-5-low`. The floor only ever
21
21
  raises a band, so the top `[90,100]` band keeps `orc-executor-opus-5-med`.
22
22
  **Under `opus5_only` the floor raises EFFORT, not model** (every band is
23
23
  already Opus 5.5, so there is no model left to raise): the `[0,90)` band rises
@@ -1,122 +1,122 @@
1
- # Schema — Durable Checkpoint + State-of-Play
2
-
3
- Two files, two jobs:
4
- - `run/{run-slug}/checkpoint.json` — machine truth. Orchestrator-only writes.
5
- Survives pause, compaction, crash, fresh sessions. KEPT after success (audit).
6
- - `run/{run-slug}/state-of-play.md` — 10-line human-readable re-anchor. Read FIRST on any
7
- resume, then the checkpoint for detail.
8
-
9
- ## run/{run-slug}/checkpoint.json
10
-
11
- ```jsonc
12
- {
13
- "run_id": "run-020726-1422",
14
- "schema_version": "0.2",
15
- "phase": "execution", // intake|planning|scoring|execution|integration|review|verify|summary|ship|done
16
- "planner": "openspec",
17
- "effort": "medium",
18
- "execution_model": "parallel", // sequential | parallel | parallel_worktrees
19
- "source_branch": "feat/notifications",
20
- "intent_spec": "run/merchant-notifications/intent-spec.md",
21
- "batch_pause_every": 2,
22
- "pause_schedule": [2], // wave indices where a MANDATORY batch stop fires
23
- // (computed from the Phase 2 answer; last wave never included) —
24
- // a resumed session enforces the same hard boundaries
25
- "logging_enabled": true, // logging is PERMANENT (always on) — re-anchor the behavior trace on resume
26
- "trace_path": null, // "<log_dir>/run-<lane>-<slug>-<DDMMYY>-<HHMMSS>.txt" — the run's trace file
27
- "ultra_mode": false, // true only on /orc-ultra runs; gates the "ultra" block below
28
- "ultra": null, /* when ultra_mode — a resumed run continues mid-gate/mid-loop:
29
- { "brief_path": "run/…/ultra/advisory-brief.md",
30
- "ledger_path": "run/…/ultra/assumption-ledger.md",
31
- "matrix_path": null, // set before gate 3
32
- "gates": { // per-gate judgment state
33
- "analysis": { "verdict": "approve", "round": 1, "loops_used": 0 },
34
- "plan": { "verdict": "revise", "round": 2, "loops_used": 1 },
35
- "implementation": { "verdict": null, "round": 0, "loops_used": 0 } } } */
36
- "current_wave": 2,
37
- "paused": true,
38
- "pause_trigger": "batch_pause", // batch_pause | token_limit | phase_transition | crash_guard
39
-
40
- "plan": { /* full planning-output object */ },
41
-
42
- // fast-resume mirror; kept in sync on every task state change
43
- "task_state": {
44
- "T1": { "status": "done", "retry_count": 0, "context_requests": 0,
45
- "failure_reason": null, "progress": null,
46
- "actual_files": ["db/migrations/0001.sql", "models/notification.x", "models/notification.test.x"] },
47
- "T3": { "status": "partial", "retry_count": 0, "context_requests": 1,
48
- "failure_reason": null,
49
- "progress": { "percent": 60, "files_written": ["services/email_digest/scheduler.x"],
50
- "notes": "daily path done; weekly cron pending" } }
51
- },
52
-
53
- // every spawn, for the usage report + rubric audit
54
- "dispatch_log": [
55
- { "task_id": "T1", "computed_score": 72, "override_score": null,
56
- "override_reason": null, "model": "sonnet-5", "effort": "medium",
57
- "spawned_at": "020726 14:24:01.100",
58
- // claimed-vs-actual (only when logging_enabled): what the worker reported
59
- "actual_model": "claude-sonnet-5", "actual_effort": "medium",
60
- "verify": "match" }, // match | downgrade
61
-
62
- { "task_id": "T6", "computed_score": 88, "override_score": 62,
63
- "override_reason": "rubric over-weighted file count; isolated leaf UI",
64
- "model": "sonnet-5", "effort": "high", "spawned_at": "020726 15:01:22.040" }
65
- ],
66
-
67
- "worktrees": { /* subagent_worktrees mode: agent → {path, branch, merged} */ },
68
- "merge_state": null, // null | pending_verify | merged | conflict_resolving
69
-
70
- "escalations": [
71
- { "id": "E1", "agent": "Agent-C", "task": "T3",
72
- "question": "Digest send time?", "answer": "07:00 fixed",
73
- "at": "020726 14:28:41.507",
74
- "affected_tasks": [], "downstream_flagged": [] }
75
- ],
76
-
77
- "review": { "ran": false }, // when ran: p0[], p1[], p2[], p3[], model, effort
78
- // (v1 checkpoints used blocking[]/nits[] — on resume
79
- // map blocking→p1, nits→p3; never rewrite the old file.
80
- // v0.7.0+: each recorded P0–P2 finding keeps its
81
- // file:line + verbatim quote so a resumed run can
82
- // re-run the quote spot-check before acting)
83
- "verify": { "ran": false }, // result, autofix_used, autofix_remaining (starts 1)
84
- "ship": { "commit": null, "push": null, "create_pr": null,
85
- "ticket": null, "pr_title": null, "target_branch": null, "pr_file": null },
86
-
87
- "decision_log": "run/merchant-notifications/decision-log.md",
88
- "created_at": "020726 14:22:01.000",
89
- "updated_at": "020726 15:02:00.331"
90
- }
91
- ```
92
-
93
- ## run/{run-slug}/state-of-play.md (regenerated at every checkpoint write)
94
-
95
- ```markdown
96
- # State of Play — run-020726-1422
97
- Phase: execution · Wave 2 of 3 · PAUSED (batch)
98
- Done: T1 T2 T4 · Partial: T3 (60%, weekly cron pending) · Pending: T5 T6
99
- Mode: subagent · Planner: openspec · Branch: feat/notifications
100
- Last decision: digest send 07:00 fixed (user, via Agent-C)
101
- Next action on resume: finish T3 from milestone, then dispatch wave 3
102
- Intent: merchant notifications (in-app + email digest + prefs) — no push, no admin
103
- ```
104
-
105
- ## Write discipline
106
-
107
- - Orchestrator-only. Atomic write (temp file + rename). `updated_at` bumped to
108
- ms on every write.
109
- - Write EAGERLY: after every wave, escalation answer, phase transition, and
110
- before any risky operation — so surprise compaction never catches
111
- conversation-only state.
112
- - A failed/malformed checkpoint write is a FAILURE: do not stop the session on
113
- it; surface it.
114
-
115
- ## Resume contract
116
-
117
- 1. Read state-of-play (orientation) → newest checkpoint (`updated_at` wins).
118
- 2. Fresh session: one-line intent reconfirm from the Intent line.
119
- 3. task_state: done stays done · partial resumes from progress.files_written ·
120
- pending awaits wave · requeued/failed re-dispatch reading failure_reason ·
121
- stale_review gets a review pass.
122
- 4. Re-attach decision log, regenerate digest, continue from `phase`.
1
+ # Schema — Durable Checkpoint + State-of-Play
2
+
3
+ Two files, two jobs:
4
+ - `run/{run-slug}/checkpoint.json` — machine truth. Orchestrator-only writes.
5
+ Survives pause, compaction, crash, fresh sessions. KEPT after success (audit).
6
+ - `run/{run-slug}/state-of-play.md` — 10-line human-readable re-anchor. Read FIRST on any
7
+ resume, then the checkpoint for detail.
8
+
9
+ ## run/{run-slug}/checkpoint.json
10
+
11
+ ```jsonc
12
+ {
13
+ "run_id": "run-020726-1422",
14
+ "schema_version": "0.2",
15
+ "phase": "execution", // intake|planning|scoring|execution|integration|review|verify|summary|ship|done
16
+ "planner": "openspec",
17
+ "effort": "medium",
18
+ "execution_model": "parallel", // sequential | parallel | parallel_worktrees
19
+ "source_branch": "feat/notifications",
20
+ "intent_spec": "run/merchant-notifications/intent-spec.md",
21
+ "batch_pause_every": 2,
22
+ "pause_schedule": [2], // wave indices where a MANDATORY batch stop fires
23
+ // (computed from the Phase 2 answer; last wave never included) —
24
+ // a resumed session enforces the same hard boundaries
25
+ "logging_enabled": true, // logging is PERMANENT (always on) — re-anchor the behavior trace on resume
26
+ "trace_path": null, // "<log_dir>/run-<lane>-<slug>-<DDMMYY>-<HHMMSS>.txt" — the run's trace file
27
+ "ultra_mode": false, // true only on /orc-ultra runs; gates the "ultra" block below
28
+ "ultra": null, /* when ultra_mode — a resumed run continues mid-gate/mid-loop:
29
+ { "brief_path": "run/…/ultra/advisory-brief.md",
30
+ "ledger_path": "run/…/ultra/assumption-ledger.md",
31
+ "matrix_path": null, // set before gate 3
32
+ "gates": { // per-gate judgment state
33
+ "analysis": { "verdict": "approve", "round": 1, "loops_used": 0 },
34
+ "plan": { "verdict": "revise", "round": 2, "loops_used": 1 },
35
+ "implementation": { "verdict": null, "round": 0, "loops_used": 0 } } } */
36
+ "current_wave": 2,
37
+ "paused": true,
38
+ "pause_trigger": "batch_pause", // batch_pause | token_limit | phase_transition | crash_guard
39
+
40
+ "plan": { /* full planning-output object */ },
41
+
42
+ // fast-resume mirror; kept in sync on every task state change
43
+ "task_state": {
44
+ "T1": { "status": "done", "retry_count": 0, "context_requests": 0,
45
+ "failure_reason": null, "progress": null,
46
+ "actual_files": ["db/migrations/0001.sql", "models/notification.x", "models/notification.test.x"] },
47
+ "T3": { "status": "partial", "retry_count": 0, "context_requests": 1,
48
+ "failure_reason": null,
49
+ "progress": { "percent": 60, "files_written": ["services/email_digest/scheduler.x"],
50
+ "notes": "daily path done; weekly cron pending" } }
51
+ },
52
+
53
+ // every spawn, for the usage report + rubric audit
54
+ "dispatch_log": [
55
+ { "task_id": "T1", "computed_score": 72, "override_score": null,
56
+ "override_reason": null, "model": "sonnet-5", "effort": "medium",
57
+ "spawned_at": "020726 14:24:01.100",
58
+ // claimed-vs-actual (only when logging_enabled): what the worker reported
59
+ "actual_model": "claude-sonnet-5-5", "actual_effort": "medium",
60
+ "verify": "match" }, // match | downgrade
61
+
62
+ { "task_id": "T6", "computed_score": 88, "override_score": 62,
63
+ "override_reason": "rubric over-weighted file count; isolated leaf UI",
64
+ "model": "sonnet-5", "effort": "high", "spawned_at": "020726 15:01:22.040" }
65
+ ],
66
+
67
+ "worktrees": { /* subagent_worktrees mode: agent → {path, branch, merged} */ },
68
+ "merge_state": null, // null | pending_verify | merged | conflict_resolving
69
+
70
+ "escalations": [
71
+ { "id": "E1", "agent": "Agent-C", "task": "T3",
72
+ "question": "Digest send time?", "answer": "07:00 fixed",
73
+ "at": "020726 14:28:41.507",
74
+ "affected_tasks": [], "downstream_flagged": [] }
75
+ ],
76
+
77
+ "review": { "ran": false }, // when ran: p0[], p1[], p2[], p3[], model, effort
78
+ // (v1 checkpoints used blocking[]/nits[] — on resume
79
+ // map blocking→p1, nits→p3; never rewrite the old file.
80
+ // v0.7.0+: each recorded P0–P2 finding keeps its
81
+ // file:line + verbatim quote so a resumed run can
82
+ // re-run the quote spot-check before acting)
83
+ "verify": { "ran": false }, // result, autofix_used, autofix_remaining (starts 1)
84
+ "ship": { "commit": null, "push": null, "create_pr": null,
85
+ "ticket": null, "pr_title": null, "target_branch": null, "pr_file": null },
86
+
87
+ "decision_log": "run/merchant-notifications/decision-log.md",
88
+ "created_at": "020726 14:22:01.000",
89
+ "updated_at": "020726 15:02:00.331"
90
+ }
91
+ ```
92
+
93
+ ## run/{run-slug}/state-of-play.md (regenerated at every checkpoint write)
94
+
95
+ ```markdown
96
+ # State of Play — run-020726-1422
97
+ Phase: execution · Wave 2 of 3 · PAUSED (batch)
98
+ Done: T1 T2 T4 · Partial: T3 (60%, weekly cron pending) · Pending: T5 T6
99
+ Mode: subagent · Planner: openspec · Branch: feat/notifications
100
+ Last decision: digest send 07:00 fixed (user, via Agent-C)
101
+ Next action on resume: finish T3 from milestone, then dispatch wave 3
102
+ Intent: merchant notifications (in-app + email digest + prefs) — no push, no admin
103
+ ```
104
+
105
+ ## Write discipline
106
+
107
+ - Orchestrator-only. Atomic write (temp file + rename). `updated_at` bumped to
108
+ ms on every write.
109
+ - Write EAGERLY: after every wave, escalation answer, phase transition, and
110
+ before any risky operation — so surprise compaction never catches
111
+ conversation-only state.
112
+ - A failed/malformed checkpoint write is a FAILURE: do not stop the session on
113
+ it; surface it.
114
+
115
+ ## Resume contract
116
+
117
+ 1. Read state-of-play (orientation) → newest checkpoint (`updated_at` wins).
118
+ 2. Fresh session: one-line intent reconfirm from the Intent line.
119
+ 3. task_state: done stays done · partial resumes from progress.files_written ·
120
+ pending awaits wave · requeued/failed re-dispatch reading failure_reason ·
121
+ stale_review gets a review pass.
122
+ 4. Re-attach decision log, regenerate digest, continue from `phase`.
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: orc-review-verify
3
3
  description: >
4
- Review/verify worker for ORC Phases 5–6 (Opus 5.5 medium). Two modes: a REVIEW
4
+ Review/verify worker for ORC Phases 5–6 (review Opus 5.5 low, verify medium). Two modes: a REVIEW
5
5
  pass — examine the changed files against the code pattern + constraints,
6
6
  create/update tests, and classify EVERY finding on the P0–P3 severity
7
7
  ladder (P0/P1 gate ship, P2/P3 advisory); a VERIFY
@@ -23,13 +23,13 @@ owns the auto-fix-once loop.
23
23
 
24
24
  - **Input slice** (the orchestrator builds it): `core.md`.
25
25
  - **Procedure + return contract** (the ONE source): the agent file —
26
- `phase=review` and `phase=security` → `.claude/agents/orc-reviewer-opus-5-med.md`;
26
+ `phase=review` and `phase=security` → `.claude/agents/orc-reviewer-opus-5-low.md`;
27
27
  `phase=verify` → `.claude/agents/orc-verifier-opus-5-med.md`.
28
28
  - **Validator** (the caller checks every return against it):
29
29
  `../../../_shared/return-validation.md`. A malformed return is treated as
30
30
  failure by the caller.
31
31
 
32
32
  Fixed models (from `../../references/effort-and-mode.md`): review on the OpenSpec/self
33
- path = Opus 5.5 medium; review on the Superpowers path is delegated to the
33
+ path = Opus 5.5 low; review on the Superpowers path is delegated to the
34
34
  Superpowers review skill instead (Sonnet 4.6 medium). Verify = Opus 5.5 medium,
35
35
  always this subskill.
@@ -2,7 +2,7 @@
2
2
 
3
3
  The INPUT SLICE the orchestrator builds for ONE review, verify or security
4
4
  dispatch. The procedure and the return contract live in ONE place, the agent
5
- file: `phase=review` and `phase=security` → `.claude/agents/orc-reviewer-opus-5-med.md`;
5
+ file: `phase=review` and `phase=security` → `.claude/agents/orc-reviewer-opus-5-low.md`;
6
6
  `phase=verify` → `.claude/agents/orc-verifier-opus-5-med.md`. The caller owns
7
7
  the auto-fix-once loop and the `tdd_loop_max` repair loop, and validates the
8
8
  return against `../../../_shared/return-validation.md`.
@@ -91,7 +91,9 @@ without the manifest (`../_shared/lane-contract.md` §Phases).
91
91
 
92
92
  ## Phase A — Ingest & detect source mode
93
93
 
94
- Read the source. **Auto-detect** which of three modes applies:
94
+ First `orc lane config orc-analyze --json`. **`habits{}` in it → print
95
+ `habits.line`, read `../_shared/habits.md` NOW**; none → ignore every `(H …)`.
96
+ Then read the source. **Auto-detect** which of three modes applies:
95
97
  - **prose/spec** — a document of narrative requirements, or
96
98
  - **audit/structured** — a document with columns like expectation / notes / result, or
97
99
  - **requirement** — NO document; the user's plain-language request is the source
@@ -213,7 +215,7 @@ exist). Menu rules, relatedness gate, combiner handling:
213
215
  - **Config:** `orc lane config orc-analyze --json`. Obey `effective`, print every line
214
216
  in `announce[]` VERBATIM at preflight, and honour `stops[]` before wave 1.
215
217
  Never merge `.claude/orc.config.yaml` yourself (`../_shared/config-precedence.md`).
216
- - **Habits:** `habits{}` in that answer → `../_shared/habits.md`; else ignore `(H …)`.
218
+ - **Habits:** Phase A, first step.
217
219
  - **Rules:** `orc rules slice --lane orc-analyze --json` is the ONLY assembler
218
220
  (`../_shared/phases/rules.md`). Its `line` prints VERBATIM at preflight.
219
221
 
@@ -10,7 +10,7 @@ description: >
10
10
  template the user fills in themself. Refresh regenerates ONLY stale sections
11
11
  and bumps the file version by 0.0.1. Never trims user-authored content;
12
12
  never touches the orc-wiki pointer block. The skill dispatches the pinned
13
- orc-claude-writer-opus-4-8-high agent — it never writes the file itself.
13
+ orc-claude-writer-opus-5-low agent — it never writes the file itself.
14
14
  ---
15
15
 
16
16
  # ORC-CLAUDE (standalone)
@@ -20,11 +20,11 @@ The target is ALWAYS `<repo root>/CLAUDE.md` of the current working directory
20
20
  never `~/.claude/CLAUDE.md`, even if ORC is installed globally.
21
21
 
22
22
  **Dispatch, don't do.** Whatever model this chat runs on, the skill itself only
23
- selects the mode and spawns `orc-claude-writer-opus-4-8-high` (the pinned
24
- engine) — so the scan + writing always run at Opus 4.8 high regardless of the
25
- caller's tier. When `opus5_only: true` the engine is
26
- `orc-claude-writer-opus-5-med` instead (that mode FORCES it — see
27
- `../_shared/opus5-only.md`), and it then needs an Opus 5.5 main session.
23
+ selects the mode and spawns `orc-claude-writer-opus-5-low` (the pinned
24
+ engine) — so the scan + writing always run at Opus 5.5 low regardless of the
25
+ caller's tier. `opus5_only` does not change this role. The writer is already
26
+ Opus 5.5 low, so that mode has nothing to flip (see `../_shared/opus5-only.md`).
27
+ The writer needs an Opus 5.5 main session in both modes.
28
28
  The one exception: the skill also writes the
29
29
  trace pointer + a few markers around that spawn (behavior-trace logging is
30
30
  permanent; see "Behavior trace"); that
@@ -70,18 +70,18 @@ set in "Behavior trace").
70
70
  `touch the trace file` of that name in the SAME step, BEFORE the spawn (a
71
71
  pointer to a file that does not exist reads as dangling — the hook rotates
72
72
  away from it and the run splits across two files).
73
- 2. Spawn `orc-claude-writer-opus-4-8-high` — or `orc-claude-writer-opus-5-med`
74
- when `opus5_only` — with: `mode`, `repo_root`,
73
+ 2. Spawn `orc-claude-writer-opus-5-low` (also under `opus5_only` — that mode
74
+ does not change this role) with: `mode`, `repo_root`,
75
75
  `budget` (from a `budget=N` argument, else null), and the paths to
76
76
  `references/template.md` + `references/refresh.md`. **Trace:** emit
77
- `DISPATCH orc-claude-writer :: <mode> expect=opus-4-8/high` just before the
78
- spawn (`expect=opus-5/medium` under `opus5_only` — the expectation is
79
- derived from the agent NAME you actually dispatched, never from this line's
80
- default; the hook then adds `SPAWN`/`RETURN` on its own).
77
+ `DISPATCH orc-claude-writer :: <mode> expect=opus-5/low` just before the
78
+ spawn (the expectation is derived from the agent NAME you actually
79
+ dispatched, never from this line's default; the hook then adds
80
+ `SPAWN`/`RETURN` on its own).
81
81
  3. On return, check `actual_model`/`actual_effort` against the pinned tier —
82
82
  mismatch → prepend a tier-downgrade warning to the report. **Trace:** emit
83
83
  `VERIFY writer actual=<model>/<effort> ✅ MATCH` (or
84
- `⛔ DOWNGRADE expected=opus-4-8/high`).
84
+ `⛔ DOWNGRADE expected=opus-5/low`).
85
85
  4. Relay the Phase-3 report verbatim. **Trace:** emit
86
86
  `FINISH :: <mode_ran> CLAUDE.md v<X.Y.Z>` (mode_ran may be `noop`), then
87
87
  delete `log_dir/.current`. Then stop. The skill NEVER writes CLAUDE.md
@@ -175,7 +175,7 @@ Dispatch-only lane: emit ONLY the markers it can truthfully witness — **not**
175
175
  `PHASE`/`SCORE`/`FINDING`/`VERDICT`, because scan/generate/report run INSIDE
176
176
  the writer sub-agent and there is no scoring or review here. The marker set, in
177
177
  order (actor `orc`, plus the hook's `SPAWN`/`RETURN`): `DISPATCH
178
- orc-claude-writer :: <mode> expect=opus-4-8/high` before the spawn (the mode
178
+ orc-claude-writer :: <mode> expect=opus-5/low` before the spawn (the mode
179
179
  rides in this tail and in `FINISH`, so no separate mode marker) · `VERIFY writer
180
180
  actual=<model>/<effort>` · `FINISH :: <mode_ran> CLAUDE.md v<X.Y.Z>`, where
181
181
  `mode_ran` may be `noop`. A noop refresh still traces the full cycle.
@@ -1,65 +1,65 @@
1
- # Worked example — orc-claude runs (mock; orient only, never execute from this)
2
-
3
- ## Run 1 — UPDATE (existing hand-written CLAUDE.md, 610 lines)
4
-
5
- U: /orc-claude
6
- C: CLAUDE.md exists, no orc-claude:meta header → UPDATE mode. Spawns
7
- orc-claude-writer-opus-4-8-high (the skill never writes the file itself).
8
- W: Scans: pnpm monorepo (3 workspaces), turbo, eslint+prettier, vitest,
9
- Postgres migrations under `packages/db/migrations`.
10
- W: Copies CLAUDE.md → CLAUDE.md.bak. Injects meta header (v0.0.1, 12-07-2026,
11
- line-budget: 400) + P0 placeholder at top, appends fenced sections:
12
- commands, layout (ownership map), conventions, boundaries, workflow,
13
- decisions, patterns, gotchas placeholder, testing, environment, glossary
14
- placeholder. Skips `adr` (nothing scannable). Existing 610 lines: untouched.
15
-
16
- ```
17
- ORC-CLAUDE — update → CLAUDE.md v0.0.1 (12-07-2026)
18
- Sections written: p0*, commands, layout, conventions, boundaries, workflow,
19
- decisions, patterns, gotchas*, testing, environment, glossary* (*=fill yourself)
20
- Skipped (empty scan): adr, pointers
21
- Preserved untouched: user content (610 lines), no wiki block found
22
- Conflicts flagged (NOT auto-edited):
23
- - existing line 42 says "run yarn test" — repo uses pnpm (pnpm test)
24
- Backup: CLAUDE.md.bak written (add it to .gitignore)
25
- NOTE: file is 802 lines total (budget covers generated content only) — trim
26
- unused user content yourself for better instruction-following.
27
- ```
28
-
29
- ## Run 2 — REFRESH, one stale section
30
-
31
- U: /orc-claude (weeks later; `test` script renamed to `test:unit` + `test:e2e`)
32
- C: Header found → REFRESH → spawns the writer.
33
- W: Recomputes fingerprints: only `commands` differs (e3f1a2 → 8c04b1). Writes
34
- .bak, replaces the commands fence interior, bumps 0.0.1 → 0.0.2,
35
- updated: 03-08-2026. User's edits outside fences + the wiki block:
36
- byte-identical. Returns actual_model=claude-opus-4-8, actual_effort=high.
37
-
38
- ## Run 3 — REFRESH, noop
39
-
40
- U: /orc-claude
41
- W: All fingerprints match →
42
- `CLAUDE.md up to date (v0.0.2, 03-08-2026)` — no write, no bump, no bak.
43
-
44
- ## Run 4 — behavior trace (permanent, always on)
45
-
46
- Same dispatch as any run, plus the minimal one-dispatch trace. The skill writes
47
- the run pointer (`run-claude-<slug>-<DDMMYY>-<HHMMSS>.txt` into `log_dir`)
48
- FIRST, records these events as they happen, and — as a single-dispatch lane —
49
- dispatches the trace writer ONCE at run end to append them (`SPAWN`/`RETURN`
50
- come from the `orc-trace.js` hook as they occur):
51
-
52
- ```
53
- [120726 09:14:02.110] writer DISPATCH orc-claude-writer :: refresh expect=opus-4-8/high
54
- [120726 09:14:02.230] hook SPAWN orc-claude-writer-opus-4-8-high
55
- [120726 09:15:47.900] hook RETURN
56
- [120726 09:15:48.010] writer VERIFY writer actual=claude-opus-4-8/high ✅ MATCH
57
- [120726 09:15:48.120] writer FINISH :: refresh CLAUDE.md v0.0.3
58
- ```
59
-
60
- Then the writer packet returns and the run pointer is deleted (in that order).
61
- A noop refresh traces the same shape, ending
62
- `FINISH :: noop`. No phase/score/gate/finding/verdict markers — orc-claude
63
- runs none of those phases (they live inside the writer). The `orc-trace.js` hook
64
- bootstraps the pointer on the writer dispatch, so the SPAWN/RETURN skeleton is
65
- captured even if the skill's run-start step is skipped.
1
+ # Worked example — orc-claude runs (mock; orient only, never execute from this)
2
+
3
+ ## Run 1 — UPDATE (existing hand-written CLAUDE.md, 610 lines)
4
+
5
+ U: /orc-claude
6
+ C: CLAUDE.md exists, no orc-claude:meta header → UPDATE mode. Spawns
7
+ orc-claude-writer-opus-5-low (the skill never writes the file itself).
8
+ W: Scans: pnpm monorepo (3 workspaces), turbo, eslint+prettier, vitest,
9
+ Postgres migrations under `packages/db/migrations`.
10
+ W: Copies CLAUDE.md → CLAUDE.md.bak. Injects meta header (v0.0.1, 12-07-2026,
11
+ line-budget: 400) + P0 placeholder at top, appends fenced sections:
12
+ commands, layout (ownership map), conventions, boundaries, workflow,
13
+ decisions, patterns, gotchas placeholder, testing, environment, glossary
14
+ placeholder. Skips `adr` (nothing scannable). Existing 610 lines: untouched.
15
+
16
+ ```
17
+ ORC-CLAUDE — update → CLAUDE.md v0.0.1 (12-07-2026)
18
+ Sections written: p0*, commands, layout, conventions, boundaries, workflow,
19
+ decisions, patterns, gotchas*, testing, environment, glossary* (*=fill yourself)
20
+ Skipped (empty scan): adr, pointers
21
+ Preserved untouched: user content (610 lines), no wiki block found
22
+ Conflicts flagged (NOT auto-edited):
23
+ - existing line 42 says "run yarn test" — repo uses pnpm (pnpm test)
24
+ Backup: CLAUDE.md.bak written (add it to .gitignore)
25
+ NOTE: file is 802 lines total (budget covers generated content only) — trim
26
+ unused user content yourself for better instruction-following.
27
+ ```
28
+
29
+ ## Run 2 — REFRESH, one stale section
30
+
31
+ U: /orc-claude (weeks later; `test` script renamed to `test:unit` + `test:e2e`)
32
+ C: Header found → REFRESH → spawns the writer.
33
+ W: Recomputes fingerprints: only `commands` differs (e3f1a2 → 8c04b1). Writes
34
+ .bak, replaces the commands fence interior, bumps 0.0.1 → 0.0.2,
35
+ updated: 03-08-2026. User's edits outside fences + the wiki block:
36
+ byte-identical. Returns actual_model=claude-opus-4-8, actual_effort=high.
37
+
38
+ ## Run 3 — REFRESH, noop
39
+
40
+ U: /orc-claude
41
+ W: All fingerprints match →
42
+ `CLAUDE.md up to date (v0.0.2, 03-08-2026)` — no write, no bump, no bak.
43
+
44
+ ## Run 4 — behavior trace (permanent, always on)
45
+
46
+ Same dispatch as any run, plus the minimal one-dispatch trace. The skill writes
47
+ the run pointer (`run-claude-<slug>-<DDMMYY>-<HHMMSS>.txt` into `log_dir`)
48
+ FIRST, records these events as they happen, and — as a single-dispatch lane —
49
+ dispatches the trace writer ONCE at run end to append them (`SPAWN`/`RETURN`
50
+ come from the `orc-trace.js` hook as they occur):
51
+
52
+ ```
53
+ [120726 09:14:02.110] writer DISPATCH orc-claude-writer :: refresh expect=opus-5/low
54
+ [120726 09:14:02.230] hook SPAWN orc-claude-writer-opus-5-low
55
+ [120726 09:15:47.900] hook RETURN
56
+ [120726 09:15:48.010] writer VERIFY writer actual=claude-opus-5-5/low ✅ MATCH
57
+ [120726 09:15:48.120] writer FINISH :: refresh CLAUDE.md v0.0.3
58
+ ```
59
+
60
+ Then the writer packet returns and the run pointer is deleted (in that order).
61
+ A noop refresh traces the same shape, ending
62
+ `FINISH :: noop`. No phase/score/gate/finding/verdict markers — orc-claude
63
+ runs none of those phases (they live inside the writer). The `orc-trace.js` hook
64
+ bootstraps the pointer on the writer dispatch, so the SPAWN/RETURN skeleton is
65
+ captured even if the skill's run-start step is skipped.