@azure-id/orc 0.56.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/CHANGELOG.md +219 -0
  2. package/README-id.md +49 -107
  3. package/README.md +694 -719
  4. package/bin/build-agents.js +18 -11
  5. package/bin/cli.js +33699 -29855
  6. package/bin/onboarding-content.js +0 -3
  7. package/bin/test-run.js +491 -0
  8. package/bin/verify-contracts.js +4330 -3277
  9. package/bin/verify-package.js +76 -6
  10. package/bin/webui/api.js +1201 -1163
  11. package/bin/webui/app.html +210 -198
  12. package/bin/webui/css/06-responsive.css +120 -108
  13. package/bin/webui/css/panels/extra.css +29 -0
  14. package/bin/webui/css/panels/lanes.css +134 -0
  15. package/bin/webui/css/panels/settings.css +79 -3
  16. package/bin/webui/css/panels/wait.css +123 -0
  17. package/bin/webui/fixtures/extra.js +2036 -1934
  18. package/bin/webui/fixtures/flow.js +2 -2
  19. package/bin/webui/fixtures/index.js +510 -486
  20. package/bin/webui/fixtures/lanes.js +218 -0
  21. package/bin/webui/fixtures/settings.js +261 -34
  22. package/bin/webui/fixtures/stats.js +3 -3
  23. package/bin/webui/fixtures/wait.js +97 -0
  24. package/bin/webui/i18n/TERMS.md +135 -134
  25. package/bin/webui/i18n/en/extra.json +345 -313
  26. package/bin/webui/i18n/en/lanes.json +29 -0
  27. package/bin/webui/i18n/en/nav.json +21 -19
  28. package/bin/webui/i18n/en/overview.json +2 -0
  29. package/bin/webui/i18n/en/settings.json +16 -5
  30. package/bin/webui/i18n/en/wait.json +41 -0
  31. package/bin/webui/i18n/id/extra.json +345 -313
  32. package/bin/webui/i18n/id/lanes.json +29 -0
  33. package/bin/webui/i18n/id/nav.json +21 -19
  34. package/bin/webui/i18n/id/overview.json +2 -0
  35. package/bin/webui/i18n/id/settings.json +15 -4
  36. package/bin/webui/i18n/id/wait.json +41 -0
  37. package/bin/webui/js/01-i18n.js +151 -149
  38. package/bin/webui/js/panels/extra.js +3199 -3011
  39. package/bin/webui/js/panels/lanes.js +259 -0
  40. package/bin/webui/js/panels/overview.js +10 -0
  41. package/bin/webui/js/panels/settings.js +149 -3
  42. package/bin/webui/js/panels/wait.js +253 -0
  43. package/package.json +39 -39
  44. package/templates/agents/MODEL-MAPPING.md +23 -35
  45. package/templates/agents/orc-executor-opus-4-7-high.md +1 -1
  46. package/templates/agents/orc-executor-opus-4-7-med.md +1 -1
  47. package/templates/agents/orc-executor-opus-4-8-high.md +1 -1
  48. package/templates/agents/orc-executor-opus-5-high.md +1 -1
  49. package/templates/agents/orc-executor-opus-5-low.md +1 -1
  50. package/templates/agents/orc-executor-opus-5-med.md +1 -1
  51. package/templates/agents/orc-retro-opus-5-med.md +73 -73
  52. package/templates/agents/orc-retro-sonnet-5-high.md +72 -72
  53. package/templates/agents/orc-trace-writer-haiku-4-5.md +107 -107
  54. package/templates/commands/orc-route.md +1 -1
  55. package/templates/commands/orc-wait.md +19 -0
  56. package/templates/commands/orc.md +1 -1
  57. package/templates/hooks/orc-statusline.js +39 -0
  58. package/templates/skills/_shared/README.md +7 -3
  59. package/templates/skills/_shared/config-precedence.md +198 -0
  60. package/templates/skills/_shared/drift-recovery.md +1 -1
  61. package/templates/skills/_shared/extra-dispatch.md +159 -7
  62. package/templates/skills/_shared/interview.md +1 -1
  63. package/templates/skills/_shared/opus5-only.md +9 -7
  64. package/templates/skills/_shared/phases/README.md +82 -0
  65. package/templates/skills/{orc/references → _shared/phases}/analyst-gates.md +15 -3
  66. package/templates/skills/_shared/phases/execution.md +143 -0
  67. package/templates/skills/{orc/references → _shared/phases}/house-rules.md +13 -1
  68. package/templates/skills/{orc/references → _shared/phases}/intake.md +15 -2
  69. package/templates/skills/_shared/phases/mock-example.md +56 -0
  70. package/templates/skills/{orc/references → _shared/phases}/plan-handoff.md +16 -3
  71. package/templates/skills/_shared/phases/planning.md +135 -0
  72. package/templates/skills/_shared/phases/preflight.md +98 -0
  73. package/templates/skills/_shared/phases/review.md +53 -0
  74. package/templates/skills/_shared/phases/scoring.md +65 -0
  75. package/templates/skills/{orc/references → _shared/phases}/security-checklist.md +12 -1
  76. package/templates/skills/_shared/phases/security.md +55 -0
  77. package/templates/skills/_shared/phases/ship.md +88 -0
  78. package/templates/skills/{orc/references/stop-and-resume.md → _shared/phases/stop-resume.md} +169 -160
  79. package/templates/skills/_shared/phases/summary.md +48 -0
  80. package/templates/skills/_shared/phases/testgen.md +51 -0
  81. package/templates/skills/{orc/references/trace-protocol.md → _shared/phases/trace.md} +49 -6
  82. package/templates/skills/_shared/phases/verify.md +70 -0
  83. package/templates/skills/{orc/references → _shared/phases}/wave-grouping.md +14 -2
  84. package/templates/skills/{orc/references → _shared/phases}/wiki-consult.md +13 -1
  85. package/templates/skills/_shared/read-ladder.md +48 -0
  86. package/templates/skills/_shared/wait.md +240 -0
  87. package/templates/skills/context-combiner/SKILL.md +214 -187
  88. package/templates/skills/orc/README.md +148 -150
  89. package/templates/skills/orc/SKILL.md +75 -358
  90. package/templates/skills/orc/config.md +137 -389
  91. package/templates/skills/orc/examples/full-run-mock.md +1 -1
  92. package/templates/skills/orc/references/effort-and-mode.md +16 -18
  93. package/templates/skills/orc/references/phases/intake.md +47 -0
  94. package/templates/skills/orc/references/phases/integration.md +19 -0
  95. package/templates/skills/orc/references/preflight-report.md +4 -4
  96. package/templates/skills/orc/references/ultra-mode.md +117 -123
  97. package/templates/skills/orc/schemas/planning-output.md +279 -279
  98. package/templates/skills/orc/subskills/orc-planner/SKILL.md +260 -264
  99. package/templates/skills/orc/subskills/orc-pr/stack-gate.md +4 -1
  100. package/templates/skills/orc-aftermath/SKILL.md +158 -136
  101. package/templates/skills/orc-analyze/SKILL.md +252 -220
  102. package/templates/skills/orc-analyze/references/branching.md +51 -51
  103. package/templates/skills/orc-analyze/references/thin-input.md +1 -1
  104. package/templates/skills/orc-analyze-mini/SKILL.md +128 -112
  105. package/templates/skills/orc-boundary/SKILL.md +249 -208
  106. package/templates/skills/orc-brainstorm/SKILL.md +377 -339
  107. package/templates/skills/orc-budget/SKILL.md +248 -225
  108. package/templates/skills/orc-challenge/README.md +1 -1
  109. package/templates/skills/orc-challenge/SKILL.md +298 -255
  110. package/templates/skills/orc-challenge/examples/council-full-roster.md +1 -1
  111. package/templates/skills/orc-claude/SKILL.md +221 -199
  112. package/templates/skills/orc-diy/README.md +2 -1
  113. package/templates/skills/orc-diy/SKILL.md +132 -68
  114. package/templates/skills/orc-diy/references/blocks/analyze.md +1 -1
  115. package/templates/skills/orc-diy/references/compile.md +21 -7
  116. package/templates/skills/orc-diy/references/flow-schema.md +2 -2
  117. package/templates/skills/orc-doc/SKILL.md +49 -7
  118. package/templates/skills/orc-explain/SKILL.md +24 -0
  119. package/templates/skills/orc-export/SKILL.md +31 -5
  120. package/templates/skills/orc-fast/SKILL.md +218 -185
  121. package/templates/skills/orc-grill/SKILL.md +238 -207
  122. package/templates/skills/orc-handoff/SKILL.md +223 -204
  123. package/templates/skills/orc-learn/SKILL.md +181 -156
  124. package/templates/skills/orc-mini/SKILL.md +47 -24
  125. package/templates/skills/orc-pact/SKILL.md +255 -218
  126. package/templates/skills/orc-pattern/SKILL.md +154 -124
  127. package/templates/skills/orc-poly/SKILL.md +242 -216
  128. package/templates/skills/orc-poly/references/gather.md +1 -1
  129. package/templates/skills/orc-pr-driver/SKILL.md +196 -167
  130. package/templates/skills/orc-pr-driver/references/orc-run-split.md +1 -1
  131. package/templates/skills/orc-pr-setup/SKILL.md +212 -184
  132. package/templates/skills/orc-quick/README.md +2 -2
  133. package/templates/skills/orc-quick/SKILL.md +51 -13
  134. package/templates/skills/orc-quick/references/dispatch-gate.md +2 -3
  135. package/templates/skills/orc-retro/SKILL.md +249 -222
  136. package/templates/skills/orc-retro/examples/retro-mock.md +171 -171
  137. package/templates/skills/orc-route/SKILL.md +188 -165
  138. package/templates/skills/orc-verify/SKILL.md +103 -84
  139. package/templates/skills/orc-wait/SKILL.md +163 -0
  140. package/templates/skills/orc-wiki/SKILL.md +60 -206
  141. package/templates/skills/orc-wiki/references/phases/phase-0.md +71 -0
  142. package/templates/skills/orc-wiki/references/phases/phase-1.md +35 -0
  143. package/templates/skills/orc-wiki/references/phases/phase-2.md +52 -0
  144. package/templates/skills/orc-wiki/references/phases/phase-3.md +57 -0
  145. package/templates/skills/orc-wiki/references/phases/phase-3c.md +36 -0
  146. package/templates/agents/orc-advisor-fable-5.md +0 -50
  147. package/templates/agents/orc-analyst-fable-5.md +0 -115
  148. package/templates/agents/orc-judge-fable-5.md +0 -79
  149. package/templates/agents/orc-planner-fable-5.md +0 -152
  150. package/templates/agents/orc-reviewer-fable-5.md +0 -57
  151. package/templates/skills/_shared/fable5-override.md +0 -56
  152. package/templates/skills/orc-diy/references/blocks/execution.md +0 -42
  153. package/templates/skills/orc-diy/references/blocks/mock-example.md +0 -22
  154. package/templates/skills/orc-diy/references/blocks/planning.md +0 -34
  155. package/templates/skills/orc-diy/references/blocks/review.md +0 -18
  156. package/templates/skills/orc-diy/references/blocks/scoring.md +0 -16
  157. package/templates/skills/orc-diy/references/blocks/security.md +0 -25
  158. package/templates/skills/orc-diy/references/blocks/ship.md +0 -25
  159. package/templates/skills/orc-diy/references/blocks/summary.md +0 -18
  160. package/templates/skills/orc-diy/references/blocks/testgen.md +0 -17
  161. package/templates/skills/orc-diy/references/blocks/trace.md +0 -28
  162. package/templates/skills/orc-diy/references/blocks/verify.md +0 -25
@@ -1,225 +1,248 @@
1
- ---
2
- name: orc-budget
3
- description: >
4
- What a run will cost, in the unit YOU are billed in. Use for "/orc-budget",
5
- "what will this plan cost", "which lane is cheaper here", "how much did that run
6
- burn", "will this hit my limit". Given a PLAN — not a sentence — it forecasts a
7
- token vector (fresh input, cache write, cache read, output kept separate) per
8
- scoring band, then renders it four ways: tokens, dollars from a dated price
9
- table, percent of your 5-hour session window, and context-window risk per task.
10
- Every number is a range with a sample count, joined from Claude Code's own usage
11
- transcripts and ORC's traces. It never blocks a run and never invents a figure.
12
- ---
13
-
14
- # ORC-BUDGET
15
-
16
- The lane that **measures** — forwards.
17
-
18
- Account-level burn tracking is solved: `/usage`, cc-budget, eight commercial
19
- dashboards. What none of them can answer is the only question that changes a
20
- decision: **given THIS plan — 14 tasks, 4 waves, top score 78 — what will it burn,
21
- and what does each lane burn instead?**
22
-
23
- **The one-sentence contract: a forecast is a RANGE WITH A SAMPLE COUNT, never one
24
- number, and never a figure ORC did not measure.**
25
-
26
- ## Tokens are the unit of truth. Everything else is derived.
27
-
28
- The core object is a **token vector**, never a scalar. Four kinds, because they
29
- price and behave completely differently:
30
-
31
- | Kind | Typical share | Relative price | Why it must stay separate |
32
- |---|---|---|---|
33
- | `input` | small | 1× | fresh, uncached prompt |
34
- | `cache_write` | medium | ~1.25× | writing the cache — a real cost |
35
- | `cache_read` | **usually the largest** | ~0.1× | nearly free, and it dominates the raw count |
36
- | `output` | small | ~5× | the most expensive tokens in the run |
37
-
38
- A forecast of "407k tokens" hides that ~80% of it is cache reads costing a tenth
39
- of list. A forecast of "$7.02" hides that a Max user does not pay it. **So the CLI
40
- computes the vector once and renders it four ways.** Never a blended token count as
41
- the headline; `cache_read` is always separable.
42
-
43
- Plus one non-token line, because it bills separately and is in the data:
44
- `server_tool_use` → web search and web fetch requests.
45
-
46
- ## Four views of the same vector (`budget_units`, default `auto`)
47
-
48
- | View | Unit | Who it is for |
49
- |---|---|---|
50
- | **tokens** | in / cache-write / cache-read / out, per band | everyone — always shown |
51
- | **usd** | dollars from a dated table | API-billed, enterprise |
52
- | **quota** | % of the 5-hour window, % of the weekly limit | **Pro / Max — most users** |
53
- | **context** | peak prompt per dispatch vs its window | shown when a task is at risk |
54
-
55
- **A dollar figure is the wrong headline for most Claude Code users.** On Pro or Max
56
- you do not pay per token — you burn a 5-hour session window and a weekly ceiling.
57
- "$7.02" means nothing to that user; "18% of your 5-hour window" means everything.
58
- `budget_units: auto` picks from `budget_plan`; `--as tokens|usd|quota|context|all`
59
- overrides.
60
-
61
- ## Context pressure — a forecast output nobody else has
62
-
63
- A run does not only cost money. It can hit **compaction**, which silently degrades
64
- quality and is invisible in every spend tool. ORC can forecast it because ORC
65
- composes the slice, and the corpus records the **peak prompt** of every past
66
- dispatch. A task forecast above 90% of its model's window is reported before the
67
- wave, not after the damage — with three options: split the task, drop a doc nobody
68
- uses from the slice (`orc wiki usage`), or raise the band so a larger-window model
69
- takes it.
70
-
71
- ## Where the numbers come from — and the join is the moat
72
-
73
- ```
74
- transcript → isSidechain block, model, effort, 4 token counts, peak, timestamp
75
- ORC trace → DISPATCH line: task, score, band, expect=<model>/<effort>,
76
- the wiki: continuation, RETURN with actual_model
77
- join key → the run's time window + sidechain grouping + model match
78
- ```
79
-
80
- Claude Code writes a JSONL transcript per session under
81
- `~/.claude/projects/<slug>/`. That gives the **cost**. ORC's own traces give the
82
- **meaning** — which task, which band, which model was expected, whether it was
83
- requeued. **Neither is enough alone, and nobody else has the right-hand column.**
84
- Details and honesty rules: `references/corpus.md`.
85
-
86
- ## Honesty rules — all six, always
87
-
88
- 1. **No transcripts?** Forecast in **tokens only** from ORC trace metadata and
89
- print *"dollars and quota unavailable: no local usage data"*. Never invent a
90
- price.
91
- 2. **`unattributed` is ALWAYS printed**, including when zero. A sidechain block that
92
- could not be joined to a task counts into it and is never silently dropped.
93
- 3. **Cache reads get their own p50/p90**, not a share of a blended number. They are
94
- the most variable component.
95
- 4. **No dollar figure without a dated price table** (`budget_price_table`; default
96
- the shipped one). Older than 90 days → a staleness warning beside every figure.
97
- **No quota figure without a known plan** — `budget_plan` is asked ONCE and
98
- stored, because a wrong guess rendered as a percentage is worse than no
99
- percentage.
100
- 5. **A band below `budget_min_samples` (default 5) is printed as low-confidence.**
101
- The top of the range is soft and the output says so.
102
-
103
- 6. **A foreign dispatch is priced from its OWN dated table, or not at all**
104
- (v0.50.0). A task can execute on a non-Claude worker
105
- (`_shared/extra-dispatch.md`); its four token kinds arrive the same way and
106
- are never blended, but an Anthropic rate applied to somebody else's bill is
107
- fiction — so `bin/pricing.json`'s `providers` block is the only source, and
108
- **every `models` map in it ships EMPTY on purpose**. Several of these vendors
109
- price by peak window or by tier, one sells a subscription rather than tokens,
110
- and one is a passthrough with a surcharge; a shipped figure wrong by 2x is
111
- worse than none, because a wrong figure gets believed. `orc extra rates`
112
- lists the pairs your traces actually used and prints the JSON to paste.
113
- Until then: **`usd` reads as an em dash, never zero and never an estimate.**
114
-
115
- Two further foreign-only distinctions, and collapsing either is a wrong
116
- number rather than a rounder one:
117
-
118
- - **`usage: null` is not `{0,0,0,0}`.** Engine `cli` frequently reports no
119
- token counts. Null means *unknown*; four zeros would mean *free*. Carry the
120
- denominator (how many dispatches the vector came from) into every total.
121
- - **`cache_write: 0` on engine `api` IS a measurement.** An
122
- OpenAI-compatible endpoint caches implicitly and has no write charge to
123
- report. That zero is true and must not be smoothed into an average.
124
-
125
- `orc extra stats --json` computes all of this per profile per band. Render
126
- it; do not recompute it.
127
-
128
- ## It refuses a sentence
129
-
130
- `orc budget forecast` takes a **plan file**. Forecasting from a request in words is
131
- guessing, and a guess that looks computed is worse than no answer — the same reason
132
- `/orc-route` is plan-only. No `- id:` task blocks → exit 3 with the reason and a
133
- pointer to `/orc-plan`.
134
-
135
- **With no history at all:**
136
-
137
- ```
138
- BUDGET · no forecast
139
- 0 joinable dispatches in .claude/orc/logs/ and no usable transcripts.
140
- I will not invent numbers. Run /orc or /orc-mini once, then ask again.
141
- A floor from the public price table only: orc budget forecast --naive
142
- ```
143
-
144
- ---
145
-
146
- ## Phases
147
-
148
- ```
149
- U0 preflight (silent) orc budget rates --json (lazily calibrates on a miss)
150
- U1 input a plan file · a run slug · "just the rates"
151
- U2 forecast / actual the CLI computes; this lane RENDERS and explains
152
- U3 decide ONE question: which lane · split a task · proceed
153
- U4 record one end-of-run trace packet
154
- ```
155
-
156
- **U2 does no arithmetic.** `orc budget forecast|actual|rates` are the only engine —
157
- this skill never re-derives a band, a price, a percentile or a total. Same rule as
158
- the wiki tier and the DIY stepper: a second idea of the number is drift no lint
159
- could see.
160
-
161
- **U0 opens the run properly.** Write `log_dir/.current` =
162
- `run-budget-<slug>-<DDMMYY>-<HHMMSS>.txt` AND `touch the trace file` of that name
163
- in the SAME step. Both, or neither. A lane the protocol declares must be a lane
164
- something OPENS, or every counting tool reports it as a permanent zero.
165
-
166
- **U1 asks `budget_plan` ONCE** if it is `auto`, as a single line, and stores it:
167
-
168
- ```
169
- Which plan are you on? It changes the primary unit, and I will not guess.
170
- 1 Max 20x 2 Max 5x 3 Pro 4 API (billed per token) 5 Skip — tokens only
171
- ```
172
-
173
- **U3 is a real question, not a summary.** The forecast exists to change a decision:
174
-
175
- ```
176
- 1 Proceed on /orc 1.23M raw · 564k weighted · 18% of a window
177
- 2 Run /orc-mini instead 0.41M raw · 188k weighted · 6% (no review/verify phase)
178
- 3 Split T12 it forecasts 189k of a 200k window — likely to compact
179
- 4 Your own — re-plan smaller, or just show me the numbers again
180
- ```
181
-
182
- ## Where this shows up in `/orc`
183
-
184
- - **Phase 2 intake** — the forecast at the batch-pause confirmation, so the pause
185
- schedule doubles as a budget checkpoint.
186
- - **Every pause** — spend so far vs forecast to here, in the primary unit.
187
- - **`/orc-route`** — a cost column per lane, so routing stops being qualitative.
188
- - **Ship** — actual vs forecast, fed to `/orc-retro`.
189
- - **Context risk** — a task above 90% of its window is reported to the planner
190
- BEFORE the wave.
191
-
192
- **It never blocks a run.** Advisory always. The one hard stop in this area is the
193
- existing `run_budget_dispatches` gate, which counts dispatches, not tokens, and is
194
- not part of this lane.
195
-
196
- ## Behavior trace (always on)
197
-
198
- Follow `../orc/references/trace-protocol.md`. Lane name `budget`.
199
- **Single-dispatch lane: exactly ONE end-of-run packet** to
200
- `orc-trace-writer-haiku-4-5` after U4 and BEFORE `.current` is deleted. It carries
201
- `run_meta`, the events (probe, forecast, the units rendered) and the U3 answer as
202
- `decisions`. A run that ends with
203
- `zero new trace lines is a protocol violation`.
204
-
205
- Zero new agents. There is nothing to dispatch: the whole forecast is deterministic.
206
-
207
- ## How this lane fails — and the rule that prevents each
208
-
209
- | Failure | Prevention |
210
- |---|---|
211
- | One confident number | A range with a sample count, always |
212
- | A blended token total as the headline | Four kinds, always separable |
213
- | A dollar figure for a Max user | `budget_units: auto` off `budget_plan` |
214
- | A price from an undated table | Dated table, 90-day staleness warning |
215
- | A quota percent from a guessed plan | Asked once, stored, never inferred |
216
- | Tokens silently dropped from the total | `unattributed` always printed |
217
- | A forecast from a sentence | Plan-only, exit 3 with the reason |
218
- | It blocks a run | Advisory always |
219
- | The skill recomputes a band | The CLI is the only engine |
220
-
221
- ## Rules this lane always keeps
222
-
223
- Never one number · never a blended headline · never an invented price · never a
224
- guessed plan · never drop `unattributed` · never forecast from prose · never block ·
225
- never compute what the CLI computes.
1
+ ---
2
+ name: orc-budget
3
+ description: >
4
+ What a run will cost, in the unit YOU are billed in. Use for "/orc-budget",
5
+ "what will this plan cost", "which lane is cheaper here", "how much did that run
6
+ burn", "will this hit my limit". Given a PLAN — not a sentence — it forecasts a
7
+ token vector (fresh input, cache write, cache read, output kept separate) per
8
+ scoring band, then renders it four ways: tokens, dollars from a dated price
9
+ table, percent of your 5-hour session window, and context-window risk per task.
10
+ Every number is a range with a sample count, joined from Claude Code's own usage
11
+ transcripts and ORC's traces. It never blocks a run and never invents a figure.
12
+ ---
13
+
14
+ # ORC-BUDGET
15
+
16
+ The lane that **measures** — forwards.
17
+
18
+ Account-level burn tracking is solved: `/usage`, cc-budget, eight commercial
19
+ dashboards. What none of them can answer is the only question that changes a
20
+ decision: **given THIS plan — 14 tasks, 4 waves, top score 78 — what will it burn,
21
+ and what does each lane burn instead?**
22
+
23
+ **The one-sentence contract: a forecast is a RANGE WITH A SAMPLE COUNT, never one
24
+ number, and never a figure ORC did not measure.**
25
+
26
+ ## Tokens are the unit of truth. Everything else is derived.
27
+
28
+ The core object is a **token vector**, never a scalar. Four kinds, because they
29
+ price and behave completely differently:
30
+
31
+ | Kind | Typical share | Relative price | Why it must stay separate |
32
+ |---|---|---|---|
33
+ | `input` | small | 1× | fresh, uncached prompt |
34
+ | `cache_write` | medium | ~1.25× | writing the cache — a real cost |
35
+ | `cache_read` | **usually the largest** | ~0.1× | nearly free, and it dominates the raw count |
36
+ | `output` | small | ~5× | the most expensive tokens in the run |
37
+
38
+ A forecast of "407k tokens" hides that ~80% of it is cache reads costing a tenth
39
+ of list. A forecast of "$7.02" hides that a Max user does not pay it. **So the CLI
40
+ computes the vector once and renders it four ways.** Never a blended token count as
41
+ the headline; `cache_read` is always separable.
42
+
43
+ Plus one non-token line, because it bills separately and is in the data:
44
+ `server_tool_use` → web search and web fetch requests.
45
+
46
+ ## Four views of the same vector (`budget_units`, default `auto`)
47
+
48
+ | View | Unit | Who it is for |
49
+ |---|---|---|
50
+ | **tokens** | in / cache-write / cache-read / out, per band | everyone — always shown |
51
+ | **usd** | dollars from a dated table | API-billed, enterprise |
52
+ | **quota** | % of the 5-hour window, % of the weekly limit | **Pro / Max — most users** |
53
+ | **context** | peak prompt per dispatch vs its window | shown when a task is at risk |
54
+
55
+ **A dollar figure is the wrong headline for most Claude Code users.** On Pro or Max
56
+ you do not pay per token — you burn a 5-hour session window and a weekly ceiling.
57
+ "$7.02" means nothing to that user; "18% of your 5-hour window" means everything.
58
+ `budget_units: auto` picks from `budget_plan`; `--as tokens|usd|quota|context|all`
59
+ overrides.
60
+
61
+ ## Context pressure — a forecast output nobody else has
62
+
63
+ A run does not only cost money. It can hit **compaction**, which silently degrades
64
+ quality and is invisible in every spend tool. ORC can forecast it because ORC
65
+ composes the slice, and the corpus records the **peak prompt** of every past
66
+ dispatch. A task forecast above 90% of its model's window is reported before the
67
+ wave, not after the damage — with three options: split the task, drop a doc nobody
68
+ uses from the slice (`orc wiki usage`), or raise the band so a larger-window model
69
+ takes it.
70
+
71
+ ## Where the numbers come from — and the join is the moat
72
+
73
+ ```
74
+ transcript → isSidechain block, model, effort, 4 token counts, peak, timestamp
75
+ ORC trace → DISPATCH line: task, score, band, expect=<model>/<effort>,
76
+ the wiki: continuation, RETURN with actual_model
77
+ join key → the run's time window + sidechain grouping + model match
78
+ ```
79
+
80
+ Claude Code writes a JSONL transcript per session under
81
+ `~/.claude/projects/<slug>/`. That gives the **cost**. ORC's own traces give the
82
+ **meaning** — which task, which band, which model was expected, whether it was
83
+ requeued. **Neither is enough alone, and nobody else has the right-hand column.**
84
+ Details and honesty rules: `references/corpus.md`.
85
+
86
+ ## Honesty rules — all six, always
87
+
88
+ 1. **No transcripts?** Forecast in **tokens only** from ORC trace metadata and
89
+ print *"dollars and quota unavailable: no local usage data"*. Never invent a
90
+ price.
91
+ 2. **`unattributed` is ALWAYS printed**, including when zero. A sidechain block that
92
+ could not be joined to a task counts into it and is never silently dropped.
93
+ 3. **Cache reads get their own p50/p90**, not a share of a blended number. They are
94
+ the most variable component.
95
+ 4. **No dollar figure without a dated price table** (`budget_price_table`; default
96
+ the shipped one). Older than 90 days → a staleness warning beside every figure.
97
+ **No quota figure without a known plan** — `budget_plan` is asked ONCE and
98
+ stored, because a wrong guess rendered as a percentage is worse than no
99
+ percentage.
100
+ 5. **A band below `budget_min_samples` (default 5) is printed as low-confidence.**
101
+ The top of the range is soft and the output says so.
102
+
103
+ 6. **A foreign dispatch is priced from its OWN dated table, or not at all**
104
+ (v0.50.0). A task can execute on a non-Claude worker
105
+ (`_shared/extra-dispatch.md`); its four token kinds arrive the same way and
106
+ are never blended, but an Anthropic rate applied to somebody else's bill is
107
+ fiction — so `bin/pricing.json`'s `providers` block is the only source, and
108
+ **every `models` map in it ships EMPTY on purpose**. Several of these vendors
109
+ price by peak window or by tier, one sells a subscription rather than tokens,
110
+ and one is a passthrough with a surcharge; a shipped figure wrong by 2x is
111
+ worse than none, because a wrong figure gets believed. `orc extra rates`
112
+ lists the pairs your traces actually used and prints the JSON to paste.
113
+ Until then: **`usd` reads as an em dash, never zero and never an estimate.**
114
+
115
+ Two further foreign-only distinctions, and collapsing either is a wrong
116
+ number rather than a rounder one:
117
+
118
+ - **`usage: null` is not `{0,0,0,0}`.** Engine `cli` frequently reports no
119
+ token counts. Null means *unknown*; four zeros would mean *free*. Carry the
120
+ denominator (how many dispatches the vector came from) into every total.
121
+ - **`cache_write: 0` on engine `api` IS a measurement.** An
122
+ OpenAI-compatible endpoint caches implicitly and has no write charge to
123
+ report. That zero is true and must not be smoothed into an average.
124
+
125
+ `orc extra stats --json` computes all of this per profile per band. Render
126
+ it; do not recompute it.
127
+
128
+ ## It refuses a sentence
129
+
130
+ `orc budget forecast` takes a **plan file**. Forecasting from a request in words is
131
+ guessing, and a guess that looks computed is worse than no answer — the same reason
132
+ `/orc-route` is plan-only. No `- id:` task blocks → exit 3 with the reason and a
133
+ pointer to `/orc-plan`.
134
+
135
+ **With no history at all:**
136
+
137
+ ```
138
+ BUDGET · no forecast
139
+ 0 joinable dispatches in .claude/orc/logs/ and no usable transcripts.
140
+ I will not invent numbers. Run /orc or /orc-mini once, then ask again.
141
+ A floor from the public price table only: orc budget forecast --naive
142
+ ```
143
+
144
+ ---
145
+
146
+ ## Phases
147
+
148
+ ```
149
+ U0 preflight (silent) orc budget rates --json (lazily calibrates on a miss)
150
+ U1 input a plan file · a run slug · "just the rates"
151
+ U2 forecast / actual the CLI computes; this lane RENDERS and explains
152
+ U3 decide ONE question: which lane · split a task · proceed
153
+ U4 record one end-of-run trace packet
154
+ ```
155
+
156
+ **U2 does no arithmetic.** `orc budget forecast|actual|rates` are the only engine —
157
+ this skill never re-derives a band, a price, a percentile or a total. Same rule as
158
+ the wiki tier and the DIY stepper: a second idea of the number is drift no lint
159
+ could see.
160
+
161
+ **U0 opens the run properly.** Write `log_dir/.current` =
162
+ `run-budget-<slug>-<DDMMYY>-<HHMMSS>.txt` AND `touch the trace file` of that name
163
+ in the SAME step. Both, or neither. A lane the protocol declares must be a lane
164
+ something OPENS, or every counting tool reports it as a permanent zero.
165
+
166
+ **U1 asks `budget_plan` ONCE** if it is `auto`, as a single line, and stores it:
167
+
168
+ ```
169
+ Which plan are you on? It changes the primary unit, and I will not guess.
170
+ 1 Max 20x 2 Max 5x 3 Pro 4 API (billed per token) 5 Skip — tokens only
171
+ ```
172
+
173
+ **U3 is a real question, not a summary.** The forecast exists to change a decision:
174
+
175
+ ```
176
+ 1 Proceed on /orc 1.23M raw · 564k weighted · 18% of a window
177
+ 2 Run /orc-mini instead 0.41M raw · 188k weighted · 6% (no review/verify phase)
178
+ 3 Split T12 it forecasts 189k of a 200k window — likely to compact
179
+ 4 Your own — re-plan smaller, or just show me the numbers again
180
+ ```
181
+
182
+ ## Where this shows up in `/orc`
183
+
184
+ - **Phase 2 intake** — the forecast at the batch-pause confirmation, so the pause
185
+ schedule doubles as a budget checkpoint.
186
+ - **Every pause** — spend so far vs forecast to here, in the primary unit.
187
+ - **`/orc-route`** — a cost column per lane, so routing stops being qualitative.
188
+ - **Ship** — actual vs forecast, fed to `/orc-retro`.
189
+ - **Context risk** — a task above 90% of its window is reported to the planner
190
+ BEFORE the wave.
191
+
192
+ **It never blocks a run.** Advisory always. The one hard stop in this area is the
193
+ existing `run_budget_dispatches` gate, which counts dispatches, not tokens, and is
194
+ not part of this lane.
195
+
196
+ ## Behavior trace (always on)
197
+
198
+ `../_shared/phases/trace.md` (`core`, at run start; `orc lane phases` names
199
+ the file and the layers). Lane token `budget`, tier **Single-dispatch**
200
+ exactly ONE end-of-run packet, dispatched solo before `.current` is deleted.
201
+ At run start write `log_dir/.current` = `run-budget-<slug>-<DDMMYY>-<HHMMSS>.txt` AND
202
+ `touch the trace file` of that name in the SAME step.
203
+ Nothing else about the protocol is restated here; a phase that ends with
204
+ `zero new trace lines is a protocol violation`.
205
+
206
+ ## How this lane fails — and the rule that prevents each
207
+
208
+ | Failure | Prevention |
209
+ |---|---|
210
+ | One confident number | A range with a sample count, always |
211
+ | A blended token total as the headline | Four kinds, always separable |
212
+ | A dollar figure for a Max user | `budget_units: auto` off `budget_plan` |
213
+ | A price from an undated table | Dated table, 90-day staleness warning |
214
+ | A quota percent from a guessed plan | Asked once, stored, never inferred |
215
+ | Tokens silently dropped from the total | `unattributed` always printed |
216
+ | A forecast from a sentence | Plan-only, exit 3 with the reason |
217
+ | It blocks a run | Advisory always |
218
+ | The skill recomputes a band | The CLI is the only engine |
219
+
220
+ ## Rules this lane always keeps
221
+
222
+ Never one number · never a blended headline · never an invented price · never a
223
+ guessed plan · never drop `unattributed` · never forecast from prose · never block ·
224
+ never compute what the CLI computes.
225
+
226
+ ## Config
227
+
228
+ Resolve with `orc lane config orc-budget --json` and obey `effective`. Never merge
229
+ `.claude/orc.config.yaml` yourself, and never re-derive a precedence. Exit ≠ 0 →
230
+ say so and use `../_shared/config-precedence.md`'s documented defaults, out
231
+ loud. Nothing this lane reads is contested, gated or a stop, so it owes no
232
+ preflight line and has no gate to honour.
233
+
234
+ ## Calls
235
+
236
+ **ONE catalogue, and it is not you:** `orc lane calls orc-budget --json` names every
237
+ CLI call this lane makes, each with its exit-code contract, its cost, when to run
238
+ it, and what an EMPTY answer means. Never invent a spelling, never re-word an
239
+ exit code, and never re-derive a state word — the CLI's state words are the only
240
+ state words, and **an exit code is an ANSWER wherever that contract says so, not
241
+ a failure**. A call the answer does not name is a call this lane does not make.
242
+ Exit ≠ 0 from the catalogue itself → say the CLI is unavailable and name the
243
+ command you are about to run, out loud, before running it.
244
+
245
+ ## Waiting mid-run (`/orc-wait`)
246
+
247
+ Canonical: `../_shared/wait.md`. **`a lane that waits without a hand-back` has broken this contract.**
248
+ Checkpoint **none** · safe point **read-only, seconds long**. Nothing here to checkpoint, so all three modes behave identically — say so rather than asking. Never begin a wait between a dispatch and its validated return, or before the smoke gate has reported.
@@ -135,7 +135,7 @@ one.
135
135
 
136
136
  ## Reading order for a new maintainer
137
137
 
138
- `references/intake.md` (it defines what every later file grades against) →
138
+ `../_shared/phases/intake.md` (it defines what every later file grades against) →
139
139
  `council.md` → `sealed-slice.md` → `rubric.md` → `conservation.md` →
140
140
  `cycle-state.md` → `fix-brief.md`. Then `examples/tsd-two-iterations.md` for the
141
141
  whole thing end to end, and `examples/council-full-roster.md` for a run where