@azure-id/orc 2.1.1 → 2.2.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 (145) hide show
  1. package/CHANGELOG.md +320 -0
  2. package/README.md +48 -23
  3. package/bin/build-agents.js +207 -205
  4. package/bin/cli.js +48188 -47417
  5. package/bin/fix.js +21 -18
  6. package/bin/graph-extract.js +314 -6
  7. package/bin/graph-gain.js +83 -2
  8. package/bin/graph-map.js +23 -1
  9. package/bin/graph-notes.js +1 -1
  10. package/bin/graph-query.js +1362 -37
  11. package/bin/graph-resolve.js +1 -1
  12. package/bin/graph-shard.js +29 -6
  13. package/bin/graph-signals.js +5 -3
  14. package/bin/graph.js +7 -3
  15. package/bin/habit.js +1 -1
  16. package/bin/pricing.json +8 -1
  17. package/bin/trace-write.js +40 -11
  18. package/bin/verify-contracts.js +5661 -5552
  19. package/bin/verify-package.js +716 -716
  20. package/bin/webui/api.js +8 -0
  21. package/bin/webui/fixtures/extra.js +2036 -2036
  22. package/bin/webui/fixtures/flow.js +1 -1
  23. package/bin/webui/fixtures/index.js +2 -2
  24. package/bin/webui/fixtures/knowledge.js +8 -1
  25. package/bin/webui/fixtures/pact.js +112 -111
  26. package/bin/webui/fixtures/stats.js +2 -2
  27. package/bin/webui/i18n/en/knowledge.json +2 -0
  28. package/bin/webui/i18n/id/knowledge.json +2 -0
  29. package/bin/webui/js/panels/knowledge.js +17 -0
  30. package/guides/code-graph-benefit.md +116 -0
  31. package/guides/configuration.md +150 -0
  32. package/guides/documents.md +262 -0
  33. package/guides/extra-models.md +448 -0
  34. package/guides/habits-and-gotchas.md +152 -0
  35. package/guides/knowledge-reads.md +190 -0
  36. package/guides/model-selection.md +186 -0
  37. package/guides/rules.md +305 -0
  38. package/guides/status-line.md +344 -0
  39. package/mock-run/orc-cli.md +3 -2
  40. package/mock-run/orc-doc.md +452 -448
  41. package/mock-run/orc.md +157 -157
  42. package/package.json +2 -1
  43. package/templates/agents/MODEL-MAPPING.md +176 -176
  44. package/templates/agents/{orc-executor-haiku-4-5.md → orc-executor-haiku-5-high.md} +21 -8
  45. package/templates/agents/orc-executor-opus-4-7-high.md +17 -5
  46. package/templates/agents/orc-executor-opus-4-7-med.md +17 -5
  47. package/templates/agents/orc-executor-opus-4-8-high.md +17 -5
  48. package/templates/agents/orc-executor-opus-5-high.md +17 -5
  49. package/templates/agents/orc-executor-opus-5-low.md +17 -5
  50. package/templates/agents/orc-executor-opus-5-med.md +17 -5
  51. package/templates/agents/orc-executor-sonnet-4-6-high.md +17 -5
  52. package/templates/agents/orc-executor-sonnet-5-high.md +17 -5
  53. package/templates/agents/orc-executor-sonnet-5-low.md +17 -5
  54. package/templates/agents/orc-executor-sonnet-5-med.md +17 -5
  55. package/templates/agents/{orc-graph-noter-sonnet-4-6-med.md → orc-graph-noter-haiku-5-high.md} +4 -4
  56. package/templates/agents/orc-planner-mini-opus-5-med.md +3 -1
  57. package/templates/agents/orc-planner-mini-sonnet-5-high.md +3 -1
  58. package/templates/agents/orc-planner-opus-5-med.md +3 -1
  59. package/templates/agents/{orc-trace-writer-haiku-4-5.md → orc-trace-writer-haiku-5-high.md} +4 -3
  60. package/templates/commands/orc-doc.md +128 -128
  61. package/templates/commands/orc-export.md +51 -46
  62. package/templates/hooks/README.md +8 -3
  63. package/templates/hooks/orc-effort-guard.js +105 -27
  64. package/templates/hooks/orc-graph-hook.js +252 -4
  65. package/templates/hooks/orc-statusline.js +13 -6
  66. package/templates/hooks/orc-trace.js +1 -1
  67. package/templates/skills/_shared/README.md +2 -2
  68. package/templates/skills/_shared/code-graph.md +185 -251
  69. package/templates/skills/_shared/extra-dispatch.md +1331 -1331
  70. package/templates/skills/_shared/lane-contract.md +7 -3
  71. package/templates/skills/_shared/opus5-only.md +137 -137
  72. package/templates/skills/_shared/phases/execution.md +13 -11
  73. package/templates/skills/_shared/phases/planning.md +27 -9
  74. package/templates/skills/_shared/phases/preflight.md +3 -3
  75. package/templates/skills/_shared/phases/review.md +4 -3
  76. package/templates/skills/_shared/phases/ship.md +7 -10
  77. package/templates/skills/_shared/phases/summary.md +2 -3
  78. package/templates/skills/_shared/phases/trace-verbs.md +21 -16
  79. package/templates/skills/_shared/phases/trace.md +3 -3
  80. package/templates/skills/_shared/phases/wiki-consult.md +2 -2
  81. package/templates/skills/_shared/pr-templates.md +108 -106
  82. package/templates/skills/_shared/read-ladder.md +8 -2
  83. package/templates/skills/_shared/return-validation.md +10 -6
  84. package/templates/skills/_shared/review-slice.md +1 -1
  85. package/templates/skills/_shared/stack-plan.md +135 -135
  86. package/templates/skills/_shared/wait.md +14 -2
  87. package/templates/skills/context-combiner/SKILL.md +2 -2
  88. package/templates/skills/orc/SKILL.md +227 -227
  89. package/templates/skills/orc/config.md +2 -2
  90. package/templates/skills/orc/examples/full-run-mock.md +74 -74
  91. package/templates/skills/orc/schemas/planning-output.md +3 -0
  92. package/templates/skills/orc-aftermath/SKILL.md +15 -15
  93. package/templates/skills/orc-analyze/SKILL.md +2 -2
  94. package/templates/skills/orc-analyze-mini/SKILL.md +2 -2
  95. package/templates/skills/orc-boundary/SKILL.md +15 -15
  96. package/templates/skills/orc-boundary/references/card.md +81 -78
  97. package/templates/skills/orc-boundary/references/gate.md +113 -113
  98. package/templates/skills/orc-brainstorm/SKILL.md +15 -15
  99. package/templates/skills/orc-budget/SKILL.md +15 -15
  100. package/templates/skills/orc-challenge/README.md +1 -1
  101. package/templates/skills/orc-challenge/SKILL.md +16 -16
  102. package/templates/skills/orc-challenge/examples/council-full-roster.md +1 -1
  103. package/templates/skills/orc-claude/SKILL.md +4 -4
  104. package/templates/skills/orc-claude/examples/claude-run-mock.md +1 -1
  105. package/templates/skills/orc-diy/SKILL.md +2 -2
  106. package/templates/skills/orc-diy/references/blocks/wiki.md +26 -26
  107. package/templates/skills/orc-diy/references/flow-schema.md +2 -2
  108. package/templates/skills/orc-doc/README.md +2 -2
  109. package/templates/skills/orc-doc/SKILL.md +501 -490
  110. package/templates/skills/orc-doc/examples/orc-doc-prd-run.md +12 -1
  111. package/templates/skills/orc-doc/references/chunking.md +6 -4
  112. package/templates/skills/orc-doc/references/gates.md +311 -311
  113. package/templates/skills/orc-doc/references/resume-protocol.md +229 -228
  114. package/templates/skills/orc-explain/SKILL.md +88 -88
  115. package/templates/skills/orc-export/SKILL.md +190 -187
  116. package/templates/skills/orc-fast/SKILL.md +213 -210
  117. package/templates/skills/orc-grill/SKILL.md +245 -245
  118. package/templates/skills/orc-handoff/SKILL.md +11 -11
  119. package/templates/skills/orc-learn/SKILL.md +13 -13
  120. package/templates/skills/orc-learn/examples/learn-run-mock.md +2 -2
  121. package/templates/skills/orc-mini/SKILL.md +12 -12
  122. package/templates/skills/orc-mini/examples/mini-run-mock.md +4 -5
  123. package/templates/skills/orc-pact/SKILL.md +15 -15
  124. package/templates/skills/orc-pact/references/gate.md +70 -70
  125. package/templates/skills/orc-pattern/SKILL.md +3 -3
  126. package/templates/skills/orc-poly/SKILL.md +4 -4
  127. package/templates/skills/orc-poly/examples/poly-run-mock.md +51 -51
  128. package/templates/skills/orc-pr-driver/SKILL.md +4 -3
  129. package/templates/skills/orc-pr-driver/references/orc-run-split.md +108 -99
  130. package/templates/skills/orc-pr-setup/SKILL.md +2 -2
  131. package/templates/skills/orc-quick/README.md +535 -536
  132. package/templates/skills/orc-quick/SKILL.md +29 -32
  133. package/templates/skills/orc-quick/references/context-doc.md +145 -145
  134. package/templates/skills/orc-quick/references/dispatch-gate.md +220 -220
  135. package/templates/skills/orc-quick/references/gh-mode.md +2 -1
  136. package/templates/skills/orc-quick/references/look.md +34 -12
  137. package/templates/skills/orc-retro/SKILL.md +2 -2
  138. package/templates/skills/orc-retro/examples/retro-mock.md +2 -2
  139. package/templates/skills/orc-route/SKILL.md +2 -2
  140. package/templates/skills/orc-test/SKILL.md +6 -3
  141. package/templates/skills/orc-verify/SKILL.md +2 -2
  142. package/templates/skills/orc-wait/SKILL.md +10 -2
  143. package/templates/skills/orc-wiki/SKILL.md +4 -4
  144. package/templates/skills/orc-wiki/references/pattern-prewarm.md +19 -19
  145. package/templates/agents/orc-executor-sonnet-4-6-med.md +0 -155
@@ -1,6 +1,6 @@
1
1
  # Phase — Behavior trace (id: `trace`)
2
2
 
3
- > **Library file.** `orc lane phases <lane> --json` → `trace_grammar` gives this lane's verbs. **A verb not in `trace_grammar` → read `trace-verbs.md`** (the CLOSED set, on demand). Never invent a verb.
3
+ > **Library file.** `orc lane phases <lane> --json` gives `trace_grammar` (the verbs) and `ask_ids` (the ASK question ids) at the top level. **A verb not in `trace_grammar` → read `trace-verbs.md`** (the CLOSED set, on demand). Never invent a verb.
4
4
 
5
5
  <!-- orc:layer core -->
6
6
 
@@ -13,7 +13,7 @@ dispatch and writes the `SPAWN`/`RETURN`/`PHASE-EDGE` skeleton itself. Only
13
13
  ## Narration is WRITTEN BY THE CLI, not remembered (v2.0.0 — the core rule)
14
14
 
15
15
  > **Phase close = pipe the phase packet to `orc trace write --packet -`.**
16
- > Exit ≠ 0 → dispatch `orc-trace-writer-haiku-4-5` with the SAME packet.
16
+ > Exit ≠ 0 → dispatch `orc-trace-writer-haiku-5-high` with the SAME packet.
17
17
 
18
18
  You supply the facts; the CLI holds the pen. You never append lines by hand.
19
19
 
@@ -125,7 +125,7 @@ its REAL timestamp into a phase packet (`PHASE`, `DISPATCH`/`VERIFY` per spawn
125
125
  `actual_model`/`actual_effort` vs expected, surface any ⛔ DOWNGRADE to the user
126
126
  — `SCORE`, `OUTCOME`, `GATE`, `FINDING`/`VERDICT` for whichever gates this flow
127
127
  enabled, `FINISH`, plus `decisions` = the WHY), then pipe it to
128
- `orc trace write --packet -` (exit ≠ 0 → `orc-trace-writer-haiku-4-5`), PAIRED
128
+ `orc trace write --packet -` (exit ≠ 0 → `orc-trace-writer-haiku-5-high`), PAIRED
129
129
  with the next phase's first dispatch. **One packet per ENABLED phase group, minimum 2** — the flow shape is
130
130
  composed, so the packet count is too; a phase this flow turned OFF owes nothing.
131
131
  A phase ending with `zero new trace lines is a protocol violation`.
@@ -70,7 +70,7 @@ in play.
70
70
  config/env work.
71
71
 
72
72
  **Lane delta — orc-fast and orc-mini pass POINTERS, not content:** each selects
73
- 1–3 page PATHS from `wiki/INDEX.md` and puts the paths in its slices with the
73
+ 1–3 page PATHS from `wiki/INDEX.md` (a slice that carries graph anchors lists at most one page) and puts the paths in its slices with the
74
74
  instruction to READ them first (TL;DR for orientation, `Contracts & shapes` for
75
75
  specifics). Neither pastes a wiki body into a slice, and neither reads one into
76
76
  its OWN context — for fast, a Sonnet-medium orchestrator curating wiki prose
@@ -120,7 +120,7 @@ where it is used**, not only where it was selected.
120
120
  gets a wiki continuation naming the docs and the tier AT TIME OF USE:**
121
121
 
122
122
  ```
123
- DISPATCH orc-executor-sonnet-5-high :: T4 modify health API expect=sonnet-5/high
123
+ DISPATCH orc-executor-sonnet-5-high :: T4 modify health API expect=sonnet-5-5/high
124
124
  wiki: FRESH — 2 docs → orc-feature-health.md, orc-reference-api-surface.md
125
125
  ```
126
126
 
@@ -1,106 +1,108 @@
1
- # Shared contract — PR-description template resolution (stacked + regular)
2
-
3
- Canonical, single-copy rule for WHERE a PR body comes from. Read by ORC's
4
- ship-phase stack gate (`orc/subskills/orc-pr/stack-gate.md`), `orc-pr-setup`
5
- (which records the resolved source in the plan) and `orc-pr-driver` (which fills
6
- it per layer). A stacked PR without a real template is a wall of prose in N
7
- copies — so template resolution is a **gate**, not a nicety.
8
-
9
- ## Resolution order (first hit wins — probe, never guess)
10
-
11
- 1. **ORC template** — `.claude/skills/orc/subskills/orc-pr/pr.md`. Counts as
12
- available only when the team REPLACED it: if the file still contains its
13
- `PLACEHOLDER` marker, treat it as **not available** and keep looking.
14
- 2. **Project template** — first existing of
15
- `.github/pull_request_template.md` · `.github/PULL_REQUEST_TEMPLATE.md` ·
16
- any `.github/PULL_REQUEST_TEMPLATE/*.md` (more than one → ask which) ·
17
- `docs/pull_request_template.md` · a `docs/**` file whose name contains both
18
- `pr`/`pull-request` and `template`.
19
- 3. **CLAUDE.md** — a PR-template section in the repo's `CLAUDE.md` (a heading
20
- matching `PR template` / `pull request template`, or a fenced block labelled
21
- as one). Use the section body verbatim as the template.
22
- 4. **Nothing found → RECOMMEND, one question, three options** (below). The user
23
- picks one, pastes their own, or declines.
24
- 5. **User declines every option → the stacked PR is SKIPPED.** Say so in one
25
- line and push/PR the change **regularly**, as one PR. Never invent a house
26
- template and never stack without one — a template is what makes N layer
27
- bodies readable.
28
-
29
- Record the winner as `pr template:` in the stack plan
30
- (`orc | project:<path> | claude.md | picked:<name>`) so the driver never
31
- re-resolves and the two lanes cannot disagree.
32
-
33
- ## The three recommended options (offer all three, with this framing)
34
-
35
- ### Option A — `minimal` (fastest to review; good default for small teams)
36
-
37
- ```markdown
38
- ## What
39
- <one paragraph — what this PR changes>
40
-
41
- ## Why
42
- <the ticket's intent in one or two lines>
43
-
44
- ## How to verify
45
- <commands or steps a reviewer runs>
46
- ```
47
-
48
- ### Option B — `context-first` (best for stacked PRs — carries the layer's place in the chain)
49
-
50
- ```markdown
51
- ## Summary
52
- <what this layer does, one paragraph>
53
-
54
- ## Why this layer exists
55
- <purpose + value class; for FOUNDATION, name the consumer layer>
56
-
57
- ## Not in this PR
58
- <what a reviewer might expect but will find in another layer> → layer <n>
59
-
60
- ## Verification
61
- - build: <command + result>
62
- - tests: <command + result>
63
- - lint: <command + result>
64
-
65
- ## Notes for reviewers
66
- <excluded-from-budget files, risks, rollback>
67
- ```
68
-
69
- ### Option C — `risk-and-rollback` (best for payment/data paths and regulated changes)
70
-
71
- ```markdown
72
- ## Change
73
- <what changes, in behavioral terms>
74
-
75
- ## Blast radius
76
- <surfaces, consumers, data touched>
77
-
78
- ## Risk & mitigation
79
- <what can go wrong; what guards it>
80
-
81
- ## Rollback
82
- <exact revert/flag-off procedure>
83
-
84
- ## Evidence
85
- build · tests · lint · manual checks (commands + results)
86
- ```
87
-
88
- On a pick, offer once to save it as `.github/pull_request_template.md` (a repo
89
- change — never write it unasked). Declined → the template is used for this stack
90
- only and lives in the plan.
91
-
92
- ## Per-layer fill rules (stacked PRs)
93
-
94
- Whatever template wins, every layer's body ALSO carries these four facts —
95
- appended if the template has no home for them:
96
-
97
- - **Layer `n` of `N`** + the ticket, and the stack map GitHub renders above it.
98
- - **Purpose + value class** (`USER | OPERATOR | CONTRACT | FOUNDATION`, with the
99
- consumer layer named for FOUNDATION).
100
- - **Deliberately NOT here** → the layer that has it. This is what stops a
101
- reviewer from rejecting a layer for something the next layer fixes.
102
- - **Excluded-from-budget files**, listed — generated/vendored/lockfiles that the
103
- numbers ignore but the reviewer should still see.
104
-
105
- Regular (unstacked) PRs use the same resolution order and none of the four
106
- layer facts.
1
+ # Shared contract — PR-description template resolution (stacked + regular)
2
+
3
+ Canonical, single-copy rule for WHERE a PR body comes from. Read by ORC's
4
+ ship-phase stack gate (`orc/subskills/orc-pr/stack-gate.md`), `orc-pr-setup`
5
+ (which records the resolved source in the plan) and `orc-pr-driver` (which fills
6
+ it per layer). A stacked PR without a real template is a wall of prose in N
7
+ copies — so template resolution is a **gate**, not a nicety.
8
+
9
+ ## Resolution order (first hit wins — probe, never guess)
10
+
11
+ 1. **ORC template** — `.claude/skills/orc/subskills/orc-pr/pr.md`. Counts as
12
+ available only when the team REPLACED it: if the file still contains its
13
+ `PLACEHOLDER` marker, treat it as **not available** and keep looking.
14
+ 2. **Project template** — first existing of
15
+ `.github/pull_request_template.md` · `.github/PULL_REQUEST_TEMPLATE.md` ·
16
+ any `.github/PULL_REQUEST_TEMPLATE/*.md` (more than one → ask which) ·
17
+ `docs/pull_request_template.md` · a `docs/**` file whose name contains both
18
+ `pr`/`pull-request` and `template`.
19
+ 3. **CLAUDE.md** — a PR-template section in the repo's `CLAUDE.md` (a heading
20
+ matching `PR template` / `pull request template`, or a fenced block labelled
21
+ as one). Use the section body verbatim as the template.
22
+ 4. **Nothing found → RECOMMEND, one question, three options** (below). The user
23
+ picks one, pastes their own, or declines.
24
+ 5. **User declines every option → the stacked PR is SKIPPED.** Say so in one
25
+ line and push/PR the change **regularly**, as one PR. Never invent a house
26
+ template and never stack without one — a template is what makes N layer
27
+ bodies readable.
28
+
29
+ Record the winner as `pr template:` in the stack plan
30
+ (`orc | project:<path> | claude.md | picked:<name>`) so the driver never
31
+ re-resolves and the two lanes cannot disagree.
32
+
33
+ ## The three recommended options (offer all three, with this framing)
34
+
35
+ ### Option A — `minimal` (fastest to review; good default for small teams)
36
+
37
+ ```markdown
38
+ ## What
39
+ <one paragraph — what this PR changes>
40
+
41
+ ## Why
42
+ <the ticket's intent in one or two lines>
43
+
44
+ ## How to verify
45
+ <commands or steps a reviewer runs>
46
+ ```
47
+
48
+ ### Option B — `context-first` (best for stacked PRs — carries the layer's place in the chain)
49
+
50
+ ```markdown
51
+ ## Summary
52
+ <what this layer does, one paragraph>
53
+
54
+ ## Why this layer exists
55
+ <purpose + value class; for FOUNDATION, name the consumer layer>
56
+
57
+ ## Not in this PR
58
+ <what a reviewer might expect but will find in another layer> → layer <n>
59
+
60
+ ## Verification
61
+ - build: <command + result>
62
+ - tests: <command + result>
63
+ - lint: <command + result>
64
+
65
+ ## Notes for reviewers
66
+ <excluded-from-budget files, risks, rollback>
67
+ ```
68
+
69
+ ### Option C — `risk-and-rollback` (best for payment/data paths and regulated changes)
70
+
71
+ ```markdown
72
+ ## Change
73
+ <what changes, in behavioral terms>
74
+
75
+ ## Blast radius
76
+ <surfaces, consumers, data touched>
77
+
78
+ ## Risk & mitigation
79
+ <what can go wrong; what guards it>
80
+
81
+ ## Rollback
82
+ <exact revert/flag-off procedure>
83
+
84
+ ## Evidence
85
+ build · tests · lint · manual checks (commands + results)
86
+ ```
87
+
88
+ On a pick, offer once to save it as `.github/pull_request_template.md` (a repo
89
+ change — never write it unasked). Declined → the template is used for this stack
90
+ only and lives in the plan: `picked:<name>` records the NAME only; a template the
91
+ user pasted goes VERBATIM in one fenced block under `## PR template`, so the
92
+ probe never reads its `<…>` slots.
93
+
94
+ ## Per-layer fill rules (stacked PRs)
95
+
96
+ Whatever template wins, every layer's body ALSO carries these four facts —
97
+ appended if the template has no home for them:
98
+
99
+ - **Layer `n` of `N`** + the ticket, and the stack map GitHub renders above it.
100
+ - **Purpose + value class** (`USER | OPERATOR | CONTRACT | FOUNDATION`, with the
101
+ consumer layer named for FOUNDATION).
102
+ - **Deliberately NOT here** → the layer that has it. This is what stops a
103
+ reviewer from rejecting a layer for something the next layer fixes.
104
+ - **Excluded-from-budget files**, listed — generated/vendored/lockfiles that the
105
+ numbers ignore but the reviewer should still see.
106
+
107
+ Regular (unstacked) PRs use the same resolution order and none of the four
108
+ layer facts.
@@ -18,7 +18,13 @@ Escalate one step at a time. Stop at the step that answers the question.
18
18
 
19
19
  ## Step 0 — ask the graph (always first; the CLI decides if it is on)
20
20
 
21
- Before step 1, run `orc graph ctx <symbol|file[:line]> --if-enabled --json --brief`
21
+ Your slice carries `graph_anchors` (up to 12 `path:a-b` ranges, one `read all:` command and, when present, a fenced block with the code of every range) →
22
+ `graph_anchors` may carry the code of its ranges inline — use it as already read; do NOT read those ranges again. Without the code, your FIRST call prints every range (below). With `graph_anchors`, a wiki page is OPTIONAL: read it only for a business rule that the requirement, the anchors and the code do not settle.
23
+ Your FIRST call prints EVERY range in `graph_anchors` in ONE shell command — the `read all:` line when present, else one `sed -n 'a,bp' <file>` per range joined with `;` and an `echo == <file>:<a>-<b>` header each. Then read further only for what those ranges do not show; do not `cat` a whole anchored file over 150 lines. A file you will EDIT is still read in full first (exception 1). The inline code and the ranges are real bytes of the current blob. Then
24
+ `orc graph ctx <name> --source --if-enabled --json --brief` for a symbol the anchors do not cover.
25
+ Never read again a range the anchors printed.
26
+
27
+ With no `graph_anchors`, before step 1, run `orc graph ctx <symbol|file[:line]> --if-enabled --json --brief`
22
28
  yourself. You do not need to know whether the graph is on. Exit 0 → the card
23
29
  answers step 1 and step 2 together: where the symbol is, its line range, who
24
30
  calls or uses it, what it calls, and which effects it has. Then continue at
@@ -46,7 +52,7 @@ list of candidates. Without an LSP tool, or with `lsp_at: null`, the ladder
46
52
  continues as before.
47
53
 
48
54
  Exit 3 (off) → skip step 0 for the rest of the task. Exit 1 (no index) or 4 (not
49
- in the graph) → step 1 as before. Name the card targets you used in
55
+ in the graph) → step 1 as before. Name the pack or card targets you used in
50
56
  `graph_used`. Both exceptions below apply unchanged.
51
57
  Canonical: `code-graph.md`.
52
58
 
@@ -6,7 +6,7 @@ a failure (requeue/re-dispatch with reason — lane sets the retry cap).
6
6
 
7
7
  **Read the SECTION, not the file.** Every return: §1–§3. Then ONLY the § of
8
8
  each field the slice carried — §4 `pattern`, §5 `tdd_spec`, §5b wiki, §5b.1
9
- graph cards, §5c the rules card, §5d `repro`. §2b only for a foreign return. §0
9
+ the graph pack, §5c the rules card, §5d `repro`. §2b only for a foreign return. §0
10
10
  only before a re-dispatch. §6 only after a wave. §7 only on a repair loop. The §
11
11
  numbers are anchors: never renumber or rename a § heading.
12
12
 
@@ -141,15 +141,19 @@ shipped into every slice and read by nobody is the failure mode this field
141
141
  exists to make visible, and it is invisible if `none` is quietly dropped. Absent
142
142
  on a slice that carried wiki material is malformed. Not required otherwise.
143
143
 
144
- ## 5b.1 Graph attestation (when code-graph cards were injected — v1.8.0)
144
+ ## 5b.1 Graph attestation (when the slice carried `graph_anchors` — v2.2.0)
145
145
 
146
- A task whose slice carried `orc graph ctx` cards must return **`graph_used`** —
147
- `{targets, generation}`: the card targets it ACTUALLY used (or `none`), and the `generation`
148
- the cards carried. The same honesty rule as `wiki_used`: `none` is informative (the cards did
149
- not help), absent is malformed, and a lane never drops it. A `generation` lower than the one
146
+ A task whose slice carried `graph_anchors` (or that ran `orc graph ctx` itself) must return
147
+ **`graph_used`** — `{targets, generation}`: the anchors (`path:a-b`) it ACTUALLY used
148
+ (or `none`), and the `generation` of the anchors call. The same honesty rule as `wiki_used`: `none`
149
+ is informative (the anchors did not help), absent is malformed, and a lane never drops it. A `generation` lower than the one
150
150
  `orc graph status` reports now means the agent acted on an OLD index — record it, do not
151
151
  re-run the task for it alone. Canonical: `code-graph.md`.
152
152
 
153
+ A planner task MAY carry `precedent[]` — read-only files this task copies behaviour or style
154
+ from (max 5). It is OPTIONAL: absent is fine and never makes a plan malformed. When present, the
155
+ lane passes it as the pack's `--refs=`.
156
+
153
157
  ## 5c. Rules attestation (when the anti-slop card was injected — v1.7.0)
154
158
 
155
159
  A slice assembled by `orc rules slice` (`phases/rules.md`) must return three
@@ -65,7 +65,7 @@ that changed files re-runs it first.
65
65
  | `previous_findings[]` | the checkpoint, on a re-review ONLY (R9), each with its outcome |
66
66
  | `mode` | `review` · `disprove` · `security` |
67
67
 
68
- - **`graph_changes`** (`code-graph.md` §7): the symbols THIS diff's hunks overlap,
68
+ - **`graph_changes`** (`code-graph.md` §0 step 4, §7): the symbols THIS diff's hunks overlap,
69
69
  each with its callers, its tests and a risk word that carries its own reason.
70
70
  The reviewer is handed `symbols[].caller_files` and reads them.
71
71
  It replaces a whole-file `orc graph impact` here: a file card reports every symbol in
@@ -1,135 +1,135 @@
1
- # Shared contract — the stack plan (`stack-plan.md`) + the `STACK-FROM` handoff
2
-
3
- Canonical, single-copy contract for stacked pull requests. `orc-pr-setup` WRITES
4
- the plan; `orc-pr-driver` READS it; ORC's ship-phase stack gate
5
- (`orc/subskills/orc-pr/stack-gate.md`) hands off to one or the other. All three
6
- read this file — the schema is never remembered.
7
-
8
- ## Location (one path, no ambiguity)
9
-
10
- ```
11
- stacked-pr/<slug>/stack-plan.md
12
- ```
13
-
14
- Project root, visible, **committed** — same class of deliverable as
15
- `poly-repo-implementation/` and `test-generator/`. Never inside `.claude/`,
16
- never inside the run folder (the installer replaces skill dirs; a plan there
17
- would vanish on `orc update`). `<slug>` is kebab-case from the change or the
18
- ticket (`[a-z0-9-]`, ≤32 chars). The `orc pr stack template [<slug>]` CLI writes
19
- the same path, so a hand-filled plan and a generated one are indistinguishable
20
- to the driver.
21
-
22
- ## Existence probe (deterministic — never an ad-hoc `find`)
23
-
24
- `orc pr stack status [<slug>]` — exit **0** = a READY plan (exists, no unfilled
25
- `<...>` placeholders, ≥2 layers), exit **1** = absent or unfilled. Same
26
- exit-code convention as `orc pattern status <lang>` and `orc diy status`. Run it
27
- FIRST; do not second-guess a positive probe.
28
-
29
- ## Budget mechanics (measured, not estimated)
30
-
31
- Per layer: `git diff --numstat <that layer's base>..<layer head>`.
32
-
33
- - **LoC = additions + deletions** over non-excluded files.
34
- - **Excluded from LoC AND from the file count:** generated code (`*.pb.go`,
35
- `*_gen.go`, mocks, openapi/swagger output), lockfiles (`go.sum`,
36
- `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, `Cargo.lock`,
37
- `poetry.lock`), `vendor/`, `node_modules/`, `testdata/` fixtures, and pure
38
- renames/moves with no content change. Excluded files are still **LISTED in the
39
- PR body** — a reviewer must know they exist.
40
- - **Tests COUNT** toward the budget (they are reviewable code). A layer over
41
- budget *only* because of tests may split its tests into their own layer rather
42
- than splitting logic badly.
43
- - **Ceilings** come from config (`orc/config.md`): `stacked_pr_loc` (default
44
- 1000) is the per-layer LoC hard max; `stacked_pr_files` (default 20) is the
45
- hard max file count, with **half of it the soft target**. Over either → split,
46
- or the user explicitly overrides and the override is logged under
47
- `## Accepted exceptions`.
48
- - **Sizing beats budget-gaming.** A 999-LoC / 20-file layer that mixes handler +
49
- migration is a FAIL even though it is under budget. The budget is a ceiling,
50
- not a definition of a good layer.
51
- - **Unsplittable atom:** when the smallest coherent unit alone exceeds a ceiling,
52
- do NOT fake-split it — flag it, state why, and ask the user to accept the
53
- oversized layer (the P0 gate path).
54
- - **Layer cap** `stacked_pr_max_layers` (default 6): ≤ cap proceed · cap+1..cap+2
55
- warn and require an explicit user override · beyond that **STOP** and
56
- recommend multiple stacks or a phased release. N layers = N full CI runs.
57
-
58
- ## Schema (the contract between the lanes)
59
-
60
- ```markdown
61
- # Stack plan: <feature>
62
-
63
- - ticket: <TICKET-123> # REQUIRED — branch names and layer titles derive from it
64
- - repo: <owner/name> # same repo for every layer (cross-fork is unsupported)
65
- - trunk: <main> # the bottom layer's base
66
- - entry mode: greenfield | orc-run # orc-run = ORC already built the change (file-granular split)
67
- - pr template: <resolved source> # orc | project:<path> | claude.md | picked:<name>
68
- - totals: <LoC> LoC · <n> files · <n> layers
69
-
70
- ## Layers
71
- | # | branch | purpose (1 line) | value class | files | LoC | depends on | build-alone? |
72
- |---|--------|------------------|-------------|-------|-----|------------|--------------|
73
-
74
- ## Layer <n> — <title>
75
- - Purpose: <one line — no purpose means it is not a layer>
76
- - Value class: USER | OPERATOR | CONTRACT | FOUNDATION (+ consumer layer if FOUNDATION)
77
- - Files: <explicit list — every path, no globs>
78
- - Excluded-from-budget files: <listed, uncounted>
79
- - Deliberately NOT here: <what a reviewer might expect> → layer <m>
80
- - Green-gate commands: build · test scope · lint scope (`--new-from-rev <this layer's base>`)
81
- - Gate status: GREEN | RED <step> | NOT RUN
82
- - Risk / rollback: <one line>
83
-
84
- ## Decisions
85
- <every P0 gate answer: boundary, the options offered, what the user chose, why>
86
-
87
- ## Accepted exceptions
88
- <over-budget layers, oversize atoms, FOUNDATION chains, layer-cap overrides>
89
- ```
90
-
91
- **Driver hard gate:** a plan with an unanswered UNCERTAIN, a missing ticket, a
92
- layer with no purpose or no value class, a FOUNDATION layer naming no consumer,
93
- or fewer than 2 layers is **not runnable**. The driver says which field is
94
- missing and stops — it never fills a field in for the user.
95
-
96
- ## The `STACK-FROM` handoff block
97
-
98
- Written into the stack-plan folder as `stacked-pr/<slug>/STACK-FROM.md` by
99
- whoever hands off (ORC's ship gate, or `orc-pr-setup` → `orc-pr-driver`). Same
100
- shape as `_shared/fallback-handoff.md`: the writer announces one line, writes the
101
- block, then invokes the reader pointing at it.
102
-
103
- ```
104
- STACK-FROM: orc-ship | orc-pr-setup
105
- TICKET: <TICKET-123>
106
- SLUG: <kebab-slug>
107
- PLAN: stacked-pr/<slug>/stack-plan.md # or "none — plan the layers first"
108
- ENTRY-MODE: greenfield | orc-run
109
- PR-TEMPLATE: orc | project:<path> | claude.md | picked:<name>
110
- CHANGE: <one-line description of the change being stacked>
111
- SURFACE: <n> files · <n> LoC (excluded paths already removed)
112
- RUN-DIR: <.claude/orc/run/{run-slug}/ if an ORC run produced the change, else "none">
113
- BUILD-GREEN: true | false # false is a hard stop — never stack a red build
114
- ```
115
-
116
- **Reader side.** Acknowledge the source + ticket in one line, run the existence
117
- probe, and skip anything already carried: an attached PLAN replaces the planner
118
- lane entirely; `ENTRY-MODE: orc-run` means the code is ALREADY in the worktree,
119
- so the driver splits what exists (file-granular, below) instead of writing code;
120
- a `RUN-DIR` gives the driver the run's task graph, acceptance criteria, and
121
- verify evidence for free.
122
-
123
- ## Entry modes (exactly two)
124
-
125
- - **`greenfield`** — nothing is written yet. Plan the layers up front, then build
126
- layer by layer. The cheapest, cleanest path.
127
- - **`orc-run`** — an ORC build already produced the whole change in the worktree.
128
- The split is **FILE-GRANULAR ONLY**: each changed file belongs to exactly one
129
- layer, and ORC's per-task `declared_files` is the seam evidence. **Hunk surgery
130
- is forbidden** — a file whose content belongs in two layers is an UNCERTAIN, and
131
- the default answer offered is "the whole file lands in the LOWEST layer that
132
- needs it".
133
-
134
- Splitting an already-open fat PR (the retro case, `gh stack link`) is **out of
135
- scope**: say so and ship the change as one regular PR instead.
1
+ # Shared contract — the stack plan (`stack-plan.md`) + the `STACK-FROM` handoff
2
+
3
+ Canonical, single-copy contract for stacked pull requests. `orc-pr-setup` WRITES
4
+ the plan; `orc-pr-driver` READS it; ORC's ship-phase stack gate
5
+ (`orc/subskills/orc-pr/stack-gate.md`) hands off to one or the other. All three
6
+ read this file — the schema is never remembered.
7
+
8
+ ## Location (one path, no ambiguity)
9
+
10
+ ```
11
+ stacked-pr/<slug>/stack-plan.md
12
+ ```
13
+
14
+ Project root, visible, **committed** — same class of deliverable as
15
+ `poly-repo-implementation/` and `test-generator/`. Never inside `.claude/`,
16
+ never inside the run folder (the installer replaces skill dirs; a plan there
17
+ would vanish on `orc update`). `<slug>` is kebab-case from the change or the
18
+ ticket (`[a-z0-9-]`, ≤32 chars). The `orc pr stack template [<slug>]` CLI writes
19
+ the same path, so a hand-filled plan and a generated one are indistinguishable
20
+ to the driver.
21
+
22
+ ## Existence probe (deterministic — never an ad-hoc `find`)
23
+
24
+ `orc pr stack status [<slug>]` — exit **0** = a READY plan (exists, no unfilled
25
+ `<...>` placeholder outside an HTML comment or a fenced block, ≥2 layers), exit **1** = absent or unfilled. Same
26
+ exit-code convention as `orc pattern status <lang>` and `orc diy status`. Run it
27
+ FIRST; do not second-guess a positive probe.
28
+
29
+ ## Budget mechanics (measured, not estimated)
30
+
31
+ Per layer: `git diff --numstat <that layer's base>..<layer head>`.
32
+
33
+ - **LoC = additions + deletions** over non-excluded files.
34
+ - **Excluded from LoC AND from the file count:** generated code (`*.pb.go`,
35
+ `*_gen.go`, mocks, openapi/swagger output), lockfiles (`go.sum`,
36
+ `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, `Cargo.lock`,
37
+ `poetry.lock`), `vendor/`, `node_modules/`, `testdata/` fixtures, and pure
38
+ renames/moves with no content change. Excluded files are still **LISTED in the
39
+ PR body** — a reviewer must know they exist.
40
+ - **Tests COUNT** toward the budget (they are reviewable code). A layer over
41
+ budget *only* because of tests may split its tests into their own layer rather
42
+ than splitting logic badly.
43
+ - **Ceilings** come from config (`orc/config.md`): `stacked_pr_loc` (default
44
+ 1000) is the per-layer LoC hard max; `stacked_pr_files` (default 20) is the
45
+ hard max file count, with **half of it the soft target**. Over either → split,
46
+ or the user explicitly overrides and the override is logged under
47
+ `## Accepted exceptions`.
48
+ - **Sizing beats budget-gaming.** A 999-LoC / 20-file layer that mixes handler +
49
+ migration is a FAIL even though it is under budget. The budget is a ceiling,
50
+ not a definition of a good layer.
51
+ - **Unsplittable atom:** when the smallest coherent unit alone exceeds a ceiling,
52
+ do NOT fake-split it — flag it, state why, and ask the user to accept the
53
+ oversized layer (the P0 gate path).
54
+ - **Layer cap** `stacked_pr_max_layers` (default 6): ≤ cap proceed · cap+1..cap+2
55
+ warn and require an explicit user override · beyond that **STOP** and
56
+ recommend multiple stacks or a phased release. N layers = N full CI runs.
57
+
58
+ ## Schema (the contract between the lanes)
59
+
60
+ ```markdown
61
+ # Stack plan: <feature>
62
+
63
+ - ticket: <TICKET-123> # REQUIRED — branch names and layer titles derive from it
64
+ - repo: <owner/name> # same repo for every layer (cross-fork is unsupported)
65
+ - trunk: <main> # the bottom layer's base
66
+ - entry mode: greenfield | orc-run # orc-run = ORC already built the change (file-granular split)
67
+ - pr template: <resolved source> # orc | project:<path> | claude.md | picked:<name>
68
+ - totals: <LoC> LoC · <n> files · <n> layers
69
+
70
+ ## Layers
71
+ | # | branch | purpose (1 line) | value class | files | LoC | depends on | build-alone? |
72
+ |---|--------|------------------|-------------|-------|-----|------------|--------------|
73
+
74
+ ## Layer <n> — <title>
75
+ - Purpose: <one line — no purpose means it is not a layer>
76
+ - Value class: USER | OPERATOR | CONTRACT | FOUNDATION (+ consumer layer if FOUNDATION)
77
+ - Files: <explicit list — every path, no globs>
78
+ - Excluded-from-budget files: <listed, uncounted>
79
+ - Deliberately NOT here: <what a reviewer might expect> → layer <m>
80
+ - Green-gate commands: build · test scope · lint scope (`--new-from-rev <this layer's base>`)
81
+ - Gate status: GREEN | RED <step> | NOT RUN
82
+ - Risk / rollback: <one line>
83
+
84
+ ## Decisions
85
+ <every P0 gate answer: boundary, the options offered, what the user chose, why>
86
+
87
+ ## Accepted exceptions
88
+ <over-budget layers, oversize atoms, FOUNDATION chains, layer-cap overrides>
89
+ ```
90
+
91
+ **Driver hard gate:** a plan with an unanswered UNCERTAIN, a missing ticket, a
92
+ layer with no purpose or no value class, a FOUNDATION layer naming no consumer,
93
+ or fewer than 2 layers is **not runnable**. The driver says which field is
94
+ missing and stops — it never fills a field in for the user.
95
+
96
+ ## The `STACK-FROM` handoff block
97
+
98
+ Written into the stack-plan folder as `stacked-pr/<slug>/STACK-FROM.md` by
99
+ whoever hands off (ORC's ship gate, or `orc-pr-setup` → `orc-pr-driver`). Same
100
+ shape as `_shared/fallback-handoff.md`: the writer announces one line, writes the
101
+ block, then invokes the reader pointing at it.
102
+
103
+ ```
104
+ STACK-FROM: orc-ship | orc-pr-setup
105
+ TICKET: <TICKET-123>
106
+ SLUG: <kebab-slug>
107
+ PLAN: stacked-pr/<slug>/stack-plan.md # or "none — plan the layers first"
108
+ ENTRY-MODE: greenfield | orc-run
109
+ PR-TEMPLATE: orc | project:<path> | claude.md | picked:<name>
110
+ CHANGE: <one-line description of the change being stacked>
111
+ SURFACE: <n> files · <n> LoC (excluded paths already removed)
112
+ RUN-DIR: <.claude/orc/run/{run-slug}/ if an ORC run produced the change, else "none">
113
+ BUILD-GREEN: true | false # false is a hard stop — never stack a red build
114
+ ```
115
+
116
+ **Reader side.** Acknowledge the source + ticket in one line, run the existence
117
+ probe, and skip anything already carried: an attached PLAN replaces the planner
118
+ lane entirely; `ENTRY-MODE: orc-run` means the code is ALREADY in the worktree,
119
+ so the driver splits what exists (file-granular, below) instead of writing code;
120
+ a `RUN-DIR` gives the driver the run's task graph, acceptance criteria, and
121
+ verify evidence for free.
122
+
123
+ ## Entry modes (exactly two)
124
+
125
+ - **`greenfield`** — nothing is written yet. Plan the layers up front, then build
126
+ layer by layer. The cheapest, cleanest path.
127
+ - **`orc-run`** — an ORC build already produced the whole change in the worktree.
128
+ The split is **FILE-GRANULAR ONLY**: each changed file belongs to exactly one
129
+ layer, and ORC's per-task `declared_files` is the seam evidence. **Hunk surgery
130
+ is forbidden** — a file whose content belongs in two layers is an UNCERTAIN, and
131
+ the default answer offered is "the whole file lands in the LOWEST layer that
132
+ needs it".
133
+
134
+ Splitting an already-open fat PR (the retro case, `gh stack link`) is **out of
135
+ scope**: say so and ship the change as one regular PR instead.
@@ -132,14 +132,23 @@ no model runs during it.
132
132
 
133
133
  ```
134
134
  1. Write the hand-back for the mode (above).
135
+ 1a. `orc wait start <spec> --mode <m> --trigger <user|gate>`
135
136
  2. remaining = the requested time, or resets_at - now
136
137
  3. hop = min(wait_hop_minutes, remaining)
137
138
  4. Run a DETACHED command that waits hop seconds.
138
139
  5. On wake: `orc usage check --json`
139
140
  6. Exit 0, or the requested time has elapsed → continue. Else go to 3.
140
141
  7. wait_max_hops reached → stop, keep the hand-back, say why.
142
+ 8. `orc wait end --reason <elapsed|recovered|cancelled|max-hops>`
141
143
  ```
142
144
 
145
+ Steps 1a and 8 are how the CLI knows a wait is running: `orc wait start` records
146
+ it in `wait.json` and `orc wait end` closes it. The computed gate passes
147
+ `--trigger gate`. With no run in flight, `start` records nothing and answers
148
+ `recorded: false`; that is an answer, and the wait continues. A wait's activity
149
+ is COMPUTED from its start and the clock, so a wait that a dead session left
150
+ open reads `stale` in `orc wait status`, never `waiting`.
151
+
143
152
  **A hop is short on purpose.** Each wake-up is session activity, and session
144
153
  activity is the only thing that makes the statusline run again — so each hop
145
154
  buys a fresh reading. A single long sleep wakes into a reading as stale as the
@@ -233,10 +242,13 @@ in the trace enum and has no `run-<lane>-<slug>` pointer — the `/orc-explain`
233
242
  precedent, a stated blind spot rather than an oversight.
234
243
 
235
244
  ```
236
- WAIT mode=hard requested=30m start=18:44 end=19:14 hops=1/4 trigger=user
237
- WAIT block reason="window resets in 5m, task needs 10" by=user
245
+ WAIT mode=hard requested=30m start=18:44 end=19:14 hops=1/5 trigger=user
246
+ WAIT end :: done=1/1 reason=elapsed
247
+ WAIT block :: reason="window resets in 5m, task needs 10" by=user
238
248
  WAIT unblock
239
249
  ```
240
250
 
251
+ `hops=` is planned hops / `wait_max_hops`.
252
+
241
253
  A wait that leaves no line cannot be counted, and a block that leaves no line
242
254
  hides the fact that a run continued through a gate on the user's authority.