@azure-id/orc 1.9.2 → 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 (172) hide show
  1. package/CHANGELOG.md +321 -0
  2. package/README-id.md +21 -36
  3. package/README.md +25 -36
  4. package/bin/build-agents.js +117 -20
  5. package/bin/cli.js +725 -29
  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/run-undo.js +398 -0
  13. package/bin/trace-write.js +657 -0
  14. package/bin/verify-contracts.js +525 -79
  15. package/bin/verify-package.js +51 -4
  16. package/bin/webui/api.js +26 -0
  17. package/bin/webui/app.html +239 -232
  18. package/bin/webui/css/00-tokens.css +110 -92
  19. package/bin/webui/css/04-motion.css +87 -0
  20. package/bin/webui/css/06-responsive.css +203 -178
  21. package/bin/webui/css/panels/behaviour.css +205 -0
  22. package/bin/webui/fixtures/behaviour.js +532 -0
  23. package/bin/webui/fixtures/index.js +34 -0
  24. package/bin/webui/fixtures/knowledge.js +7 -1
  25. package/bin/webui/fixtures/stats.js +16 -0
  26. package/bin/webui/i18n/en/behaviour.json +143 -0
  27. package/bin/webui/i18n/en/nav.json +25 -24
  28. package/bin/webui/i18n/en/tour.json +37 -35
  29. package/bin/webui/i18n/id/behaviour.json +143 -0
  30. package/bin/webui/i18n/id/nav.json +25 -24
  31. package/bin/webui/i18n/id/tour.json +37 -35
  32. package/bin/webui/js/01-i18n.js +155 -154
  33. package/bin/webui/js/90-tour.js +498 -494
  34. package/bin/webui/js/91-shortcuts.js +126 -126
  35. package/bin/webui/js/99-boot.js +121 -118
  36. package/bin/webui/js/panels/behaviour.js +1022 -0
  37. package/mock-run/INDEX.md +109 -107
  38. package/mock-run/gotcha-import.md +118 -0
  39. package/mock-run/habits.md +129 -0
  40. package/mock-run/orc-quick.md +6 -1
  41. package/package.json +1 -1
  42. package/templates/agents/MODEL-MAPPING.md +7 -7
  43. package/templates/agents/orc-advisor-opus-5-xhigh.md +1 -7
  44. package/templates/agents/orc-analyze-mini-opus-5-med.md +1 -6
  45. package/templates/agents/orc-analyze-mini-sonnet-5-high.md +1 -4
  46. package/templates/agents/orc-claude-writer-opus-4-8-high.md +48 -53
  47. package/templates/agents/orc-claude-writer-opus-5-med.md +1 -8
  48. package/templates/agents/orc-context-combiner-opus-5-high.md +1 -11
  49. package/templates/agents/orc-executor-haiku-4-5.md +14 -6
  50. package/templates/agents/orc-executor-opus-4-7-high.md +14 -6
  51. package/templates/agents/orc-executor-opus-4-7-med.md +14 -6
  52. package/templates/agents/orc-executor-opus-4-8-high.md +14 -6
  53. package/templates/agents/orc-executor-opus-5-high.md +14 -6
  54. package/templates/agents/orc-executor-opus-5-low.md +14 -6
  55. package/templates/agents/orc-executor-opus-5-med.md +14 -6
  56. package/templates/agents/orc-executor-sonnet-4-6-high.md +14 -6
  57. package/templates/agents/orc-executor-sonnet-4-6-med.md +14 -6
  58. package/templates/agents/orc-executor-sonnet-5-high.md +14 -6
  59. package/templates/agents/orc-graph-noter-sonnet-4-6-med.md +1 -10
  60. package/templates/agents/orc-judge-opus-5-xhigh.md +5 -9
  61. package/templates/agents/orc-learn-writer-opus-5-low.md +1 -7
  62. package/templates/agents/orc-pattern-codifier-opus-5-med.md +1 -8
  63. package/templates/agents/orc-pattern-codifier-sonnet-5-high.md +58 -63
  64. package/templates/agents/orc-planner-mini-opus-5-med.md +1 -4
  65. package/templates/agents/orc-planner-mini-sonnet-5-high.md +1 -2
  66. package/templates/agents/orc-planner-opus-5-med.md +1 -4
  67. package/templates/agents/orc-recon-opus-5-low.md +1 -8
  68. package/templates/agents/orc-recon-sonnet-4-6-med.md +1 -8
  69. package/templates/agents/orc-retro-opus-5-med.md +6 -8
  70. package/templates/agents/orc-retro-sonnet-5-high.md +6 -7
  71. package/templates/agents/orc-reviewer-opus-5-med.md +52 -16
  72. package/templates/agents/orc-scout-opus-5-low.md +1 -6
  73. package/templates/agents/orc-scout-sonnet-4-6-high.md +35 -39
  74. package/templates/agents/orc-system-analyst-opus-5-high.md +1 -6
  75. package/templates/agents/orc-test-author-opus-5-med.md +4 -5
  76. package/templates/agents/orc-trace-writer-haiku-4-5.md +3 -7
  77. package/templates/agents/orc-verifier-opus-5-med.md +16 -8
  78. package/templates/agents/orc-wiki-scanner-opus-4-8-high.md +74 -79
  79. package/templates/agents/orc-wiki-scanner-opus-5-med.md +1 -8
  80. package/templates/agents/orc-wiki-scanner-sonnet-5-high.md +97 -106
  81. package/templates/commands/orc-analyze.md +13 -21
  82. package/templates/commands/orc-fast.md +10 -15
  83. package/templates/commands/orc-poly.md +12 -21
  84. package/templates/commands/orc-pr-driver.md +11 -30
  85. package/templates/commands/orc-pr-setup.md +10 -31
  86. package/templates/commands/orc-route.md +11 -41
  87. package/templates/commands/orc-test.md +5 -60
  88. package/templates/hooks/README.md +34 -0
  89. package/templates/hooks/orc-session-hook.js +264 -0
  90. package/templates/hooks/orc-statusline.js +3 -1
  91. package/templates/skills/_shared/README.md +9 -0
  92. package/templates/skills/_shared/code-graph.md +47 -55
  93. package/templates/skills/_shared/config-precedence.md +3 -1
  94. package/templates/skills/_shared/extra-dispatch.md +73 -88
  95. package/templates/skills/_shared/gotchas.md +228 -177
  96. package/templates/skills/_shared/habits.md +101 -0
  97. package/templates/skills/_shared/lane-contract.md +84 -0
  98. package/templates/skills/_shared/phases/README.md +142 -83
  99. package/templates/skills/_shared/phases/analyst-gates.md +10 -21
  100. package/templates/skills/_shared/phases/execution.md +8 -14
  101. package/templates/skills/_shared/phases/house-rules.md +27 -32
  102. package/templates/skills/_shared/phases/intake.md +127 -133
  103. package/templates/skills/_shared/phases/mock-example.md +46 -56
  104. package/templates/skills/_shared/phases/plan-handoff.md +91 -97
  105. package/templates/skills/_shared/phases/planning.md +7 -17
  106. package/templates/skills/_shared/phases/preflight.md +19 -42
  107. package/templates/skills/_shared/phases/review.md +23 -27
  108. package/templates/skills/_shared/phases/rules.md +18 -42
  109. package/templates/skills/_shared/phases/scoring.md +55 -65
  110. package/templates/skills/_shared/phases/security-checklist.md +46 -50
  111. package/templates/skills/_shared/phases/security.md +45 -55
  112. package/templates/skills/_shared/phases/ship.md +6 -15
  113. package/templates/skills/_shared/phases/stop-resume.md +2 -5
  114. package/templates/skills/_shared/phases/summary.md +73 -48
  115. package/templates/skills/_shared/phases/testgen.md +41 -51
  116. package/templates/skills/_shared/phases/trace-verbs.md +433 -0
  117. package/templates/skills/_shared/phases/trace.md +136 -367
  118. package/templates/skills/_shared/phases/verify.md +62 -70
  119. package/templates/skills/_shared/phases/wave-grouping.md +128 -133
  120. package/templates/skills/_shared/phases/wiki-consult.md +10 -6
  121. package/templates/skills/_shared/read-ladder.md +2 -55
  122. package/templates/skills/_shared/return-validation.md +17 -70
  123. package/templates/skills/_shared/review-slice.md +79 -0
  124. package/templates/skills/_shared/smoke-gate.md +46 -28
  125. package/templates/skills/context-combiner/SKILL.md +15 -44
  126. package/templates/skills/orc/SKILL.md +34 -62
  127. package/templates/skills/orc/references/pattern-gate.md +89 -89
  128. package/templates/skills/orc/references/phases/intake.md +41 -47
  129. package/templates/skills/orc/references/phases/integration.md +13 -19
  130. package/templates/skills/orc/references/preflight-report.md +8 -9
  131. package/templates/skills/orc/references/ultra-mode.md +8 -6
  132. package/templates/skills/orc/subskills/orc-execution/SKILL.md +27 -73
  133. package/templates/skills/orc/subskills/orc-execution/core.md +12 -99
  134. package/templates/skills/orc/subskills/orc-execution/subagent.md +14 -13
  135. package/templates/skills/orc/subskills/orc-review-verify/SKILL.md +11 -52
  136. package/templates/skills/orc/subskills/orc-review-verify/core.md +52 -135
  137. package/templates/skills/orc/subskills/orc-review-verify/subagent.md +7 -7
  138. package/templates/skills/orc/subskills/orc-testgen/SKILL.md +11 -22
  139. package/templates/skills/orc/subskills/orc-testgen/core.md +20 -59
  140. package/templates/skills/orc/subskills/orc-testgen/subagent.md +7 -7
  141. package/templates/skills/orc-advisor/SKILL.md +56 -60
  142. package/templates/skills/orc-analyze/SKILL.md +30 -66
  143. package/templates/skills/orc-analyze/schemas/report-audit.md +2 -1
  144. package/templates/skills/orc-analyze/schemas/report-prose.md +2 -1
  145. package/templates/skills/orc-analyze-mini/SKILL.md +35 -70
  146. package/templates/skills/orc-diy/README.md +31 -0
  147. package/templates/skills/orc-diy/SKILL.md +23 -74
  148. package/templates/skills/orc-diy/references/blocks/pattern.md +18 -18
  149. package/templates/skills/orc-fast/SKILL.md +44 -72
  150. package/templates/skills/orc-judge/SKILL.md +77 -82
  151. package/templates/skills/orc-mini/SKILL.md +61 -109
  152. package/templates/skills/orc-pattern/SKILL.md +27 -48
  153. package/templates/skills/orc-poly/SKILL.md +32 -61
  154. package/templates/skills/orc-pr-driver/SKILL.md +25 -51
  155. package/templates/skills/orc-pr-driver/references/green-gate.md +113 -105
  156. package/templates/skills/orc-pr-setup/SKILL.md +20 -45
  157. package/templates/skills/orc-quick/README.md +43 -2
  158. package/templates/skills/orc-quick/SKILL.md +76 -107
  159. package/templates/skills/orc-quick/references/dispatch-gate.md +16 -5
  160. package/templates/skills/orc-quick/references/gh-mode.md +48 -1
  161. package/templates/skills/orc-quick/references/look.md +3 -1
  162. package/templates/skills/orc-retro/SKILL.md +19 -18
  163. package/templates/skills/orc-retro/examples/retro-mock.md +1 -1
  164. package/templates/skills/orc-route/SKILL.md +25 -45
  165. package/templates/skills/orc-test/SKILL.md +16 -37
  166. package/templates/skills/orc-verify/SKILL.md +14 -32
  167. package/templates/skills/orc-wait/SKILL.md +156 -163
  168. package/templates/skills/orc-wiki/references/phases/phase-0.md +1 -6
  169. package/templates/skills/orc-wiki/references/phases/phase-1.md +1 -6
  170. package/templates/skills/orc-wiki/references/phases/phase-2.md +1 -6
  171. package/templates/skills/orc-wiki/references/phases/phase-3.md +1 -6
  172. package/templates/skills/orc-wiki/references/phases/phase-3c.md +1 -6
@@ -1,177 +1,228 @@
1
- # Shared contract — Gotchas (repair memory that outlives the run)
2
-
3
- Canonical file: `_shared/gotchas.md`. THE one description of ORC's repair memory:
4
- what a gotcha is, where it lives, when one is recorded, when one is injected, and
5
- which lane may do which. Gate: config `gotchas` (`on` | `off`, default `on`).
6
-
7
- ## 1. What a gotcha is
8
-
9
- **ONE project-specific failure that a repair in this project already solved.**
10
- Not a rule, not a preference, not a lesson in general.
11
-
12
- It is deliberately none of the other three knowledge artifacts:
13
-
14
- | Artifact | Answers | Not this |
15
- |---|---|---|
16
- | the wiki | "what IS this codebase" | a gotcha is not a fact about the code |
17
- | the pattern cache | "how does this project WRITE code" | a gotcha is not a convention |
18
- | `tdd_spec` | "what must this change PROVE" | a gotcha is not an acceptance test |
19
- | **gotchas** | **"what has this project already gotten WRONG here"** | — |
20
-
21
- If a finding fits one of the first three rows, it belongs there. A gotcha is the
22
- residue of a repair: something went red, a specific cause was found, a specific
23
- fix made it green.
24
-
25
- ## 2. The artifact
26
-
27
- ```
28
- .claude/orc/gotchas.md # live entries, capped at gotchas_max
29
- .claude/orc/gotchas-archive.md # evicted entries — never hard-dropped
30
- ```
31
-
32
- Both sit BESIDE the pattern cache (`orc/patterns/`), never inside it. Like every
33
- file ORC generates under `.claude/orc/`, neither is in the install manifest — so
34
- `orc update --prune` can never delete them and `orc update` never overwrites them.
35
- They are user data by ORC's own rules.
36
-
37
- **Entry format** — the parser and every writer depend on this exactly:
38
-
39
- ```markdown
40
- ## G-014 · express · repair
41
- - trigger: adding a route handler that awaits a Mongoose query
42
- - symptom: Cannot read properties of undefined (reading 'session') in tests
43
- - cause: the test harness stubs req.session only for authed routes
44
- - fix: register the route under authedRouter, not app
45
- - scope: src/routes/**/*.js
46
- - origin: run-orc-add-billing-050826-141233 · TDD repair round 2
47
- - hits: 3
48
- - last_seen: 05-08-2026
49
- ```
50
-
51
- - Heading: `## G-<3-digit id> · <lang-or-area> · <kind>`; `kind` ∈
52
- `repair | drift | review | verify`.
53
- - Field order is FIXED. Every field is required. Values are single-line.
54
- - `scope` is a glob matched against a task's `declared_files`.
55
- - Dates are `DD-MM-YYYY` (the repo's convention).
56
- - IDs are monotonic; **never reused**, even after archival — an archived gotcha
57
- stays traceable from a trace or a run doc that cited it.
58
-
59
- ## 3. Existence probe (never a `find`)
60
-
61
- ```
62
- orc gotcha status exit 0 = one or more live entries · exit 1 = none
63
- orc gotcha list the same contract, and prints the entries
64
- orc gotcha prune archive the low-value tail down to gotchas_max
65
- ```
66
-
67
- **The exit code IS the contract**, same convention as `orc pattern status <lang>`
68
- and `orc diy status`. `.claude/` is a hidden directory, so an ad-hoc `find`/glob
69
- false-negatives from the wrong CWD or when it skips dot-dirs — the same reason
70
- `detecting-artifacts.md` exists for the wiki and the pattern cache. Probe once,
71
- treat the result as the source of truth, and never second-guess a positive probe.
72
-
73
- ## 4. When one is RECORDED
74
-
75
- At phase close, **when and only when a repair loop went red → green**:
76
-
77
- - the TDD repair loop turned a failing `tdd_spec` test green;
78
- - a `DRIFT-FROM` recovery round resolved the drift;
79
- - a reviewer P0/P1 that THIS SAME RUN fixed;
80
- - a verifier `unmet[]` entry that THIS SAME RUN closed.
81
-
82
- **A loop that hit its cap and STOPPED records NOTHING.** An unsolved failure is
83
- not a gotcha — it is an open problem, and the honest red report is where it
84
- belongs. Writing one anyway would seed the memory with advice that never worked.
85
-
86
- Nothing else records. A first-try success has no repair to remember; a green
87
- `regression-guard` test proved something, but it was never red.
88
-
89
- ## 5. Who writes it
90
-
91
- Three parties, and they do not overlap:
92
-
93
- 1. **The agent RETURNS the body** in `gotcha_recorded` (see
94
- `return-validation.md` §7) — either the entry fields or `none` + a one-line
95
- reason. The agent that did the repair is the only party that knows the cause.
96
- 2. **The ORCHESTRATOR appends it** to `.claude/orc/gotchas.md`, at the same
97
- phase-close point where it dispatches the trace packet. **A subagent never
98
- writes either gotcha file.**
99
- 3. **The CLI owns counting, capping and archival** (`orc gotcha prune`) —
100
- deterministic bookkeeping, never a model's judgement.
101
-
102
- ## 6. Dedupe (before every append)
103
-
104
- Compare the returned `symptom` + `scope` against the live entries. A match:
105
- increment `hits`, refresh `last_seen`, and **append nothing**. Only a genuinely
106
- new failure gets a new ID. Without this the file grows one duplicate per run and
107
- the injection cap fills with the same entry three times.
108
-
109
- ## 7. When one is INJECTED
110
-
111
- Into an executor slice, **filtered by the `scope` glob against that task's
112
- `declared_files`**.
113
-
114
- - **NEVER inject unfiltered.** An unfiltered injection is the exact failure mode
115
- that turns this feature into the bloat it exists to prevent.
116
- - Cap **3 entries per slice**, highest `hits` first.
117
- - **Zero matches = no gotcha block at all** — not an empty one. An empty block
118
- costs tokens and says nothing.
119
-
120
- The block rides beside `pattern` in the slice, and like `pattern` it is injected
121
- LITERALLY, never as a file pointer.
122
-
123
- ## 8. Who reads it
124
-
125
- - **Phase 1 preflight** — one line, never silent (see
126
- `../orc/references/preflight-report.md`).
127
- - **executor slices** — filtered, capped, per §7.
128
- - **the reviewer** — the matching entries as a checklist: has this change
129
- reintroduced a failure this project already paid for?
130
- - **`/orc-retro`** — read-only calibration input. It never writes one.
131
-
132
- ## 9. Staleness is the user's job
133
-
134
- An injected gotcha is presented to an executor as **fact**. Nothing in ORC
135
- re-verifies that it is still true — `orc gotcha prune` handles CAPACITY, not
136
- correctness.
137
-
138
- So, plainly: **delete an entry that stopped being true.** Open
139
- `.claude/orc/gotchas.md` and remove the block. That is the whole procedure, and
140
- it is deliberately manual — a model deciding which of its own memories to forget
141
- is a worse failure mode than a stale line a human can read.
142
-
143
- ## 10. Lane policy
144
-
145
- | Lane | Reads | Writes |
146
- |------|-------|--------|
147
- | `/orc`, `/orc-ultra` | yes | yes |
148
- | `/orc-mini` | yes | yes |
149
- | `/orc-fast` | yes | no |
150
- | `/orc-diy` | compile-owned (`gotchas` flow key) | compile-owned |
151
- | `/orc-quick` | **no** | **no** |
152
- | `/orc-retro` | yes | no (read-only by contract) |
153
-
154
- ### Per-lane mechanics (the spines keep the trigger; this is the detail)
155
-
156
- **`/orc-mini` — reads AND writes, trimmed to one row.** Phase 1: probe
157
- `orc gotcha status` and print exactly one of `gotchas: <n> known · <m> match` /
158
- `none yet` / `off` — never silent. Phase 3: inject the scope-matching entries into
159
- the single executor slice beside the pattern (cap 3, highest `hits` first; zero
160
- matches = no block, NEVER unfiltered). After the return: dedupe a
161
- `gotcha_recorded` body on `symptom`+`scope` (a match bumps `hits`/`last_seen`) and
162
- append it to `.claude/orc/gotchas.md` yourself. A capped-and-stopped loop records
163
- nothing. Mini has no separate review/verify phase, so its only writer is the
164
- executor return.
165
-
166
- **`/orc-fast` — reads only, and gains no third prerequisite.** Its two hard gates
167
- (a FRESH/AGING wiki + a cached pattern) are its entire design; a missing gotchas
168
- file is never a reason to fall back, and gotchas here are purely additive: probe,
169
- inject the scope-matching entries into the F2 slice, and stop there. It never
170
- writes one, because one executor plus one repair round is too little signal to
171
- attribute a cause — and a lane with no analyst writing repair memory is how that
172
- memory fills with guesses.
173
-
174
- **`/orc-quick` does not participate at all — not even reading.** Its Q0 preflight
175
- reads `log_dir` and no other config key, by contract. A `gotchas` key read would
176
- break that guarantee, and the lane's whole premise is fewer steps, not more
177
- knowledge. This exclusion is intentional and is not an oversight to "fix".
1
+ # Shared contract — Gotchas (repair memory that outlives the run)
2
+
3
+ Canonical file: `_shared/gotchas.md`. THE one description of ORC's repair memory:
4
+ what a gotcha is, where it lives, when one is recorded, when one is injected, and
5
+ which lane may do which. Gate: config `gotchas` (`on` | `off`, default `on`).
6
+
7
+ ## 1. What a gotcha is
8
+
9
+ **ONE project-specific failure that a repair in this project already solved.**
10
+ Not a rule, not a preference, not a lesson in general.
11
+
12
+ It is deliberately none of the other three knowledge artifacts:
13
+
14
+ | Artifact | Answers | Not this |
15
+ |---|---|---|
16
+ | the wiki | "what IS this codebase" | a gotcha is not a fact about the code |
17
+ | the pattern cache | "how does this project WRITE code" | a gotcha is not a convention |
18
+ | `tdd_spec` | "what must this change PROVE" | a gotcha is not an acceptance test |
19
+ | **gotchas** | **"what has this project already gotten WRONG here"** | — |
20
+
21
+ If a finding fits one of the first three rows, it belongs there. A gotcha is the
22
+ residue of a repair: something went red, a specific cause was found, a specific
23
+ fix made it green.
24
+
25
+ ## 2. The artifact
26
+
27
+ ```
28
+ .claude/orc/gotchas.md # live entries, capped at gotchas_max
29
+ .claude/orc/gotchas-archive.md # evicted entries — never hard-dropped
30
+ ```
31
+
32
+ Both sit BESIDE the pattern cache (`orc/patterns/`), never inside it. Like every
33
+ file ORC generates under `.claude/orc/`, neither is in the install manifest — so
34
+ `orc update --prune` can never delete them and `orc update` never overwrites them.
35
+ They are user data by ORC's own rules.
36
+
37
+ **Entry format** — the parser and every writer depend on this exactly:
38
+
39
+ ```markdown
40
+ ## G-014 · express · repair
41
+ - trigger: adding a route handler that awaits a Mongoose query
42
+ - symptom: Cannot read properties of undefined (reading 'session') in tests
43
+ - cause: the test harness stubs req.session only for authed routes
44
+ - fix: register the route under authedRouter, not app
45
+ - scope: src/routes/**/*.js
46
+ - origin: run-orc-add-billing-050826-141233 · TDD repair round 2
47
+ - hits: 3
48
+ - last_seen: 05-08-2026
49
+ ```
50
+
51
+ - Heading: `## G-<3-digit id> · <lang-or-area> · <kind>`; `kind` ∈
52
+ `repair | drift | review | verify`.
53
+ - Field order is FIXED. Every field is required. Values are single-line.
54
+ - `scope` is a glob matched against a task's `declared_files`.
55
+ - Dates are `DD-MM-YYYY` (the repo's convention).
56
+ - IDs are monotonic; **never reused**, even after archival — an archived gotcha
57
+ stays traceable from a trace or a run doc that cited it.
58
+
59
+ ## 3. Existence probe (never a `find`)
60
+
61
+ ```
62
+ orc gotcha status exit 0 = one or more live entries · exit 1 = none
63
+ orc gotcha list the same contract, and prints the entries
64
+ orc gotcha prune archive the low-value tail down to gotchas_max
65
+ ```
66
+
67
+ **The exit code IS the contract**, same convention as `orc pattern status <lang>`
68
+ and `orc diy status`. `.claude/` is a hidden directory, so an ad-hoc `find`/glob
69
+ false-negatives from the wrong CWD or when it skips dot-dirs — the same reason
70
+ `detecting-artifacts.md` exists for the wiki and the pattern cache. Probe once,
71
+ treat the result as the source of truth, and never second-guess a positive probe.
72
+
73
+ ## 4. When one is RECORDED
74
+
75
+ At phase close, **when and only when a repair loop went red → green**:
76
+
77
+ - the TDD repair loop turned a failing `tdd_spec` test green;
78
+ - a `DRIFT-FROM` recovery round resolved the drift;
79
+ - a reviewer P0/P1 that THIS SAME RUN fixed;
80
+ - a verifier `unmet[]` entry that THIS SAME RUN closed.
81
+
82
+ **A loop that hit its cap and STOPPED records NOTHING.** An unsolved failure is
83
+ not a gotcha — it is an open problem, and the honest red report is where it
84
+ belongs. Writing one anyway would seed the memory with advice that never worked.
85
+
86
+ Nothing else records. A first-try success has no repair to remember; a green
87
+ `regression-guard` test proved something, but it was never red.
88
+
89
+ ## 5. Who writes it
90
+
91
+ Three parties, and they do not overlap:
92
+
93
+ 1. **The agent RETURNS the body** in `gotcha_recorded` (see
94
+ `return-validation.md` §7) — either the entry fields or `none` + a one-line
95
+ reason. The agent that did the repair is the only party that knows the cause.
96
+ 2. **The ORCHESTRATOR hands it to `orc gotcha add -`** (§10), at the same
97
+ phase-close point where it dispatches the trace packet. **A subagent never
98
+ writes either gotcha file.**
99
+ 3. **The CLI owns counting, capping and archival** (`orc gotcha prune`) —
100
+ deterministic bookkeeping, never a model's judgement.
101
+
102
+ ## 6. Dedupe (before every append)
103
+
104
+ `orc gotcha add` does this; the rule is written here so a person can check it.
105
+ Compare the returned `symptom` + `scope` against the live entries. A match:
106
+ increment `hits`, refresh `last_seen`, and **append nothing**. Only a genuinely
107
+ new failure gets a new ID. Without this the file grows one duplicate per run and
108
+ the injection cap fills with the same entry three times.
109
+
110
+ ## 7. When one is INJECTED
111
+
112
+ Into an executor slice, **filtered by the `scope` glob against that task's
113
+ `declared_files`**.
114
+
115
+ - **NEVER inject unfiltered.** An unfiltered injection is the exact failure mode
116
+ that turns this feature into the bloat it exists to prevent.
117
+ - Cap **3 entries per slice**, highest `hits` first.
118
+ - **Zero matches = no gotcha block at all** — not an empty one. An empty block
119
+ costs tokens and says nothing.
120
+
121
+ The block rides beside `pattern` in the slice, and like `pattern` it is injected
122
+ LITERALLY, never as a file pointer.
123
+
124
+ ## 8. Who reads it
125
+
126
+ - **Phase 1 preflight** — one line, never silent (see
127
+ `../orc/references/preflight-report.md`).
128
+ - **executor slices** — filtered, capped, per §7.
129
+ - **the reviewer** — the matching entries as a checklist: has this change
130
+ reintroduced a failure this project already paid for?
131
+ - **`/orc-retro`** — read-only calibration input. It never writes one.
132
+
133
+ ## 9. Staleness is the user's job
134
+
135
+ An injected gotcha is presented to an executor as **fact**. Nothing in ORC
136
+ re-verifies that it is still true — `orc gotcha prune` handles CAPACITY, not
137
+ correctness.
138
+
139
+ So, plainly: **delete an entry that stopped being true.** Open
140
+ `.claude/orc/gotchas.md` and remove the block. That is the whole procedure, and
141
+ it is deliberately manual — a model deciding which of its own memories to forget
142
+ is a worse failure mode than a stale line a human can read.
143
+
144
+ ## 10. Lane policy (v2.0.0 — who reads, who records, and where)
145
+
146
+ | Lane | Reads | Records (an observation; promotion is computed) |
147
+ |------|-------|-------|
148
+ | `/orc`, `/orc-ultra` | match (executors) · card (Phase 5 reviewer, Phase 6 verifier, ultra gate 3) · filter (after Phase 5) | repairs (via `add`) · every Phase 5 finding's outcome · defect repros |
149
+ | `/orc-mini` | match · card (when the risk option dispatches the reviewer) · filter | repairs · a smoke-gate repair round that went green · reviewer outcomes |
150
+ | `/orc-fast` | match | nothing |
151
+ | `/orc-quick` | card for the review offer · match for code dispatches | a defect repro red → green · a PR thread taken and fixed · a Sonar/SARIF item fixed · a CI failure fixed · a review-offer P0/P1 fixed · a finding the user disputed |
152
+ | `/orc-verify` | card (its adversarial pass) | nothing — read-only lane stays read-only |
153
+ | `/orc-pr-driver` | card at the per-layer gate | a green-gate lint/seam fix |
154
+ | `/orc-diy` | compile-owned (`gotchas` flow key) | compile-owned |
155
+ | `/orc-retro` | yes | no (read-only by contract) |
156
+
157
+ The `gotchas` key (`on` | `off`) now gates ONLY the executor block
158
+ (`orc gotcha match` exits 4 under `off`). The reviewer card has no off answer
159
+ (review learning is always on); `gotcha_card_budget` is only its size.
160
+
161
+ ### How a lane records — ONE CLI call, where it already writes
162
+
163
+ - **An observation:** `orc gotcha observe - --json`, stdin ONE JSON object:
164
+ `source` (`repair` · `drift` · `review` · `verify` · `defect` · `ci` · `pr` ·
165
+ `sonar` · `sarif` · `dismissal`), `ref` (unique per event, e.g.
166
+ `<run> · F3` — the same `ref` REPLACES the earlier line), `outcome`
167
+ (`addressed` · `disputed` · `wontfix` · `open` · `flaky`), `author` (`orc` ·
168
+ `human` · `bot`), `rule` or `sig` (the finding text), and when known
169
+ `category`, `severity`, `path`, `lines`, `run`, `gotcha` (the `G-###` the
170
+ finding cited). Exit 0 = appended and promotion ran · 2 = malformed: say it
171
+ once and go on. **It never blocks a run.** The CLI alone writes
172
+ `.claude/orc/observations.jsonl`; a lane never edits it.
173
+ - **A red → green repair:** the `gotcha_recorded` body goes to
174
+ `orc gotcha add -` (exit 0 added · 3 bumped an existing entry · 2 malformed).
175
+ The CLI dedupes, assigns the id and writes the entry. Nobody appends by hand.
176
+ - **The outcome is PROGRAMMATIC**, never a model's opinion: the flagged lines
177
+ changed before ship = `addressed`; the user said "not a problem here" =
178
+ `disputed`; declined with no reason = `wontfix`; none of these yet = `open`.
179
+
180
+ ### Review close — the same step in every lane that ran a review
181
+
182
+ After `review-slice.md` §3 and the fixes: ONE observation per finding
183
+ (`source: review`, `author: orc`, the outcome above, `gotcha` when the finding
184
+ cited one), then ONE trace line:
185
+ `FINDING-OUTCOME addressed=<n> disputed=<n> wontfix=<n> open=<n> pre=<n> suppressed=<n> :: <cat>:<addressed>/<total>,…`.
186
+ Where: `/orc` and `/orc-ultra` at Phase 7 (`phases/summary.md`), `/orc-mini`
187
+ after the risk option's review, `/orc-quick` after the review offer. A review
188
+ with zero findings records nothing and is a HEALTHY answer.
189
+
190
+ ### Per-lane mechanics (the spines keep the trigger; this is the detail)
191
+
192
+ **`/orc-mini` — reads AND writes, trimmed to one row.** Phase 1: probe
193
+ `orc gotcha status` and print exactly one of `gotchas: <n> known · <m> match` /
194
+ `none yet` / `off` — never silent. Phase 3: inject the scope-matching entries into
195
+ the single executor slice beside the pattern (cap 3, highest `hits` first; zero
196
+ matches = no block, NEVER unfiltered). After the return: pipe a
197
+ `gotcha_recorded` body to `orc gotcha add -` (a match on `symptom`+`scope`
198
+ bumps `hits`/`last_seen`). A capped-and-stopped loop records nothing. A
199
+ smoke-gate repair round that went green records `source: repair`. When the
200
+ risk option ran the reviewer, record its outcomes as "Review close" says.
201
+
202
+ **`/orc-fast` — reads only, and gains no third prerequisite.** Its two hard gates
203
+ (a FRESH/AGING wiki + a cached pattern) are its entire design; a missing gotchas
204
+ file is never a reason to fall back, and gotchas here are purely additive: probe,
205
+ inject the scope-matching entries into the F2 slice, and stop there. It never
206
+ writes one, because one executor plus one repair round is too little signal to
207
+ attribute a cause — and a lane with no analyst writing repair memory is how that
208
+ memory fills with guesses.
209
+
210
+ **`/orc-quick` — reads and records, since 2.0.0 (a deliberate reversal).**
211
+ Record at step 3.3, after entry N is appended, and only for a request with
212
+ programmatic proof: a defect entry with `REPRO red` then `REPRO green`
213
+ (`source: defect`, `reproduced: true`) · a PR thread the request took and fixed
214
+ (`source: pr`) · a Sonar or SARIF item fixed (`source: sonar` / `sarif`) · a CI
215
+ failure fixed (`source: ci`) · a review-offer P0/P1 fixed (`source: review`,
216
+ `addressed`) · a review finding the user called "not a problem here"
217
+ (`source: review`, `disputed`). A plain fix with none of these records nothing.
218
+ Why the reversal: quick is where most of the fixes happen, so a memory that
219
+ skips it never learns; a PR thread is a human's judgement and a red → green
220
+ repro is proof, so the v1 "too little signal" objection does not apply; and the
221
+ card and `observe` are CLI calls — the CLI reads the `gotchas` key, so Q0 still
222
+ reads `log_dir` and no other config key itself.
223
+
224
+ **`/orc-pr-driver` — the card is advice only.** A rung that went red and then
225
+ green after a lint or seam fix records `source: repair` (`ref`: the layer and
226
+ the rung). The gate itself stays build · tests · lint · hooks.
227
+
228
+ **`/orc-verify` and `/orc-retro` never record.** Both are read-only by contract.
@@ -0,0 +1,101 @@
1
+ # Shared contract — habits (the lane side, read ON DEMAND)
2
+
3
+ Canonical file: `_shared/habits.md`. **Read it ONLY when the
4
+ `orc lane config <lane> --json` answer has a `habits{}` block.** No block means
5
+ `habits: off` (the default). Then the lane emits NO `ASK` line, shows NO
6
+ suggestion, prints NO habits line and makes NO proposal, and every `(H <qid>)`
7
+ mark in a spine or phase file means nothing. Off costs zero tokens.
8
+
9
+ The CLI owns the rule (`orc habit`, `bin/habit.js`). The lane reads `habits{}`,
10
+ shows what it says, and records each answer. **Nothing is applied without a
11
+ yes.** `orc habit points --json` lists every qid and its option ids.
12
+
13
+ ## 1. Preflight — one line
14
+
15
+ Print `habits.line` VERBATIM with the other preflight lines. A learned key
16
+ (`habits.learned[]`) is already resolved into `effective` at the `learned`
17
+ rank, and its line is already in `announce[]` — print it like every other
18
+ announce line. Do not re-derive it.
19
+
20
+ ## 2. At each question marked `(H <qid>)`
21
+
22
+ **Never ask what is already answered.** The request said it (the intent
23
+ ledger), a config key set it, or a learned key answers it → do not ask. Use
24
+ that answer, say it in one line, and record `by=ledger|config|learned`.
25
+ `orc stats --json` → `questions{}` counts the questions asked per run, per lane
26
+ and per point, so each extra question shows.
27
+
28
+ 1. **Suggestion.** A `habits.suggestions[]` row with this `qid` (and a `bucket`
29
+ that matches this question's ctx) → put its `option` FIRST and add its `mark`
30
+ (`→ usual (<count> of <total>)`) beside it. It is a recommendation, never a
31
+ pre-selection. **The question is still asked.** Under `observe` the CLI
32
+ sends no suggestion.
33
+ 2. **Learned key.** A `learned[]` row answers the key of this qid → do not ask;
34
+ use its value and say so in one line. The user can still override it.
35
+ 3. **Record.** Put ONE `ASK` event in the phase packet (grammar:
36
+ `trace_grammar` → `ASK`, `./phases/trace-verbs.md`):
37
+ `ASK <qid> :: offered=<o1|o2|…> rec=<o|none> chose=<o|other> by=<…> [pre=<o>] [ctx=<k=v,…>]`
38
+ - `offered`, `rec`, `chose`, `pre` are option ids from `orc habit points`.
39
+ An answer in the user's own words is `chose=other`. **Never store the
40
+ words.**
41
+ - `by`: `user` answered it · `ledger` the request said it up front ·
42
+ `learned` a learned key or a `→ usual` pre-mark answered and the user
43
+ kept it · `config` a config key answered and the question was not shown ·
44
+ `default` the lane default answered and the question was not shown.
45
+ - `pre=<o>` only when an option was pre-marked or pre-selected.
46
+ - `ctx` only with what the lane knows: `branch=main|feature|fix|release|other`,
47
+ `kind=feature|defect|pr|read|refactor`, `size=s|m|l`, `risk=none|cited`.
48
+ Never guess a missing key.
49
+
50
+ ## 3. Run end — at most ONE proposal
51
+
52
+ `habits.proposal` is set → add its `line` to the EXISTING end-of-run batch. One
53
+ line, no new turn. Run the command the answer names — it is part of the
54
+ `lane config` answer, so it is an allowed call:
55
+ yes → `proposal.yes` · keep asking (a re-ask) → `proposal.keep` ·
56
+ later / not now → `proposal.later` · never → `proposal.never`.
57
+ A `null` command is an answer that is not offered. Put `proposal.trace` in the
58
+ last packet with `chose=` filled in. No proposal → say nothing.
59
+ The end-of-run batch per lane: `/orc` and `/orc-ultra` the Phase 8 completion
60
+ report · `/orc-mini` the end-of-run batch · `/orc-fast` the F4 ship offer ·
61
+ `/orc-quick` the Q3 offers · `/orc-analyze` the Phase F choice · `/orc-diy` the
62
+ compiled flow's last phase. `/orc-wait` makes no proposal.
63
+
64
+ ## 4. Lane notes
65
+
66
+ - **`/orc-quick`.** The dispatch gate is asked EVERY time. A habit only fills
67
+ its `→ suggested` line (Q2b), with the CLI's numbers as the reason.
68
+ `review_before_push` and `quick_update_tests` touch the OFFERS after the work,
69
+ never the gate. A `quick.q3.offer.review` suggestion of `review-first` makes
70
+ offers 2 and 3 ONE offer: *review → then commit (your usual, 9 of 10) ·
71
+ commit without review · stop*. The review is a dispatch, so its gate is still
72
+ asked. ctx: `kind`, `branch`.
73
+ - **`/orc-mini`.** A learned `mini_tdd: on` → intake does not ask the TDD
74
+ question; its `announce[]` line names the habit and its undo. A habit
75
+ toward `no` is a pre-mark only, never applied. A learned
76
+ `review_before_push: on` → the end-of-run batch ALWAYS carries option *a*
77
+ (dispatch `orc-reviewer-opus-5-med` on the diff), marked `→ usual`, even with
78
+ no `risk: high` row. Record `any.ship.review-before-push` whenever option *a*
79
+ is offered: `chose=review` when the user takes it, else `push`.
80
+ - **`/orc-fast`.** `fast.f0.stale-wiki`: a habit NEVER suggests `continue`
81
+ (a stale wiki is a risk the user takes each time). The CLI never proposes
82
+ it (`never_option`); a suggestion row that names it anyway is ignored. Show
83
+ a `refresh` or `mini` suggestion only, and never apply one. A learned `review_before_push: on` → F4
84
+ offers a dispatch of `orc-reviewer-opus-5-med` on the diff FIRST (P0/P1 block
85
+ the commit), marked `→ usual`; the reviewer is not in the fast pipeline, so
86
+ it runs only on that yes. Record `any.ship.review-before-push` whenever it is
87
+ offered.
88
+ - **`/orc` and `/orc-ultra`.** The points live in the phase files. Ultra forces
89
+ its overrides for the run: a habit never answers a forced key or question
90
+ (analysis depth, pattern findings, test authoring, security review) — record
91
+ those `ASK`s `by=config`, and the habits line says ultra wins.
92
+ - **`any.analysis.depth`** (`/orc`, `/orc-analyze`): a suggestion only. `deep`
93
+ needs the user's explicit yes EVERY run — a habit never picks it and never
94
+ skips the question. ctx: none.
95
+ - **`/orc-diy`.** The compiled flow asks the same questions as the phases it
96
+ came from and emits the same `ASK`. A question the flow's `autonomy`
97
+ (`semi` · `hands-off`) answered is `by=default` and never counts toward a
98
+ habit — it was not a choice.
99
+ - **`/orc-wait`.** `any.stop.where` only, at W6. The wait opens no run: the
100
+ `ASK` goes in the NEXT packet of the run in flight, and only when that run's
101
+ `lane config` answer had `habits{}`.
@@ -0,0 +1,84 @@
1
+ # Shared contract — the lane contract (Calls · Config · Rules · Trace · Phases · Wait)
2
+
3
+ Canonical file: `_shared/lane-contract.md`. It holds, ONCE, the text that every
4
+ coding-lane spine used to repeat in six blocks. **Read it ONLY when a CLI call
5
+ exits ≠ 0.** Otherwise the spine's pointer lines are enough: each pointer names
6
+ the lane's OWN values (its `orc lane calls` / `orc lane config` spelling, its
7
+ trace token and tier, its checkpoint and safe point). This file never restates
8
+ those values, and a spine never restates this file.
9
+
10
+ ## Calls
11
+
12
+ **ONE catalogue, and it is not you:** `orc lane calls <lane> --json` names every
13
+ CLI call the lane makes. Each row gives the exit-code contract, the cost, when
14
+ to run the call, and what an EMPTY answer means.
15
+
16
+ - Never invent a spelling. Never re-word an exit code.
17
+ - Never re-derive a state word. The CLI's state words are the only state words.
18
+ - **An exit code is an ANSWER wherever that contract says so, not a failure.**
19
+ - A call that the answer does not name is a call the lane does not make.
20
+ - The catalogue itself exits ≠ 0 → say that the CLI is unavailable. Before you
21
+ run a command, name it out loud.
22
+
23
+ ## Config
24
+
25
+ **ONE resolver, and it is not you:** `orc lane config <lane> --json`. A spine
26
+ carries ONE of two forms. `bin/verify-contracts.js` decides which one.
27
+
28
+ - **Full form** — the lane reads a contested, gated or inert key. Obey
29
+ `effective`. Print every line in `announce[]` VERBATIM at preflight. Honour
30
+ `stops[]` before wave 1 (or before the lane's first unit of work, which the
31
+ spine names).
32
+ - **Short form** — the lane reads nothing contested, gated or a stop. Obey
33
+ `effective`. The lane owes no preflight line and has no gate to honour.
34
+
35
+ Both forms:
36
+
37
+ - Never merge `.claude/orc.config.yaml` yourself.
38
+ - Never re-derive a value, a precedence or an inertness from that file. A key
39
+ that the lane does not read is not in the answer. A key that another key
40
+ shadows comes back already marked.
41
+ - Exit ≠ 0 → say that the CLI is unavailable. Fall back to the documented
42
+ defaults of `config-precedence.md`, out loud.
43
+ - Priorities and families: `config-precedence.md`.
44
+
45
+ ## Rules — the anti-slop card
46
+
47
+ `orc rules slice --lane <lane> --json` is the ONLY assembler. Never build the
48
+ card in the spine. Canonical: `phases/rules.md`.
49
+
50
+ - The card rides under the house rules and above the task:
51
+ **house rules > your project's rules > ORC's own packs**.
52
+ - Its `line` prints VERBATIM at preflight.
53
+ - Returns gain `rules_applied[]`, `rules_conflicts[]` (a gap, never a silent
54
+ choice) and `rules_overridden[]`.
55
+
56
+ ## Trace
57
+
58
+ Canonical: `phases/trace.md` (layer `core`, loaded at run start).
59
+ `orc lane phases <lane> --json` names the file and the layers, and its
60
+ `trace_grammar` gives the verbs. The tier table in `trace.md` defines the
61
+ packet count for each tier. The spine names only its token, its tier, its own
62
+ unit, and its run-start step. Nothing else about the protocol is restated in a
63
+ spine.
64
+
65
+ ## Phases
66
+
67
+ `orc lane phases <lane> --json` is the lane's pipeline: the ordered list, where
68
+ each phase lives, and how much of it to read.
69
+
70
+ - **The CLI owns the order.** Never derive it from the spine's headings.
71
+ - Never renumber or rename a phase heading without the manifest. A
72
+ `read: section` pointer names a HEADING, so a renamed heading is a pointer
73
+ into nothing.
74
+
75
+ ## Wait
76
+
77
+ Canonical: `wait.md`. The spine names its checkpoint and its safe point, the
78
+ same values as `orc wait lanes`. The modes, the safe points and the
79
+ never-begin-a-wait list are in `wait.md` only.
80
+
81
+ - Checkpoint `none` → nothing to checkpoint, so the three modes behave the
82
+ same. Say so. Do not ask.
83
+ - Any other checkpoint → `soft` FORCES the checkpoint and does NOT stop if the
84
+ write fails. `hard` skips it and can lose an in-flight return.