@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
@@ -0,0 +1,448 @@
1
+ # Running ORC work on another AI model
2
+
3
+ > `orc extra` — the provider-by-provider setup detail that would bloat the
4
+ > README. For what the subsystem IS and why it is shaped this way, see
5
+ > `knowledge.md` §4z.15. For the panel, open `orc ui` ▸ **Extra**.
6
+
7
+ ORC scores every task and picks the cheapest capable Claude model for it. This
8
+ lets you point a **band of that score ladder** at somewhere else — DeepSeek, Z.ai
9
+ (GLM), Moonshot (Kimi), MiniMax, Qwen, Xiaomi MiMo, StepFun, SiliconFlow,
10
+ OpenRouter, a local Ollama, any endpoint you name, or an agentic CLI you already
11
+ have installed.
12
+
13
+ **ORC's own session never moves.** Only the task slice does. The orchestrator,
14
+ the planner, the reviewer and the verifier stay where they are unless you name
15
+ them explicitly in `extra_roles`.
16
+
17
+ ---
18
+
19
+ ## The five minutes
20
+
21
+ ```bash
22
+ orc extra providers # what ORC knows how to reach, and its date
23
+ orc extra tools # ...and which of them are programs you must install
24
+ orc extra add cheap --provider deepseek --engine api --env-key DEEPSEEK_API_KEY
25
+ orc extra ping cheap # THE GATE. Nothing routes until this passes
26
+ orc extra route set 0-30 cheap/deepseek-chat
27
+ orc config set extra_enabled true # nothing is armed until you do this
28
+ orc extra route # the whole ladder, including what stays on Claude
29
+ ```
30
+
31
+ Then run a lane as usual. Every armed run prints an `extra:` line at Phase 1,
32
+ before wave 1, naming how many tasks will cross the boundary and where they go.
33
+
34
+ ### Undoing it
35
+
36
+ ```bash
37
+ orc config set extra_enabled false # everything falls back to Claude, instantly
38
+ orc extra route rm 0-30 # or drop one band
39
+ orc extra remove cheap --reason "…" # or the whole connection (a reason is required)
40
+ ```
41
+
42
+ ---
43
+
44
+ ## Choosing an engine
45
+
46
+ | engine | what it runs | pick it when |
47
+ |---|---|---|
48
+ | `api` | ORC's own tool loop against an OpenAI-compatible endpoint | you want the **file fence** or a **privacy policy** — this is the only engine that composes the request body, so it is the only one that can enforce either |
49
+ | `claude-shim` | a nested `claude -p` pointed at the provider's `/anthropic` base | you want the highest tool fidelity for the least setup — it is Claude Code's own agent loop, driven by somebody else's model |
50
+ | `cli` | an agentic CLI you already have (`opencode`, `codex`) | you already trust that tool, or you want to attach to a server it is running. **These are programs on your machine** — see *Tools that live on this machine* below |
51
+
52
+ **The asymmetry matters and ORC never hides it.** On `api`, a task's
53
+ `declared_files` is a RULE the loop enforces. On the other two it is an
54
+ INSTRUCTION in the prompt, and a return that says the fence held is reported as a
55
+ warning rather than a pass — a constraint that was never applied is never
56
+ reported as kept.
57
+
58
+ Not sure? Start with `claude-shim` if your provider publishes an `/anthropic`
59
+ base (most in the catalog do), and switch to `api` the day you want the fence.
60
+
61
+ ---
62
+
63
+ ## Tools that live on this machine
64
+
65
+ Two of the things ORC can hand work to are not websites — they are programs
66
+ installed on your own computer. That means one thing no endpoint ever does:
67
+ **it can simply not be there.**
68
+
69
+ ```bash
70
+ orc extra tools # what is installed, what version, signed in, how many models
71
+ ```
72
+
73
+ Four states, and each one has exactly one next thing to do:
74
+
75
+ | state | what it means | what to do |
76
+ |---|---|---|
77
+ | `absent` | the program is not on your PATH | install it (below) — `orc extra add` will refuse until you do, and it names the command |
78
+ | `outdated` | older than the version ORC knows how to drive | the same install, as an upgrade |
79
+ | `unauthenticated` | installed, but no sign-in ORC can see | `orc extra keyhelp <profile>` says what it takes |
80
+ | `ready` | version, sign-in, and a live model list | connect, or test |
81
+
82
+ One of the two has a route that needs no install at all — an ordinary endpoint
83
+ serving the same models, reachable with a key. The other does not, and ORC says
84
+ so plainly rather than leaving you looking for one.
85
+
86
+ ### Letting ORC run the install
87
+
88
+ ```bash
89
+ orc extra install <provider> # opens a terminal window and runs it there
90
+ ```
91
+
92
+ **It runs in YOUR terminal, not in the background.** A global install can ask for
93
+ a password, hit a permissions error, pull 80 MB or take a minute — and inside a
94
+ hidden process all four look the same: nothing happened. So you get a real
95
+ window, with the command printed on screen before it runs, which you can read,
96
+ scroll and stop with Ctrl-C.
97
+
98
+ **ORC never asks for administrator rights.** If your package manager needs them,
99
+ you will see it ask, in your own window, and it is your call. If no terminal can
100
+ be opened at all — over SSH, or on a locked-down machine — you get the command to
101
+ paste and nothing pretends otherwise.
102
+
103
+ Come back and press *Check again* (or re-run `orc extra tools`) when it is done.
104
+ ORC stores no "installing" state, because you might close the window and that
105
+ flag would be a lie from then on.
106
+
107
+ ### ORC never touches the tool's own sign-in
108
+
109
+ Your key stays in ORC's vault or in your own environment variable, and ORC hands
110
+ it to the program for each run. Nothing global changes, revoking it in ORC
111
+ actually revokes it, and if you already signed that tool in yourself, ORC leaves
112
+ it completely alone — say so with `--tool-auth` and ORC will not ask you for a
113
+ key at all.
114
+
115
+ ```bash
116
+ orc extra keyhelp <profile> # which of three routes applies, and why
117
+ ```
118
+
119
+ ---
120
+
121
+ ## The credential
122
+
123
+ Three sources, and **the right one depends on who already holds the key**:
124
+
125
+ ```bash
126
+ # 1. an environment variable your OS already protects ← recommended
127
+ orc extra add cheap --provider deepseek --engine api --env-key DEEPSEEK_API_KEY
128
+
129
+ # 2. the encrypted vault, for people who would rather not manage variables
130
+ orc extra add cheap --provider deepseek --engine api --key-stdin
131
+ printf '%s\n%s\n' "$KEY" "$PASSPHRASE" | orc extra ping cheap --key-stdin
132
+
133
+ # 3. the tool signs itself in and holds its own key ← engine `cli` only
134
+ orc extra add local --provider opencode --engine cli --cli opencode --tool-auth
135
+ ```
136
+
137
+ **If `orc extra tools` says a program is signed in, use option 3.** It needs no
138
+ key from ORC, no variable, no vault and no deadline — and ORC never writes
139
+ another tool's credential store. The connect form in `orc ui` offers all three,
140
+ and pre-selects this one when the tool you pressed Connect on is already signed
141
+ in.
142
+
143
+ There is deliberately **no `--key <value>`**. argv is world-readable in a process
144
+ list and lands in shell history, so ORC refuses that flag by name.
145
+
146
+ ### If you use the vault, read this once
147
+
148
+ - The key is encrypted with **your passphrase plus a per-machine pepper**. ORC
149
+ does not store the passphrase and **cannot recover it**.
150
+ - The key is stored **only after a connection test passes**. A failed test leaves
151
+ nothing behind — not the key, not even the profile.
152
+ - **Ten wrong attempts and ORC deletes the stored key on purpose.** The profile,
153
+ its routes and its cached model names survive; you paste a new key.
154
+ - The counter stops someone at your keyboard. It does **not** stop someone who
155
+ copies the vault file and tries offline — scrypt's cost is the only defence
156
+ there, which is why unlocking takes a moment and why that must never be "sped
157
+ up".
158
+
159
+ ```bash
160
+ orc extra unlock cheap # prove the passphrase (the key is never printed)
161
+ orc extra rekey cheap # change it (needs the old one)
162
+ orc extra ping cheap --passphrase-stdin # re-test a stored key
163
+ ```
164
+
165
+ `extra_unlock` decides when you are asked. `per-run` (the default) asks ONCE at
166
+ the Phase-1 stop the lane already has; `per-dispatch` asks every time and
167
+ **refuses to start an unattended wave**, naming why.
168
+
169
+ ### Save the passphrase, with a deadline
170
+
171
+ Without this, a vaulted key needs the passphrase every single time — and a run
172
+ that cannot get it announces a fallback to Claude and carries on. That is safe,
173
+ and it is also a decision being made for you.
174
+
175
+ ```bash
176
+ printf '%s\n' "$PASSPHRASE" | orc extra session cheap --save --ttl 30
177
+ orc extra session # every connection, and when each deadline falls
178
+ orc extra session cheap --forget # delete it now
179
+ orc extra preflight # the gate that runs before wave 1
180
+ ```
181
+
182
+ **Say the honest part out loud, because it is the whole shape of the feature:**
183
+ a passphrase stored on the same machine as the vault it opens is **not a second
184
+ factor any more — it is a deadline**. While it is saved, anything that can run
185
+ as you on this computer can open the connection. The deadline is what limits
186
+ that.
187
+
188
+ One thing it does keep, and it is real: the passphrase is cached **in the
189
+ project** and encrypted under a key that lives in **your home directory**, so
190
+ **copying the project folder to another computer opens nothing**.
191
+
192
+ - Deadlines are a closed set: **1 · 3 · 7 · 14 · 30 · 90 · 180 · 360 days.** There is
193
+ no `0` and no "forever" — "forever" is the option that makes every other one
194
+ pointless. `extra_passphrase_ttl_days` (default 30) is only what the picker
195
+ opens on; the deadline is stored per connection.
196
+ - **Using it does not extend it.** A deadline that renews itself is not a
197
+ deadline.
198
+ - **When it runs out, the next run STOPS.** It does not fall back to Claude:
199
+ `extra_on_failure` is about an endpoint that failed, and this is a deadline you
200
+ set yourself. The stored key is deleted and the connection is marked expired
201
+ — **but your routing rows survive**, so re-connecting is one step, not a
202
+ rebuild.
203
+ - `--passphrase <value>` does not exist, for the same reason `--key <value>` does
204
+ not.
205
+
206
+ ---
207
+
208
+ ## Model names
209
+
210
+ **ORC ships no model ids, ever.** They change within a quarter and they change
211
+ silently — a stale one is a 404 in the middle of a wave. `orc extra ping` reads
212
+ the live list from the provider and caches it:
213
+
214
+ ```bash
215
+ orc extra models cheap # what the last ping actually saw
216
+ ```
217
+
218
+ A route may name a model outside that list — ORC's cache is not the authority on
219
+ somebody else's catalogue — but it becomes an `orc extra doctor` finding rather
220
+ than a surprise later.
221
+
222
+ ### A model on the list is not a model that works
223
+
224
+ This one costs people real time, so it is worth the paragraph. A model list is
225
+ what the provider **offers**. An id can be on that list and still be dead: it
226
+ answers *"model is unavailable"* the moment you actually call it. That has been
227
+ seen on a live provider, with an id its own list returned.
228
+
229
+ There is exactly one way to tell those apart:
230
+
231
+ ```bash
232
+ orc extra models cheap --refresh # re-read the live list
233
+ orc extra models cheap --test <model-id> # actually call it. THIS costs money
234
+ orc extra ping cheap --live # or test the whole connection for real
235
+ ```
236
+
237
+ `--live` sends one short fixed message and shows you the round trip, the reply,
238
+ and what it cost — split into four token counts that are never added together.
239
+
240
+ **A real message through a local tool is not a cheap test.** The tool loads its
241
+ own instructions and tool definitions before it sends anything, so one short
242
+ message costs thousands of words of input rather than a handful. ORC says which
243
+ of the two you are about to spend before you press the button.
244
+
245
+ **Neither local tool tells you which model actually answered.** So if one quietly
246
+ served you something else, nothing here can detect it — ORC prints that sentence
247
+ rather than leaving the field blank, because a blank reads as "all fine".
248
+
249
+ ### Providers with regions
250
+
251
+ `moonshot`, `minimax` and `qwen` serve different base URLs per region:
252
+
253
+ ```bash
254
+ orc extra add kimi --provider moonshot --engine api --region cn --env-key MOONSHOT_API_KEY
255
+ ```
256
+
257
+ `orc extra providers --json` lists every region a provider declares.
258
+
259
+ ### A provider ORC has never heard of
260
+
261
+ ```bash
262
+ orc extra add mine --provider custom --engine api \
263
+ --base-url https://api.example.com/v1 --env-key MY_KEY
264
+ ```
265
+
266
+ `custom` is the escape hatch that keeps the catalog from being a gate. You supply
267
+ the base URL; everything else works the same.
268
+
269
+ ### A local model
270
+
271
+ ```bash
272
+ orc extra add local --provider ollama --engine api --base-url http://localhost:11434
273
+ ```
274
+
275
+ Nothing leaves your machine at all. Note that Ollama's Anthropic-compatible
276
+ surface rejects an `x-api-key` header, which is why the catalog names the auth
277
+ variable rather than a header — ORC sends whichever one that variable implies.
278
+
279
+ ---
280
+
281
+ ## Deciding which bands to route
282
+
283
+ ```bash
284
+ orc extra route # the whole 0→100 ladder, foreign rows and Claude rows
285
+ orc extra resolve 42 # what a task scoring 42 would actually get, and why
286
+ ```
287
+
288
+ **A gap is not a hole — it is Claude.** The table is printed with the Claude
289
+ fall-through split at the Claude ladder's own edges, so "I left the hard work on
290
+ Claude on purpose" and "there is no band up there" can never look the same.
291
+
292
+ A sane starting shape is the bottom of the ladder only: the tasks ORC already
293
+ scores as mechanical are the ones where a cheaper model costs you least when it
294
+ is wrong. Then read `orc extra stats` after a few runs and move the line.
295
+
296
+ Rows may not overlap — ORC refuses one that would, and names the `route rm` that
297
+ clears it. Rows do **not** have to tile.
298
+
299
+ ### A band is not the same thing as a lane
300
+
301
+ ```bash
302
+ orc extra lanes # which lane each band actually governs
303
+ ```
304
+
305
+ `/orc` scores every task, so a row covering `[40,55)` applies score by score.
306
+ **`/orc-fast` does not work that way**: it pins ONE executor, so ORC resolves
307
+ that agent's band at **both edges** and requires them to agree. One edge foreign
308
+ and the other not — the lane stays on Claude, and `orc extra lanes` names the row
309
+ that covered only part of it. A row covering three scores out of fifteen should
310
+ not capture a whole lane.
311
+
312
+ Some lanes never route at all, whatever the table says: `/orc-quick` asks which
313
+ agent before every dispatch, and `/orc-challenge`'s lenses are measuring
314
+ instruments. **A lane the list does not mention does not route foreign** —
315
+ absence is a no, not an omission.
316
+
317
+ `/orc-doc` is its own case: it is a per-document switch, because a document's
318
+ voice is the deliverable.
319
+
320
+ ```bash
321
+ orc doc extra <slug> --set writer # off | writer | checker | both (default off)
322
+ ```
323
+
324
+ ---
325
+
326
+ ## What never leaves Claude, whatever the table says
327
+
328
+ - A task whose plan cites a **`risk[]`** (auth, money, migration, security,
329
+ concurrency, data-integrity) — `extra_risk_tasks`, default `off`.
330
+ - A task in an area a **boundary card marks REFUSE** — in `warn` mode as well as
331
+ `block`. A REFUSE is by construction an area where ORC cannot verify its own
332
+ output, so it is the last work that should go to the worker with the weakest
333
+ fence.
334
+ - Everything `extra_roles` does not name. The default is `executor` only.
335
+ - `/orc-challenge`'s lenses, always. Swapping a lens for a different model does
336
+ not make the lane cheaper — it changes what is being measured, invisibly.
337
+
338
+ ---
339
+
340
+ ## What it cost
341
+
342
+ ```bash
343
+ orc extra stats # per profile per band: outcomes, tokens, usd
344
+ orc extra rates # which provider/model pairs have a price
345
+ ```
346
+
347
+ Four token kinds are reported separately and **never blended**: fresh input,
348
+ cache write, cache read (usually the largest count and about a tenth of the
349
+ price) and output.
350
+
351
+ **ORC ships no prices.** Several of these vendors price by peak window or by
352
+ tier, one sells a subscription rather than tokens, and one is a passthrough with
353
+ a surcharge — a shipped figure wrong by 2× is worse than none, because a wrong
354
+ figure gets believed. `orc extra rates` prints the JSON to paste into your own
355
+ price table:
356
+
357
+ ```bash
358
+ orc config set budget_price_table ~/my-prices.json # so `orc update` never overwrites it
359
+ ```
360
+
361
+ Until a pair has a rate, `usd` reads as an em dash. That is the honest answer,
362
+ not a zero.
363
+
364
+ Three things only these stats can tell you, and they are different questions:
365
+
366
+ - **SUBSTITUTION** — you did not get the model you asked for.
367
+ - **REROUTE** — you got the model and a different company served it.
368
+ - **FALLBACK** — it did not work and Claude finished the job.
369
+
370
+ ---
371
+
372
+ ## When it goes wrong
373
+
374
+ ```bash
375
+ orc extra doctor # every finding, with the reason
376
+ orc extra conform cheap # measure the shim: streams, tool round trip, cache_control
377
+ orc extra privacy router --zdr on --data-collection deny # engine `api` only
378
+ ```
379
+
380
+ `extra_on_failure` decides what an unreachable endpoint, a 401, a timeout or a
381
+ malformed return does. `fallback` (the default) re-dispatches the task to the
382
+ Claude band it would have had, **announced**, and the run continues. `stop` is
383
+ for people who would rather stop than silently start paying Anthropic rates. A
384
+ failed foreign dispatch is never a dead run either way.
385
+
386
+ Two findings have **no fix** and say so rather than offering one that cannot
387
+ work: a missing install pepper (the stored key is unrecoverable) and managed
388
+ settings that pin a login method (engine `claude-shim` cannot coexist with a
389
+ third-party credential — switch that profile to `api`).
390
+
391
+ ### When it stops half-way
392
+
393
+ A worker that is cut off mid-write has already changed files on your disk. ORC
394
+ records what those files looked like **before** the dispatch started, so it can
395
+ tell you what changed rather than starting the task again on top of it.
396
+
397
+ ```bash
398
+ orc extra reconcile T-2 # free. What changed, and whose fault it was
399
+ orc extra resume-slice T-2 --out .orc/T-2.json # the continuation slice
400
+ orc extra dispatch --task .orc/T-2.json --json # the ordinary bridge
401
+ orc extra journal list # what was recorded, and what never came back
402
+ ```
403
+
404
+ `orc extra reconcile` is **free and deterministic** — no model, no tokens — and
405
+ it answers with one of five states: `resumable`, `nothing-to-resume`,
406
+ `no-journal`, `complete`, or `in-flight` (which is a refusal: two workers on one
407
+ file is worse than one lost worker).
408
+
409
+ It also says **whose fault it was**, and that decides what happens next:
410
+
411
+ | verdict | what you do |
412
+ |---|---|
413
+ | `provider` | send it to Claude instead — that works |
414
+ | `network` | **fix your connection.** A Claude fallback would fail too, so ORC holds the wave rather than paying for a second failure |
415
+ | `local` | something on this machine — a missing program, a disk error |
416
+ | `worker` | the model ran out of turns or gave up. The band or the turn cap is wrong |
417
+ | `orc` | an ORC bug, and ORC says so |
418
+
419
+ ORC tells `provider` and `network` apart by making **one cheap request with no
420
+ key attached**, with a three-second limit. Any answer at all — even a rejection —
421
+ proves the wire is up.
422
+
423
+ A resume **never widens the file list, never changes what "done" means, never
424
+ changes the score, and refuses if the plan changed** between attempts. A
425
+ non-retryable failure still goes to Claude — but as a *resume* slice, so the
426
+ replacement is told what is already on disk instead of landing on it blind.
427
+
428
+ **Nothing resumes on its own.** A dispatch that never reported back at all is
429
+ reported before your next wave and left alone until you decide.
430
+
431
+ | key | default | what it does |
432
+ |---|---|---|
433
+ | `extra_resume` | `on` | Continue a stopped dispatch instead of re-doing it. On by default, because off is the broken behaviour |
434
+ | `extra_resume_max` | `2` | Resume attempts per task before the fallback takes over, with an honest report rather than a silent third loop |
435
+
436
+ ---
437
+
438
+ ## The part worth reading twice
439
+
440
+ What leaves your machine is the task slice: your request, the contents of the
441
+ files that task names, the tool results the worker asks for, and the code it
442
+ writes back. Who receives it is the provider you configured, at the base URL on
443
+ its profile — nobody else is in the path and ORC adds no telemetry of its own.
444
+
445
+ What ORC **cannot** promise is how long that provider keeps your prompt, whether
446
+ it trains on it, or where in the world it runs. Those are their terms, not ORC's.
447
+ `orc extra providers --json` carries the link to each one, and reading it is your
448
+ call to make.
@@ -0,0 +1,152 @@
1
+ # Habits and gotchas
2
+
3
+ Two kinds of memory came in ORC 2.0.0. **Habits** remember how YOU answer ORC's
4
+ questions. **Gotchas** remember what THIS PROJECT already got wrong. Both are
5
+ computed by the CLI from files on your disk, with no model.
6
+
7
+ ---
8
+
9
+ ## Habits
10
+
11
+ ### Turn it on
12
+
13
+ ```bash
14
+ orc config set habits observe # count your answers, propose nothing
15
+ orc config set habits propose # also ask ONCE at the end of a run
16
+ orc config set habits off # the default: nothing is read, nothing changes
17
+ ```
18
+
19
+ `off` costs zero tokens. The lanes write no `ASK` line, and
20
+ `orc lane config --json` has no habits field.
21
+
22
+ ### How a habit is proposed
23
+
24
+ 1. Each answered question writes one `ASK` line into the run's trace. It
25
+ records the options, the answer and how it was given (`by=user`,
26
+ `ledger`, `learned`, `config` or `default`). Your own words are never
27
+ stored: a free answer is `chose=other`.
28
+ 2. `orc habit show` groups the answers per question and per context (for
29
+ example the branch kind).
30
+ 3. An answer becomes a **proposal** when all of these are true:
31
+ - at least 5 answers at full weight;
32
+ - a Wilson lower bound (95 %) of 0.55 or more;
33
+ - the last 3 answers are the same.
34
+ Recent answers count more. An answer the lane pre-selected counts a
35
+ quarter. A value from `config` or a lane default does not count at all.
36
+ 4. Under `propose`, ORC adds at most ONE proposal to the questions that the
37
+ lane asks at the end of a run: **yes · not now · never**.
38
+ 5. Nothing is applied without your yes. There is no automatic level.
39
+
40
+ ### The three classes
41
+
42
+ | Class | What a habit can do | Examples |
43
+ |---|---|---|
44
+ | `apply` | set a config key at the `learned` rank — **toward the careful side only** | `review_before_push: on`, `mini_tdd: on`, `quick_update_tests: on` |
45
+ | `suggest` | put your usual option first with `→ usual (<n> of <m>)`. The question is still asked | how to ship, the review offer in `/orc-quick`, analysis depth |
46
+ | `never` | nothing | an unknown question point |
47
+
48
+ A dispatch gate is asked every time. A habit to skip a review, to drop TDD or
49
+ to continue on a stale wiki is never applied. `deep` analysis needs your yes
50
+ every run.
51
+
52
+ ### Where a habit sits
53
+
54
+ An accepted habit is the `learned` rank: below your `.claude/orc.config.yaml`
55
+ and above the shipped default. `orc config set` always wins, and
56
+ `orc config list` shows `source: learned:H-…` for a key a habit set.
57
+
58
+ ### Stale habits
59
+
60
+ A habit is stale after 2 overrides in your last 3 answers, or after 90 days
61
+ without use. ORC then asks again at the end of a run. A declined habit can come
62
+ back only after 10 more answers AND 14 days. `never` stops it for good.
63
+
64
+ ### Commands
65
+
66
+ ```bash
67
+ orc habit show [--lane L] [--window 30d|90d|all] # your usual answers
68
+ orc habit log [--states] # the last answers, with by=
69
+ orc habit points # every question point and its options
70
+ orc habit why <H-id|qid> # the ASK lines behind a habit
71
+ orc habit accept <H-id> | decline <H-id> [--never]
72
+ orc habit forget <H-id> # undo: back to asking
73
+ orc habit reset <H-id> | doctor | export | purge --yes
74
+ orc habit repo [accept|decline|forget <id>] # soft preferences from git history
75
+ ```
76
+
77
+ `orc habit repo` reads your git history for commit, branch and test naming. A
78
+ preference is proposed only at a share of 0.8 or more over 20 samples or more.
79
+ An accepted one goes into the rules card as a LEARNED preference, below your
80
+ own `.claude/orc/rules.md`.
81
+
82
+ `orc ui` ▸ **Behaviour** shows the same data, with the buttons the CLI allows.
83
+ A `never` habit has no button — only the command.
84
+
85
+ ---
86
+
87
+ ## Gotchas
88
+
89
+ ### What an entry is
90
+
91
+ `.claude/orc/gotchas.md` holds entries like `G-017`: a trigger, a symptom, a
92
+ cause, a fix and a scope. A v1 file stays valid. 2.0.0 can add nine optional
93
+ fields (source, rule, category, cwe, severity, polarity, evidence, helpful,
94
+ harmful), and ORC 1.9.2 can still read the file.
95
+
96
+ ### Where observations come from
97
+
98
+ Every finding becomes an **observation** in `.claude/orc/observations.jsonl`
99
+ first. The sources:
100
+
101
+ | Source | Command | Notes |
102
+ |---|---|---|
103
+ | a red → green in a lane | (the lane records it) | with a reproduction, it promotes at once |
104
+ | an ORC review | (the lane records it at review close) | measured; the outcome of each finding is kept |
105
+ | SARIF 2.1.0 (ESLint, Semgrep, …) | `orc gotcha import sarif <file>` | suppressed results are skipped |
106
+ | Sonar | `orc gotcha import sonar [--pr N \| --branch B]` | `sonar_url`, `sonar_project`, `sonar_org`; the token comes from `SONAR_TOKEN` only |
107
+ | PR review threads | `orc gotcha import pr <n>` | people only; a bot is measured, never mined |
108
+ | closed defects | `orc gotcha import issues [--label bug]` | a defect with a closing PR |
109
+
110
+ `orc gotcha sync` runs every source that is available. It reads only what is
111
+ new, it has a time limit, and it runs again when the last sync is older than
112
+ `gotcha_sync_hours` (6). No importer writes to GitHub.
113
+
114
+ ### How an observation becomes an entry
115
+
116
+ A candidate is promoted on ONE of these:
117
+
118
+ - a red → green inside a lane, with a reproduction;
119
+ - a miss: an ORC review read the lines and did not flag them;
120
+ - a security finding with a CWE tag or a HIGH/BLOCKER impact (one case);
121
+ - 3 addressed cases in 2 PRs within 90 days.
122
+
123
+ `orc gotcha list --candidates` shows what is close, and what it still needs.
124
+ `orc gotcha accept <C-id>` promotes one by hand. Two disputes make a proposed
125
+ **suppression**: advice the reviewer should stop giving.
126
+
127
+ ### The reviewer card
128
+
129
+ `orc gotcha card --files <csv>` is what the reviewer gets: the entries that
130
+ match the files under review. Its size is `gotcha_card_budget` (600 tokens,
131
+ at least 200). It is always on. An entry that does not fit is counted in the
132
+ header, never dropped in silence.
133
+
134
+ `orc gotcha filter` removes suppressed, folded and noisy advice from a
135
+ review's findings. It never removes a P0 or a P1. `orc gotcha quality` shows
136
+ the acceptance per category after five reviews.
137
+
138
+ ---
139
+
140
+ ## How to undo
141
+
142
+ | You want to | Do this |
143
+ |---|---|
144
+ | stop all habit learning | `orc config set habits off` |
145
+ | drop one habit | `orc habit forget <H-id>` |
146
+ | never be asked about it again | `orc habit decline <H-id> --never` |
147
+ | delete what ORC computed from your traces | `orc habit purge --yes` (your traces stay) |
148
+ | undo what a run changed | `orc undo --run <slug>` prints the commands; add `--apply` to run them |
149
+
150
+ Your data files (`habits-state.json`, `habits-cache.json`,
151
+ `observations.jsonl`, `gotchas-sync.json`) are never in the install manifest.
152
+ `orc update`, `orc update --prune` and `orc doctor --fix` keep them.