@azure-id/orc 1.9.1 → 2.0.2

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 (224) hide show
  1. package/CHANGELOG.md +390 -0
  2. package/README-id.md +20 -36
  3. package/README.md +24 -34
  4. package/bin/build-agents.js +206 -109
  5. package/bin/cli.js +760 -62
  6. package/bin/gotcha-import.js +1081 -0
  7. package/bin/gotcha.js +1286 -0
  8. package/bin/graph-query.js +1 -1
  9. package/bin/graph.js +717 -717
  10. package/bin/habit.js +1453 -0
  11. package/bin/mockrun-catalog.js +281 -276
  12. package/bin/onboarding-content.js +4 -4
  13. package/bin/pricing.json +207 -200
  14. package/bin/run-undo.js +398 -0
  15. package/bin/trace-write.js +657 -0
  16. package/bin/verify-contracts.js +527 -81
  17. package/bin/verify-package.js +58 -11
  18. package/bin/webui/api.js +26 -0
  19. package/bin/webui/app.html +239 -232
  20. package/bin/webui/css/00-tokens.css +110 -92
  21. package/bin/webui/css/04-motion.css +249 -152
  22. package/bin/webui/css/06-responsive.css +203 -178
  23. package/bin/webui/css/panels/behaviour.css +205 -0
  24. package/bin/webui/css/panels/knowledge.css +563 -116
  25. package/bin/webui/fixtures/behaviour.js +532 -0
  26. package/bin/webui/fixtures/extra.js +2036 -2036
  27. package/bin/webui/fixtures/hookui.js +5 -5
  28. package/bin/webui/fixtures/index.js +34 -0
  29. package/bin/webui/fixtures/knowledge.js +7 -1
  30. package/bin/webui/fixtures/settings.js +305 -305
  31. package/bin/webui/fixtures/stats.js +16 -0
  32. package/bin/webui/i18n/en/behaviour.json +143 -0
  33. package/bin/webui/i18n/en/knowledge.json +117 -2
  34. package/bin/webui/i18n/en/nav.json +25 -24
  35. package/bin/webui/i18n/en/tour.json +37 -35
  36. package/bin/webui/i18n/id/behaviour.json +143 -0
  37. package/bin/webui/i18n/id/knowledge.json +117 -2
  38. package/bin/webui/i18n/id/nav.json +25 -24
  39. package/bin/webui/i18n/id/tour.json +37 -35
  40. package/bin/webui/js/01-i18n.js +155 -154
  41. package/bin/webui/js/90-tour.js +498 -494
  42. package/bin/webui/js/91-shortcuts.js +126 -126
  43. package/bin/webui/js/99-boot.js +121 -118
  44. package/bin/webui/js/panels/behaviour.js +1022 -0
  45. package/bin/webui/js/panels/knowledge.js +552 -7
  46. package/bin/webui/js/panels/overview.js +13 -4
  47. package/mock-run/INDEX.md +109 -107
  48. package/mock-run/context-combiner.md +100 -100
  49. package/mock-run/gotcha-import.md +118 -0
  50. package/mock-run/habits.md +129 -0
  51. package/mock-run/orc-budget.md +534 -534
  52. package/mock-run/orc-challenge-council.md +262 -262
  53. package/mock-run/orc-quick.md +6 -1
  54. package/mock-run/orc-ultra.md +103 -103
  55. package/package.json +1 -1
  56. package/templates/agents/MODEL-MAPPING.md +49 -49
  57. package/templates/agents/orc-advisor-opus-5-xhigh.md +50 -56
  58. package/templates/agents/orc-analyze-mini-opus-5-med.md +55 -60
  59. package/templates/agents/orc-analyze-mini-sonnet-5-high.md +55 -58
  60. package/templates/agents/orc-challenge-advisor-opus-5-med.md +75 -75
  61. package/templates/agents/orc-challenge-contrarian-opus-5-high.md +110 -110
  62. package/templates/agents/orc-challenge-executor-opus-5-med.md +114 -114
  63. package/templates/agents/orc-challenge-expansionist-opus-5-med.md +112 -112
  64. package/templates/agents/orc-challenge-judge-opus-5-high.md +132 -132
  65. package/templates/agents/orc-challenge-outsider-opus-5-low.md +109 -109
  66. package/templates/agents/orc-challenge-principles-opus-5-high.md +109 -109
  67. package/templates/agents/orc-challenge-reader-opus-5-low.md +90 -90
  68. package/templates/agents/orc-claude-writer-opus-4-8-high.md +48 -53
  69. package/templates/agents/orc-claude-writer-opus-5-med.md +48 -55
  70. package/templates/agents/orc-context-combiner-opus-5-high.md +78 -88
  71. package/templates/agents/orc-doc-checker-opus-5-low.md +108 -108
  72. package/templates/agents/orc-doc-writer-opus-5-med.md +134 -134
  73. package/templates/agents/orc-executor-haiku-4-5.md +14 -6
  74. package/templates/agents/orc-executor-opus-4-7-high.md +14 -6
  75. package/templates/agents/orc-executor-opus-4-7-med.md +14 -6
  76. package/templates/agents/orc-executor-opus-4-8-high.md +14 -6
  77. package/templates/agents/orc-executor-opus-5-high.md +15 -7
  78. package/templates/agents/orc-executor-opus-5-low.md +15 -7
  79. package/templates/agents/orc-executor-opus-5-med.md +15 -7
  80. package/templates/agents/orc-executor-sonnet-4-6-high.md +14 -6
  81. package/templates/agents/orc-executor-sonnet-4-6-med.md +14 -6
  82. package/templates/agents/orc-executor-sonnet-5-high.md +14 -6
  83. package/templates/agents/orc-graph-noter-sonnet-4-6-med.md +1 -10
  84. package/templates/agents/orc-judge-opus-5-xhigh.md +81 -85
  85. package/templates/agents/orc-learn-writer-opus-5-low.md +67 -73
  86. package/templates/agents/orc-pattern-codifier-opus-5-med.md +58 -65
  87. package/templates/agents/orc-pattern-codifier-sonnet-5-high.md +58 -63
  88. package/templates/agents/orc-planner-mini-opus-5-med.md +4 -7
  89. package/templates/agents/orc-planner-mini-sonnet-5-high.md +2 -3
  90. package/templates/agents/orc-planner-opus-5-med.md +157 -160
  91. package/templates/agents/orc-recon-opus-5-low.md +3 -10
  92. package/templates/agents/orc-recon-sonnet-4-6-med.md +1 -8
  93. package/templates/agents/orc-retro-opus-5-med.md +8 -10
  94. package/templates/agents/orc-retro-sonnet-5-high.md +6 -7
  95. package/templates/agents/orc-reviewer-opus-5-med.md +96 -60
  96. package/templates/agents/orc-scout-opus-5-low.md +35 -40
  97. package/templates/agents/orc-scout-sonnet-4-6-high.md +35 -39
  98. package/templates/agents/orc-system-analyst-opus-5-high.md +115 -120
  99. package/templates/agents/orc-test-author-opus-5-med.md +70 -71
  100. package/templates/agents/orc-test-designer-opus-5-high.md +158 -158
  101. package/templates/agents/orc-test-interpreter-opus-5-low.md +130 -130
  102. package/templates/agents/orc-trace-writer-haiku-4-5.md +3 -7
  103. package/templates/agents/orc-verifier-opus-5-med.md +77 -69
  104. package/templates/agents/orc-wiki-scanner-opus-4-8-high.md +74 -79
  105. package/templates/agents/orc-wiki-scanner-opus-5-med.md +74 -81
  106. package/templates/agents/orc-wiki-scanner-sonnet-5-high.md +97 -106
  107. package/templates/commands/orc-analyze.md +13 -21
  108. package/templates/commands/orc-fast.md +10 -15
  109. package/templates/commands/orc-poly.md +12 -21
  110. package/templates/commands/orc-pr-driver.md +11 -30
  111. package/templates/commands/orc-pr-setup.md +10 -31
  112. package/templates/commands/orc-route.md +11 -41
  113. package/templates/commands/orc-test.md +5 -60
  114. package/templates/commands/orc-ultra.md +17 -17
  115. package/templates/commands/orc-verify.md +11 -11
  116. package/templates/hooks/README.md +36 -2
  117. package/templates/hooks/orc-effort-guard.js +178 -178
  118. package/templates/hooks/orc-session-hook.js +264 -0
  119. package/templates/hooks/orc-statusline.js +9 -7
  120. package/templates/skills/_shared/README.md +9 -0
  121. package/templates/skills/_shared/code-graph.md +48 -56
  122. package/templates/skills/_shared/config-precedence.md +200 -198
  123. package/templates/skills/_shared/extra-dispatch.md +1331 -1346
  124. package/templates/skills/_shared/gotchas.md +228 -177
  125. package/templates/skills/_shared/habits.md +101 -0
  126. package/templates/skills/_shared/lane-contract.md +84 -0
  127. package/templates/skills/_shared/opus5-only.md +8 -8
  128. package/templates/skills/_shared/phases/README.md +142 -83
  129. package/templates/skills/_shared/phases/analyst-gates.md +125 -136
  130. package/templates/skills/_shared/phases/execution.md +8 -14
  131. package/templates/skills/_shared/phases/house-rules.md +27 -32
  132. package/templates/skills/_shared/phases/intake.md +127 -133
  133. package/templates/skills/_shared/phases/mock-example.md +46 -56
  134. package/templates/skills/_shared/phases/plan-handoff.md +91 -97
  135. package/templates/skills/_shared/phases/planning.md +7 -17
  136. package/templates/skills/_shared/phases/preflight.md +19 -42
  137. package/templates/skills/_shared/phases/review.md +23 -27
  138. package/templates/skills/_shared/phases/rules.md +18 -42
  139. package/templates/skills/_shared/phases/scoring.md +55 -65
  140. package/templates/skills/_shared/phases/security-checklist.md +46 -50
  141. package/templates/skills/_shared/phases/security.md +45 -55
  142. package/templates/skills/_shared/phases/ship.md +6 -15
  143. package/templates/skills/_shared/phases/stop-resume.md +2 -5
  144. package/templates/skills/_shared/phases/summary.md +73 -48
  145. package/templates/skills/_shared/phases/testgen.md +41 -51
  146. package/templates/skills/_shared/phases/trace-verbs.md +433 -0
  147. package/templates/skills/_shared/phases/trace.md +136 -367
  148. package/templates/skills/_shared/phases/verify.md +62 -70
  149. package/templates/skills/_shared/phases/wave-grouping.md +128 -133
  150. package/templates/skills/_shared/phases/wiki-consult.md +10 -6
  151. package/templates/skills/_shared/read-ladder.md +2 -55
  152. package/templates/skills/_shared/return-validation.md +17 -70
  153. package/templates/skills/_shared/review-slice.md +79 -0
  154. package/templates/skills/_shared/smoke-gate.md +46 -28
  155. package/templates/skills/context-combiner/SKILL.md +16 -45
  156. package/templates/skills/context-combiner/schemas/combined-report.md +78 -78
  157. package/templates/skills/orc/README.md +2 -2
  158. package/templates/skills/orc/SKILL.md +41 -69
  159. package/templates/skills/orc/config.md +9 -9
  160. package/templates/skills/orc/examples/full-run-mock.md +73 -73
  161. package/templates/skills/orc/references/effort-and-mode.md +222 -222
  162. package/templates/skills/orc/references/pattern-gate.md +89 -89
  163. package/templates/skills/orc/references/phases/intake.md +41 -47
  164. package/templates/skills/orc/references/phases/integration.md +13 -19
  165. package/templates/skills/orc/references/preflight-report.md +10 -11
  166. package/templates/skills/orc/references/ultra-mode.md +11 -9
  167. package/templates/skills/orc/subskills/orc-execution/SKILL.md +27 -73
  168. package/templates/skills/orc/subskills/orc-execution/core.md +12 -99
  169. package/templates/skills/orc/subskills/orc-execution/subagent.md +14 -13
  170. package/templates/skills/orc/subskills/orc-planner/SKILL.md +2 -2
  171. package/templates/skills/orc/subskills/orc-planner-mini/SKILL.md +121 -121
  172. package/templates/skills/orc/subskills/orc-review-verify/SKILL.md +35 -76
  173. package/templates/skills/orc/subskills/orc-review-verify/core.md +52 -135
  174. package/templates/skills/orc/subskills/orc-review-verify/subagent.md +7 -7
  175. package/templates/skills/orc/subskills/orc-testgen/SKILL.md +34 -45
  176. package/templates/skills/orc/subskills/orc-testgen/core.md +20 -59
  177. package/templates/skills/orc/subskills/orc-testgen/subagent.md +7 -7
  178. package/templates/skills/orc-advisor/SKILL.md +56 -60
  179. package/templates/skills/orc-analyze/SKILL.md +32 -68
  180. package/templates/skills/orc-analyze/examples/analyze-mock.md +42 -42
  181. package/templates/skills/orc-analyze/schemas/report-audit.md +84 -83
  182. package/templates/skills/orc-analyze/schemas/report-prose.md +64 -63
  183. package/templates/skills/orc-analyze/schemas/report-requirement.md +78 -78
  184. package/templates/skills/orc-analyze-mini/SKILL.md +35 -70
  185. package/templates/skills/orc-challenge/README.md +142 -142
  186. package/templates/skills/orc-challenge/examples/council-full-roster.md +273 -273
  187. package/templates/skills/orc-challenge/references/council.md +315 -315
  188. package/templates/skills/orc-challenge/references/intake.md +171 -171
  189. package/templates/skills/orc-claude/SKILL.md +14 -14
  190. package/templates/skills/orc-diy/README.md +174 -143
  191. package/templates/skills/orc-diy/SKILL.md +23 -74
  192. package/templates/skills/orc-diy/references/blocks/pattern.md +18 -18
  193. package/templates/skills/orc-diy/references/flow-schema.md +1 -1
  194. package/templates/skills/orc-doc/README.md +229 -229
  195. package/templates/skills/orc-doc/examples/orc-doc-prd-run.md +325 -325
  196. package/templates/skills/orc-doc/references/chunking.md +527 -527
  197. package/templates/skills/orc-fast/SKILL.md +45 -73
  198. package/templates/skills/orc-judge/SKILL.md +77 -82
  199. package/templates/skills/orc-learn/SKILL.md +14 -14
  200. package/templates/skills/orc-learn/examples/learn-run-mock.md +61 -61
  201. package/templates/skills/orc-mini/SKILL.md +65 -113
  202. package/templates/skills/orc-pattern/SKILL.md +27 -48
  203. package/templates/skills/orc-poly/SKILL.md +32 -61
  204. package/templates/skills/orc-pr-driver/SKILL.md +25 -51
  205. package/templates/skills/orc-pr-driver/references/green-gate.md +113 -105
  206. package/templates/skills/orc-pr-setup/SKILL.md +20 -45
  207. package/templates/skills/orc-quick/README.md +43 -2
  208. package/templates/skills/orc-quick/SKILL.md +76 -107
  209. package/templates/skills/orc-quick/references/dispatch-gate.md +16 -5
  210. package/templates/skills/orc-quick/references/gh-mode.md +48 -1
  211. package/templates/skills/orc-quick/references/look.md +3 -1
  212. package/templates/skills/orc-retro/SKILL.md +19 -18
  213. package/templates/skills/orc-retro/examples/retro-mock.md +1 -1
  214. package/templates/skills/orc-route/SKILL.md +25 -45
  215. package/templates/skills/orc-test/SKILL.md +16 -37
  216. package/templates/skills/orc-verify/SKILL.md +21 -39
  217. package/templates/skills/orc-verify/examples/verify-mock.md +33 -33
  218. package/templates/skills/orc-wait/SKILL.md +156 -163
  219. package/templates/skills/orc-wiki/references/extra.md +1 -1
  220. package/templates/skills/orc-wiki/references/phases/phase-0.md +1 -6
  221. package/templates/skills/orc-wiki/references/phases/phase-1.md +1 -6
  222. package/templates/skills/orc-wiki/references/phases/phase-2.md +1 -6
  223. package/templates/skills/orc-wiki/references/phases/phase-3.md +1 -6
  224. package/templates/skills/orc-wiki/references/phases/phase-3c.md +1 -6
@@ -1,198 +1,200 @@
1
- # Shared contract — config precedence: ranks, families, and one resolver per lane
2
-
3
- Canonical rule for how EVERY ORC lane learns what it is configured to do.
4
- Consumed by every lane that reads a setting; the lint pins the
5
- `config-precedence.md` pointer into each of them.
6
-
7
- Two sentences carry the whole file:
8
-
9
- > **ONE resolver, and it is not you:** `orc lane config <lane> --json`.
10
- >
11
- > **Read a family top-down and stop at the first rank that resolves.**
12
-
13
- ---
14
-
15
- ## 1. The resolver
16
-
17
- A lane never reads `.claude/orc.config.yaml`. It runs
18
- `orc lane config <lane> --json` once, at preflight, and obeys the answer.
19
-
20
- | field | what a lane does with it |
21
- |---|---|
22
- | `effective` | the flat answer. Obey it and reason about nothing. |
23
- | `announce[]` | print every line VERBATIM at preflight, before the first dispatch |
24
- | `stops[]` | every value that can HARD-STOP this run; honour each before wave 1 |
25
- | `keys[]` | per key: `value`, `default`, `prio`, `family`, `state`, `is_shadowed` / `shadow_reason`, `is_inert` / `inert_reason` |
26
- | `families{}` | which rank answered each question, and why the rest were not read |
27
- | `not_read[]` | the keys this lane deliberately ignores |
28
-
29
- `not_read[]` is an ANSWER, not a gap. "This lane does not read `doc_language`"
30
- is information, and it is what makes the two-way registry lint possible.
31
-
32
- **Never re-derive a value, a precedence, or an inertness.** A key this lane does
33
- not read is not in the answer; a key another key shadows comes back already
34
- marked, with the sentence already worded. A lane that reasons *"`opus5_only` is
35
- on, so the fable block must be inert"* has forked the resolver — it reads
36
- `is_shadowed` and prints `shadow_reason`.
37
-
38
- ---
39
-
40
- ## 2. Ranks, and the rule that makes them mean something
41
-
42
- Every key declares `answers[]`: which FAMILY question it answers, at which
43
- RANK (`P0` · `P1` · `P2` · `P3`), in which MODE.
44
-
45
- > **Read a family top-down and stop at the first rank that resolves.**
46
- > If the P0 key of a family resolves, P1, P2 and P3 of that family are **not
47
- > read at all** — not consulted, not defaulted, not mentioned as a fallback. A
48
- > rank below a resolved rank has no effect and no meaning for this decision.
49
-
50
- **A rank compares only INSIDE its family.** `log_dir` being P2 and `opus5_only`
51
- being P1 says nothing whatever: they never compete. A family whose keys do not
52
- compete has every key at P2, the neutral rank, and the lint asserts it — rank
53
- distinctness is required only where a family is declared contested.
54
-
55
- | `mode` | resolves when | effect on the ranks below it |
56
- |---|---|---|
57
- | `replace` | the key is set to a truthy / non-default value | every lower rank is shadowed, entirely |
58
- | `overlay` | the key is on **and** at least one row applies to THIS decision | lower ranks are shadowed only for the ranges or slots it covers |
59
- | `gate` | — | it never resolves the family; it makes its own dependants **inert** (§4) |
60
-
61
- An `overlay` resolves PARTIALLY, so the honest report is WHICH ranges and WHICH
62
- positions it took — never a single word. The ranges it did not take fall through
63
- to the next rank normally. That is what lets "cheap work goes to a foreign
64
- worker, hard work stays on Opus 5" be two rows rather than a table rewrite.
65
-
66
- **The lowest rank of a contested family is TOTAL.** Something must answer when
67
- nothing above resolved, so that terminal row is the shipped default and it is
68
- declared as a row, not as a key — a fall-through is not a setting.
69
-
70
- ---
71
-
72
- ## 3. The two contested families
73
-
74
- Everything else is uncontested: one question, no competition, every key P2.
75
-
76
- **`executor-band` — which model executes a SCORED task**
77
-
78
- | rank | key | mode | |
79
- |---|---|---|---|
80
- | P0 | `extra_enabled` | overlay | a route row covering this score sends it off Claude |
81
- | P1 | `opus5_only` | replace | the fixed 2-band Opus 5 ladder |
82
- | P2 | `rubric_bands_override` | replace | hand-edited, registry-less by design; resolves on PRESENCE |
83
- | P3 | — | terminal | the shipped score→model table |
84
-
85
- **`fixed-role-model` — which model runs a role that has no score**
86
-
87
- | rank | key | mode | |
88
- |---|---|---|---|
89
- | P0 | `extra_enabled` | overlay | a slot row holds that POSITION |
90
- | P1 | `opus5_only` | replace | the shipped Opus 5 variant of that position's agent |
91
- | P2 | — | terminal | the agent shipped for that position |
92
-
93
- Said once, for both shapes: **extra decides whether a Claude agent runs at all;
94
- `opus5_only` and the score tables only decide WHICH Claude agent runs where
95
- extra did not take it.** Under a taken band or a taken slot, `opus5_only` is
96
- **not consulted** — not "inert" — and it stays fully live everywhere else.
97
-
98
- ---
99
-
100
- ## 4. A gate is not a rank — it is inertness
101
-
102
- `extra_enabled: false` does not lose a precedence contest. It means **no
103
- `extra_*` key is consulted at all**. A key declares `gated_by`, inherits its
104
- gate's row, and comes back `inert` with the reason already worded.
105
-
106
- Lane-level inertness is a THIRD thing, with nothing in the config file involved:
107
-
108
- | lane | inert | reason (must not be softened) |
109
- |---|---|---|
110
- | `/orc-quick` | `opus5_only`, `rubric_bands_override`, `extra_*` | this lane asks WHICH AGENT before every dispatch — a config that silently answered that question would break the lane's entire premise |
111
- | `/orc-challenge` | `opus5_only` | every agent in this lane is already `claude-opus-5` — a **no-op; the lane is unaffected, not exempt** |
112
- | `/orc-doc` | `opus5_only` | the same — unaffected, not exempt |
113
-
114
- **"Unaffected, not exempt"** survives verbatim. A generic "not applicable" loses
115
- the fact that turning the key on breaks nothing here.
116
-
117
- ---
118
-
119
- ## 5. `announce[]` — and its exact boundary
120
-
121
- A shadowed setting must never be silent, and work must never leave Claude
122
- without the run saying so. Those lines are computed, worded once by the CLI, and
123
- printed by the lane verbatim.
124
-
125
- | goes in `announce[]` | stays with the lane |
126
- |---|---|
127
- | anything derivable from config + disk the CLI already reads: the wiki tier, pattern-cache presence, crosslink state, extra route rows and taken slots, pact / boundary / challenge state, which keys are shadowed or inert, the resolved scan tier, a run-scoped demotion | anything needing a per-task or per-run value the CLI cannot know: a task's score, a task id, a slug, a file count, a forecast number, a wave index |
128
-
129
- A line needing a runtime value is **not** emitted as a template with holes. Half
130
- a sentence from the CLI and half from the model is worse than either — it is a
131
- sentence nobody owns. Those lines stay with the lane.
132
-
133
- ---
134
-
135
- ## 6. The ladder can move at runtime
136
-
137
- A profile that stalls twice in one run, or holds one live attempt quiet past
138
- `extra_demote_stale_min`, is DEMOTED to the bottom of its families for the rest
139
- of that run — so the next rank down becomes the effective P0. The verdict is
140
- recomputed from disk on every read and never stored; it is run-scoped and never
141
- touches the config file; it is never promoted back on its own; and it is
142
- ANNOUNCED, because the mirror of sending work off Claude silently is quietly
143
- stopping. Full rule: `extra-dispatch.md`.
144
-
145
- ---
146
-
147
- ## 7. When the CLI is not there
148
-
149
- Exit ≠ 0, or the command is not found:
150
-
151
- 1. **Say so, in one line.** Fail open with the failure stated.
152
- 2. Use the documented defaults below.
153
- 3. Treat **every P0 forcing mode as OFF**.
154
- 4. Never guess a user override, and never present a default as a resolved value.
155
-
156
- The floor is the keys a run cannot start without — `max_wave_tasks: 3` ·
157
- `batch_pause_every: 2` · `rubric_bands: 5` · `max_scouts: 3` ·
158
- `default_analysis_depth: standard` · `generate_tests: false` ·
159
- `pattern_findings: ask` · `security_review: off`.
160
-
161
- Every other key's default is the CLI's to state. **A lane never guesses one** —
162
- if a decision needs a key not on that list and the CLI cannot answer, the lane
163
- says which key it could not resolve and stops, rather than inventing a value the
164
- user may have overridden.
165
-
166
- ---
167
-
168
- ## 8. The `## Config` section every lane carries
169
-
170
- Verbatim, and identical in every lane but its own name:
171
-
172
- ```markdown
173
- ## Config
174
-
175
- **ONE resolver, and it is not you:** `orc lane config <lane> --json`. Obey
176
- `effective`, print every line in `announce[]` VERBATIM at preflight, and honour
177
- `stops[]` before wave 1. Never re-derive a value, a precedence or an inertness
178
- from `.claude/orc.config.yaml` — a key this lane does not read is not in the
179
- answer, and a key another key shadows comes back already marked. Exit ≠ 0 → say
180
- the CLI is unavailable and fall back to `../_shared/config-precedence.md`'s
181
- documented defaults, out loud. Priorities and families:
182
- `../_shared/config-precedence.md`.
183
- ```
184
-
185
- ---
186
-
187
- ## 9. The file the user edits
188
-
189
- `.claude/orc.config.yaml` holds only the keys the user changed, sits outside
190
- `templates/` (so `orc update` never clobbers it), and is written exclusively by
191
- `orc config set`. It is grouped by the QUESTION each key answers, ordered by
192
- rank only inside a contested family.
193
-
194
- `orc config set` regenerates its own group comments on every write and
195
- **never rewrites a value it was not given**: a comment the user wrote stays with
196
- the key it sits above, and a hand-edited multi-line block survives byte for
197
- byte. A key written under a retired spelling is rebuilt under its current name —
198
- a renamed mechanism must never be a silent revert.
1
+ # Shared contract — config precedence: ranks, families, and one resolver per lane
2
+
3
+ Canonical rule for how EVERY ORC lane learns what it is configured to do.
4
+ Consumed by every lane that reads a setting; the lint pins the
5
+ `config-precedence.md` pointer into each of them.
6
+
7
+ Two sentences carry the whole file:
8
+
9
+ > **ONE resolver, and it is not you:** `orc lane config <lane> --json`.
10
+ >
11
+ > **Read a family top-down and stop at the first rank that resolves.**
12
+
13
+ ---
14
+
15
+ ## 1. The resolver
16
+
17
+ A lane never reads `.claude/orc.config.yaml`. It runs
18
+ `orc lane config <lane> --json` once, at preflight, and obeys the answer.
19
+
20
+ | field | what a lane does with it |
21
+ |---|---|
22
+ | `effective` | the flat answer. Obey it and reason about nothing. |
23
+ | `announce[]` | print every line VERBATIM at preflight, before the first dispatch |
24
+ | `stops[]` | every value that can HARD-STOP this run; honour each before wave 1 |
25
+ | `keys[]` | per key: `value`, `default`, `prio`, `family`, `state`, `is_shadowed` / `shadow_reason`, `is_inert` / `inert_reason` |
26
+ | `families{}` | which rank answered each question, and why the rest were not read |
27
+ | `not_read[]` | the keys this lane deliberately ignores |
28
+
29
+ `not_read[]` is an ANSWER, not a gap. "This lane does not read `doc_language`"
30
+ is information, and it is what makes the two-way registry lint possible.
31
+
32
+ **Never re-derive a value, a precedence, or an inertness.** A key this lane does
33
+ not read is not in the answer; a key another key shadows comes back already
34
+ marked, with the sentence already worded. A lane that reasons *"`opus5_only` is
35
+ on, so the fable block must be inert"* has forked the resolver — it reads
36
+ `is_shadowed` and prints `shadow_reason`.
37
+
38
+ ---
39
+
40
+ ## 2. Ranks, and the rule that makes them mean something
41
+
42
+ Every key declares `answers[]`: which FAMILY question it answers, at which
43
+ RANK (`P0` · `P1` · `P2` · `P3`), in which MODE.
44
+
45
+ > **Read a family top-down and stop at the first rank that resolves.**
46
+ > If the P0 key of a family resolves, P1, P2 and P3 of that family are **not
47
+ > read at all** — not consulted, not defaulted, not mentioned as a fallback. A
48
+ > rank below a resolved rank has no effect and no meaning for this decision.
49
+
50
+ **A rank compares only INSIDE its family.** `log_dir` being P2 and `opus5_only`
51
+ being P1 says nothing whatever: they never compete. A family whose keys do not
52
+ compete has every key at P2, the neutral rank, and the lint asserts it — rank
53
+ distinctness is required only where a family is declared contested.
54
+
55
+ | `mode` | resolves when | effect on the ranks below it |
56
+ |---|---|---|
57
+ | `replace` | the key is set to a truthy / non-default value | every lower rank is shadowed, entirely |
58
+ | `overlay` | the key is on **and** at least one row applies to THIS decision | lower ranks are shadowed only for the ranges or slots it covers |
59
+ | `gate` | — | it never resolves the family; it makes its own dependants **inert** (§4) |
60
+
61
+ An `overlay` resolves PARTIALLY, so the honest report is WHICH ranges and WHICH
62
+ positions it took — never a single word. The ranges it did not take fall through
63
+ to the next rank normally. That is what lets "cheap work goes to a foreign
64
+ worker, hard work stays on Opus 5.5" be two rows rather than a table rewrite.
65
+
66
+ **The lowest rank of a contested family is TOTAL.** Something must answer when
67
+ nothing above resolved, so that terminal row is the shipped default and it is
68
+ declared as a row, not as a key — a fall-through is not a setting.
69
+
70
+ ---
71
+
72
+ ## 3. The two contested families
73
+
74
+ Everything else is uncontested: one question, no competition, every key P2.
75
+
76
+ **`executor-band` — which model executes a SCORED task**
77
+
78
+ | rank | key | mode | |
79
+ |---|---|---|---|
80
+ | P0 | `extra_enabled` | overlay | a route row covering this score sends it off Claude |
81
+ | P1 | `opus5_only` | replace | the fixed 2-band Opus 5.5 ladder |
82
+ | P2 | `rubric_bands_override` | replace | hand-edited, registry-less by design; resolves on PRESENCE |
83
+ | P3 | — | terminal | the shipped score→model table |
84
+
85
+ **`fixed-role-model` — which model runs a role that has no score**
86
+
87
+ | rank | key | mode | |
88
+ |---|---|---|---|
89
+ | P0 | `extra_enabled` | overlay | a slot row holds that POSITION |
90
+ | P1 | `opus5_only` | replace | the shipped Opus 5.5 variant of that position's agent |
91
+ | P2 | — | terminal | the agent shipped for that position |
92
+
93
+ Said once, for both shapes: **extra decides whether a Claude agent runs at all;
94
+ `opus5_only` and the score tables only decide WHICH Claude agent runs where
95
+ extra did not take it.** Under a taken band or a taken slot, `opus5_only` is
96
+ **not consulted** — not "inert" — and it stays fully live everywhere else.
97
+
98
+ ---
99
+
100
+ ## 4. A gate is not a rank — it is inertness
101
+
102
+ `extra_enabled: false` does not lose a precedence contest. It means **no
103
+ `extra_*` key is consulted at all**. A key declares `gated_by`, inherits its
104
+ gate's row, and comes back `inert` with the reason already worded.
105
+
106
+ Lane-level inertness is a THIRD thing, with nothing in the config file involved:
107
+
108
+ | lane | inert | reason (must not be softened) |
109
+ |---|---|---|
110
+ | `/orc-quick` | `opus5_only`, `rubric_bands_override`, `extra_*` | this lane asks WHICH AGENT before every dispatch — a config that silently answered that question would break the lane's entire premise |
111
+ | `/orc-challenge` | `opus5_only` | every agent in this lane is already `claude-opus-5-5` — a **no-op; the lane is unaffected, not exempt** |
112
+ | `/orc-doc` | `opus5_only` | the same — unaffected, not exempt |
113
+
114
+ **"Unaffected, not exempt"** survives verbatim. A generic "not applicable" loses
115
+ the fact that turning the key on breaks nothing here.
116
+
117
+ ---
118
+
119
+ ## 5. `announce[]` — and its exact boundary
120
+
121
+ A shadowed setting must never be silent, and work must never leave Claude
122
+ without the run saying so. Those lines are computed, worded once by the CLI, and
123
+ printed by the lane verbatim.
124
+
125
+ | goes in `announce[]` | stays with the lane |
126
+ |---|---|
127
+ | anything derivable from config + disk the CLI already reads: the wiki tier, pattern-cache presence, crosslink state, extra route rows and taken slots, pact / boundary / challenge state, which keys are shadowed or inert, the resolved scan tier, a run-scoped demotion | anything needing a per-task or per-run value the CLI cannot know: a task's score, a task id, a slug, a file count, a forecast number, a wave index |
128
+
129
+ A line needing a runtime value is **not** emitted as a template with holes. Half
130
+ a sentence from the CLI and half from the model is worse than either — it is a
131
+ sentence nobody owns. Those lines stay with the lane.
132
+
133
+ ---
134
+
135
+ ## 6. The ladder can move at runtime
136
+
137
+ A profile that stalls twice in one run, or holds one live attempt quiet past
138
+ `extra_demote_stale_min`, is DEMOTED to the bottom of its families for the rest
139
+ of that run — so the next rank down becomes the effective P0. The verdict is
140
+ recomputed from disk on every read and never stored; it is run-scoped and never
141
+ touches the config file; it is never promoted back on its own; and it is
142
+ ANNOUNCED, because the mirror of sending work off Claude silently is quietly
143
+ stopping. Full rule: `extra-dispatch.md`.
144
+
145
+ ---
146
+
147
+ ## 7. When the CLI is not there
148
+
149
+ Exit ≠ 0, or the command is not found:
150
+
151
+ 1. **Say so, in one line.** Fail open with the failure stated.
152
+ 2. Use the documented defaults below.
153
+ 3. Treat **every P0 forcing mode as OFF**.
154
+ 4. Never guess a user override, and never present a default as a resolved value.
155
+
156
+ The floor is the keys a run cannot start without — `max_wave_tasks: 3` ·
157
+ `batch_pause_every: 2` · `rubric_bands: 5` · `max_scouts: 3` ·
158
+ `default_analysis_depth: standard` · `generate_tests: false` ·
159
+ `pattern_findings: ask` · `security_review: off`.
160
+
161
+ Every other key's default is the CLI's to state. **A lane never guesses one** —
162
+ if a decision needs a key not on that list and the CLI cannot answer, the lane
163
+ says which key it could not resolve and stops, rather than inventing a value the
164
+ user may have overridden.
165
+
166
+ ---
167
+
168
+ ## 8. The `## Config` section every lane carries
169
+
170
+ Verbatim, and identical in every lane but its own name — except the coding
171
+ lanes, which carry the short `## Lane contract` pointer instead. Their full text
172
+ (both forms and the exit ≠ 0 fallback) is `lane-contract.md` §Config:
173
+
174
+ ```markdown
175
+ ## Config
176
+
177
+ **ONE resolver, and it is not you:** `orc lane config <lane> --json`. Obey
178
+ `effective`, print every line in `announce[]` VERBATIM at preflight, and honour
179
+ `stops[]` before wave 1. Never re-derive a value, a precedence or an inertness
180
+ from `.claude/orc.config.yaml` — a key this lane does not read is not in the
181
+ answer, and a key another key shadows comes back already marked. Exit ≠ 0 → say
182
+ the CLI is unavailable and fall back to `../_shared/config-precedence.md`'s
183
+ documented defaults, out loud. Priorities and families:
184
+ `../_shared/config-precedence.md`.
185
+ ```
186
+
187
+ ---
188
+
189
+ ## 9. The file the user edits
190
+
191
+ `.claude/orc.config.yaml` holds only the keys the user changed, sits outside
192
+ `templates/` (so `orc update` never clobbers it), and is written exclusively by
193
+ `orc config set`. It is grouped by the QUESTION each key answers, ordered by
194
+ rank only inside a contested family.
195
+
196
+ `orc config set` regenerates its own group comments on every write and
197
+ **never rewrites a value it was not given**: a comment the user wrote stays with
198
+ the key it sits above, and a hand-edited multi-line block survives byte for
199
+ byte. A key written under a retired spelling is rebuilt under its current name —
200
+ a renamed mechanism must never be a silent revert.