@azure-id/orc 1.2.0 → 1.2.1

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.
@@ -1,568 +1,573 @@
1
- #!/usr/bin/env node
2
- "use strict";
3
- /**
4
- * Package integrity check. Fails LOUDLY if any critical file is missing —
5
- * so an incomplete push (e.g. corrupted by OneDrive sync) errors immediately
6
- * instead of installing a dangling `orc` command.
7
- * Runs on prepack (before publish/pack) and can be run manually: node bin/verify-package.js
8
- */
9
- const fs = require("fs");
10
- const path = require("path");
11
-
12
- const ROOT = path.join(__dirname, "..");
13
- const required = [
14
- "bin/cli.js",
15
- "package.json",
16
- "README.md",
17
- // The `orc ui` web panel (v0.43.0). Named file by file, not covered by a
18
- // count: the panel is a set of files that only work together, and a publish
19
- // missing any one of them serves a page that 500s or renders blank. NOTE the
20
- // folder — `bin/ui.js` is the TERMINAL styling kit and is a different thing.
21
- "bin/webui/serve.js",
22
- "bin/webui/api.js",
23
- "bin/webui/app.html",
24
- // The stylesheet layers (v0.48.1). The <link> order in app.html is the
25
- // cascade order; 06-responsive and 04-motion are last on purpose.
26
- "bin/webui/css/00-tokens.css",
27
- "bin/webui/css/01-base.css",
28
- "bin/webui/css/02-shell.css",
29
- "bin/webui/css/03-components.css",
30
- "bin/webui/css/04-motion.css",
31
- "bin/webui/css/05-tour.css",
32
- "bin/webui/css/06-responsive.css",
33
- "bin/webui/css/panels/overview.css",
34
- "bin/webui/css/panels/settings.css",
35
- "bin/webui/css/panels/lanes.css",
36
- "bin/webui/css/panels/runs.css",
37
- "bin/webui/css/panels/knowledge.css",
38
- // No knowledge.css: that panel is composed entirely from shared primitives
39
- // (.card, .chip, .tbl, .bar-track). An empty stylesheet would be one more
40
- // request and one more thing to keep in the manifest for no rules at all.
41
- "bin/webui/css/panels/stats.css",
42
- "bin/webui/css/panels/flow.css",
43
- "bin/webui/css/panels/crosslink.css",
44
- "bin/webui/css/panels/learn.css",
45
- "bin/webui/css/panels/mockrun.css",
46
- "bin/webui/css/panels/maintenance.css",
47
- "bin/webui/css/panels/pact.css",
48
- "bin/webui/css/panels/boundary.css",
49
- "bin/webui/css/panels/wait.css",
50
- "bin/webui/css/panels/handoff.css",
51
- "bin/webui/css/panels/challenge.css",
52
- "bin/webui/css/panels/docs.css",
53
- "bin/webui/css/panels/extra.css",
54
- "bin/webui/css/panels/experiment.css",
55
- // The client modules (v0.48.1). The <script> order in app.html is the load
56
- // order and the numeric prefix is that order; 99-boot.js must be last.
57
- "bin/webui/js/00-core.js",
58
- "bin/webui/js/01-i18n.js",
59
- "bin/webui/js/02-ui.js",
60
- "bin/webui/js/03-md.js",
61
- "bin/webui/js/04-router.js",
62
- "bin/webui/js/05-banners.js",
63
- "bin/webui/js/06-edit.js",
64
- "bin/webui/js/panels/overview.js",
65
- "bin/webui/js/panels/settings.js",
66
- "bin/webui/js/panels/lanes.js",
67
- "bin/webui/js/panels/runs.js",
68
- "bin/webui/js/panels/knowledge.js",
69
- "bin/webui/js/panels/stats.js",
70
- "bin/webui/js/panels/flow.js",
71
- "bin/webui/js/panels/crosslink.js",
72
- "bin/webui/js/panels/learn.js",
73
- "bin/webui/js/panels/mockrun.js",
74
- "bin/webui/js/panels/experiment.js",
75
- "bin/webui/js/panels/maintenance.js",
76
- "bin/webui/js/panels/pact.js",
77
- "bin/webui/js/panels/boundary.js",
78
- "bin/webui/js/panels/wait.js",
79
- "bin/webui/js/panels/handoff.js",
80
- "bin/webui/js/panels/challenge.js",
81
- "bin/webui/js/panels/docs.js",
82
- "bin/webui/js/panels/extra.js",
83
- "bin/webui/js/90-tour.js",
84
- "bin/webui/js/91-shortcuts.js",
85
- "bin/webui/js/99-boot.js",
86
- // The canned data (v0.48.1), one file per panel. index.js is the ROUTER;
87
- // every other file is data. --fixtures must carry ONE OF EVERY STATE.
88
- "bin/webui/fixtures/index.js",
89
- "bin/webui/fixtures/shell.js",
90
- "bin/webui/fixtures/settings.js",
91
- "bin/webui/fixtures/lanes.js",
92
- "bin/webui/fixtures/knowledge.js",
93
- "bin/webui/fixtures/runs.js",
94
- "bin/webui/fixtures/stats.js",
95
- "bin/webui/fixtures/pact.js",
96
- "bin/webui/fixtures/boundary.js",
97
- "bin/webui/fixtures/wait.js",
98
- "bin/webui/fixtures/handoff.js",
99
- "bin/webui/fixtures/maintenance.js",
100
- "bin/webui/fixtures/challenge.js",
101
- "bin/webui/fixtures/docs.js",
102
- "bin/webui/fixtures/flow.js",
103
- "bin/webui/fixtures/crosslink.js",
104
- "bin/webui/fixtures/mockrun.js",
105
- "bin/webui/fixtures/extra.js",
106
- // The string tables (v0.43.6). Named here for the same reason: English is the
107
- // FALLBACK table every other language falls back to, so a publish that drops
108
- // it renders raw dotted keys on every panel, in every language.
109
- // v0.52.0 - the TERM LIST. It is not a string table and is never fetched by
110
- // the page; it is the one page that keeps the next two hundred strings
111
- // consistent, and without it a wording pass drifts back within two releases.
112
- "bin/webui/i18n/TERMS.md",
113
- "bin/webui/i18n/en/common.json",
114
- "bin/webui/i18n/en/nav.json",
115
- "bin/webui/i18n/en/banner.json",
116
- "bin/webui/i18n/en/overview.json",
117
- "bin/webui/i18n/en/settings.json",
118
- "bin/webui/i18n/en/lanes.json",
119
- "bin/webui/i18n/en/runs.json",
120
- "bin/webui/i18n/en/knowledge.json",
121
- "bin/webui/i18n/en/stats.json",
122
- "bin/webui/i18n/en/flow.json",
123
- "bin/webui/i18n/en/crosslink.json",
124
- "bin/webui/i18n/en/learn.json",
125
- "bin/webui/i18n/en/mockrun.json",
126
- "bin/webui/i18n/en/maintenance.json",
127
- "bin/webui/i18n/en/pact.json",
128
- "bin/webui/i18n/en/boundary.json",
129
- "bin/webui/i18n/en/wait.json",
130
- "bin/webui/i18n/en/handoff.json",
131
- "bin/webui/i18n/en/challenge.json",
132
- "bin/webui/i18n/en/docs.json",
133
- "bin/webui/i18n/en/extra.json",
134
- "bin/webui/i18n/en/experiment.json",
135
- "bin/webui/i18n/en/tour.json",
136
- "bin/webui/i18n/id/common.json",
137
- "bin/webui/i18n/id/nav.json",
138
- "bin/webui/i18n/id/banner.json",
139
- "bin/webui/i18n/id/overview.json",
140
- "bin/webui/i18n/id/settings.json",
141
- "bin/webui/i18n/id/lanes.json",
142
- "bin/webui/i18n/id/runs.json",
143
- "bin/webui/i18n/id/knowledge.json",
144
- "bin/webui/i18n/id/stats.json",
145
- "bin/webui/i18n/id/flow.json",
146
- "bin/webui/i18n/id/crosslink.json",
147
- "bin/webui/i18n/id/learn.json",
148
- "bin/webui/i18n/id/mockrun.json",
149
- "bin/webui/i18n/id/maintenance.json",
150
- "bin/webui/i18n/id/pact.json",
151
- "bin/webui/i18n/id/boundary.json",
152
- "bin/webui/i18n/id/wait.json",
153
- "bin/webui/i18n/id/handoff.json",
154
- "bin/webui/i18n/id/challenge.json",
155
- "bin/webui/i18n/id/docs.json",
156
- "bin/webui/i18n/id/extra.json",
157
- "bin/webui/i18n/id/experiment.json",
158
- "bin/webui/i18n/id/tour.json",
159
- // The mocked runs (v0.46.x): the catalogue module plus the folder it reads.
160
- // Both `orc mock-run` and the panel's Mocked Skill Use page are empty without
161
- // them, and an empty catalogue looks like a broken feature rather than a
162
- // publish that dropped a folder.
163
- "bin/mockrun-catalog.js",
164
- // The two DATED data files (v0.50.0). Both ship inside the package and both
165
- // are load-bearing on absence rather than on content: without the catalog
166
- // `orc extra providers` is a packaging bug it reports as one, and without the
167
- // price table every `usd` reads as an em dash forever. They are named here for
168
- // the same reason every webui file is — a publish that drops one serves a
169
- // feature that looks broken rather than missing.
170
- "bin/providers.json",
171
- "bin/pricing.json",
172
- "mock-run",
173
- "mock-run/INDEX.md",
174
- "templates",
175
- "templates/skills/orc/SKILL.md",
176
- "templates/skills/orc/references/ultra-mode.md",
177
- "templates/skills/orc-advisor/SKILL.md",
178
- "templates/skills/orc-judge/SKILL.md",
179
- "templates/skills/orc-fast/SKILL.md",
180
- "templates/skills/orc-claude/SKILL.md",
181
- "templates/skills/orc-claude/references/template.md",
182
- "templates/skills/orc-claude/references/refresh.md",
183
- "templates/skills/orc-wiki/references/staleness.md",
184
- "templates/skills/orc-learn/SKILL.md",
185
- "templates/skills/orc-learn/references/refresh.md",
186
- "templates/skills/orc-poly/SKILL.md",
187
- "templates/skills/orc-poly/references/poly-spec.md",
188
- "templates/skills/orc-poly/references/gather.md",
189
- // Stacked pull requests (v0.37.0) — two standalone lanes plus the three
190
- // canonical shared contracts they and ORC's ship gate all read. A missing
191
- // shared file makes the ship gate hand off to a lane that cannot preflight.
192
- "templates/skills/orc-pr-setup/SKILL.md",
193
- "templates/skills/orc-pr-setup/README.md",
194
- "templates/skills/orc-pr-setup/references/layer-taxonomy.md",
195
- "templates/skills/orc-pr-setup/references/certainty-gate.md",
196
- "templates/skills/orc-pr-driver/SKILL.md",
197
- "templates/skills/orc-pr-driver/README.md",
198
- "templates/skills/orc-pr-driver/references/green-gate.md",
199
- "templates/skills/orc-pr-driver/references/orc-run-split.md",
200
- "templates/skills/orc-pr-driver/references/conflict-playbook.md",
201
- "templates/skills/_shared/stack-plan.md",
202
- "templates/skills/_shared/gh-stack-commands.md",
203
- "templates/skills/_shared/pr-templates.md",
204
- "templates/skills/orc/subskills/orc-pr/stack-gate.md",
205
- "templates/skills/orc-diy/SKILL.md",
206
- "templates/skills/orc-diy/README.md",
207
- "templates/skills/orc-diy/references/compile.md",
208
- "templates/skills/orc-diy/references/flow-schema.md",
209
- "templates/skills/orc-diy/references/locked-blocks.md",
210
- "templates/skills/orc-diy/references/blocks/header.md",
211
- "templates/skills/orc-quick/SKILL.md",
212
- "templates/skills/orc-quick/README.md",
213
- "templates/skills/orc-quick/references/context-doc.md",
214
- "templates/skills/orc-quick/references/dispatch-gate.md",
215
- "templates/skills/orc-quick/references/gh-mode.md",
216
- // Quality-of-life lanes (v0.42.0). Three skills, ZERO new agents — the grill
217
- // dispatches read-only recon ad-hoc (the orc-quick precedent) and the other
218
- // two dispatch nothing at all. `_shared/interview.md` is the canonical
219
- // mechanic both the grill and intake.md run; a missing copy of it makes the
220
- // grill a lane with no procedure.
221
- "templates/skills/_shared/interview.md",
222
- "templates/skills/orc-grill/SKILL.md",
223
- "templates/skills/orc-grill/references/grill-doc.md",
224
- // v0.45.0 — /orc-brainstorm, again with ZERO new agents. `lane-suspend.md` is
225
- // the RETURN-TO contract BOTH halves of the brainstorm↔grill trip read: a
226
- // publish missing it leaves a lane that suspends into another lane with no
227
- // definition of how (or whether) it comes back. `lenses.md` is the only place
228
- // ORC generates options on purpose — without it B2 is a mood, not a phase.
229
- "templates/skills/_shared/lane-suspend.md",
230
- "templates/skills/orc-brainstorm/SKILL.md",
231
- "templates/skills/orc-brainstorm/references/brainstorm-doc.md",
232
- "templates/skills/orc-brainstorm/references/lenses.md",
233
- "templates/commands/orc-brainstorm.md",
234
- // v0.46.0 — the six new lanes. Named file by file for the same reason the
235
- // panel's files are: each SKILL.md is useless without its references (a lane
236
- // whose card/ledger/surface shape is missing dispatches against a contract it
237
- // cannot read), and the two CONSUMER gate files are what /orc loads at Phase 1
238
- // — a publish that drops one leaves the spine pointing at nothing.
239
- "templates/skills/orc-pact/SKILL.md",
240
- "templates/skills/orc-pact/references/ledger.md",
241
- "templates/skills/orc-pact/references/gate.md",
242
- "templates/skills/orc-boundary/SKILL.md",
243
- "templates/skills/orc-boundary/references/card.md",
244
- "templates/skills/orc-boundary/references/gate.md",
245
- "templates/skills/orc-handoff/SKILL.md",
246
- "templates/skills/orc-handoff/references/surfaces.md",
247
- "templates/skills/orc-handoff/references/handoff-log.md",
248
- "templates/skills/orc-budget/SKILL.md",
249
- "templates/skills/orc-budget/references/corpus.md",
250
- "templates/skills/orc-aftermath/SKILL.md",
251
- "templates/skills/orc-aftermath/references/report.md",
252
- "templates/skills/orc-export/SKILL.md",
253
- // W1 — the partial-refresh reference is the whole tier ladder + the budget cap
254
- // + the retirement offer; without it orc-wiki's spine points at a missing file
255
- // at exactly the moment it has to choose which scanner to dispatch.
256
- "templates/skills/orc-wiki/references/partial-refresh.md",
257
- // v0.47.0 — /orc-challenge. Named file by file for the reason every lane's
258
- // files are: the SKILL.md is a spine and its references ARE the contract. A
259
- // publish that drops `sealed-slice.md` ships a judge whose slice has no
260
- // definition, which is the one thing this lane exists to prevent; a publish
261
- // that drops `intake.md` ships a lane with no goal contract, so rule 0 becomes
262
- // a sentence nobody can act on.
263
- "templates/skills/orc-challenge/SKILL.md",
264
- "templates/skills/orc-challenge/README.md",
265
- "templates/skills/orc-challenge/references/intake.md",
266
- "templates/skills/orc-challenge/references/dimensions.md",
267
- "templates/skills/orc-challenge/references/kinds.md",
268
- "templates/skills/orc-challenge/references/rubric.md",
269
- "templates/skills/orc-challenge/references/sealed-slice.md",
270
- "templates/skills/orc-challenge/references/cycle-state.md",
271
- "templates/skills/orc-challenge/references/verdict-doc.md",
272
- "templates/skills/orc-challenge/references/fix-brief.md",
273
- "templates/skills/orc-challenge/references/plain-english.md",
274
- "templates/skills/orc-challenge/references/conservation.md",
275
- // v0.49.1 — the council's canonical prose. The spine keeps the token and a
276
- // pointer; this file is the one copy (the `_shared/` discipline).
277
- "templates/skills/orc-challenge/references/council.md",
278
- "templates/skills/orc-challenge/examples/council-full-roster.md",
279
- // v0.48.0 — /orc-doc. Named file by file for the reason every lane's files
280
- // are: `chunking.md` IS the token architecture (a publish that drops it ships
281
- // an orchestrator with no definition of what it may hold, which is the one
282
- // thing this lane exists to bound), `resume-protocol.md` is the whole reason
283
- // the context is frozen, and `templates/` is the five base skeletons the
284
- // batching table is pinned to by a golden test.
285
- "templates/skills/orc-doc/SKILL.md",
286
- "templates/skills/orc-doc/README.md",
287
- "templates/skills/orc-doc/references/gates.md",
288
- "templates/skills/orc-doc/references/chunking.md",
289
- "templates/skills/orc-doc/references/resume-protocol.md",
290
- "templates/skills/orc-doc/references/portable-markdown.md",
291
- "templates/skills/orc-doc/references/plain-language.md",
292
- "templates/skills/orc-doc/references/import-targets.md",
293
- // v0.49.2 — the project's own house rules, and ORC's own generation rules.
294
- // Two files because they are read in that ORDER and the order is the contract.
295
- "templates/skills/orc-doc/references/house-rules.md",
296
- "templates/skills/orc-doc/references/generation-rules.md",
297
- "templates/skills/orc-doc/references/templates/prd.md",
298
- "templates/skills/orc-doc/references/templates/tsd.md",
299
- "templates/skills/orc-doc/references/templates/collaboration.md",
300
- "templates/skills/orc-doc/references/templates/report.md",
301
- "templates/skills/orc-doc/references/templates/workflow.md",
302
- "templates/commands/orc-doc.md",
303
- "templates/commands/orc-challenge.md",
304
- "templates/commands/orc-pact.md",
305
- "templates/commands/orc-boundary.md",
306
- "templates/commands/orc-handoff.md",
307
- "templates/commands/orc-budget.md",
308
- "templates/commands/orc-aftermath.md",
309
- "templates/commands/orc-export.md",
310
- "templates/skills/orc-route/SKILL.md",
311
- "templates/skills/orc-explain/SKILL.md",
312
- "templates/skills/orc-analyze/references/thin-input.md",
313
- // v1.0.0 W7 — the ONE config doc. `orc/config.md` stopped restating 72 key
314
- // defaults and now points here for the ranks, the families, the gates, the
315
- // `announce[]` boundary and the CLI-absent floor. A publish missing this file
316
- // leaves every lane's `## Config` section pointing at nothing — and the
317
- // fallback that is supposed to fire when the CLI cannot answer is exactly the
318
- // moment there is no CLI to ask instead.
319
- "templates/skills/_shared/config-precedence.md",
320
- // v1.0.0 W11 — the phase library. The shared phase material already existed
321
- // and was already shared; it just lived in ONE lane's private folder with 26
322
- // other lanes reaching across into it. A publish missing any of these leaves
323
- // every one of those lanes pointing at nothing — and `trace.md` in particular
324
- // is the file that says how a run records itself, so its absence is silent by
325
- // construction. README.md carries the CLOSED layer set, which is what stops a
326
- // trimmed lane reading a full-lane procedure.
327
- "templates/skills/_shared/phases/README.md",
328
- "templates/skills/_shared/phases/trace.md",
329
- "templates/skills/_shared/phases/preflight.md",
330
- "templates/skills/_shared/phases/stop-resume.md",
331
- // v1.0.0 W12 — the seven files that were already SHARED while living in one
332
- // lane's private `references/`. Their consumers are measured, not believed:
333
- // the C.6 lint asserts every declared reader really points at the file.
334
- "templates/skills/_shared/phases/intake.md",
335
- "templates/skills/_shared/phases/plan-handoff.md",
336
- "templates/skills/_shared/phases/wave-grouping.md",
337
- "templates/skills/_shared/phases/analyst-gates.md",
338
- "templates/skills/_shared/phases/wiki-consult.md",
339
- "templates/skills/_shared/phases/security-checklist.md",
340
- "templates/skills/_shared/phases/house-rules.md",
341
- // v1.0.0 W13 — the ten build phases orc-diy became the second reader of.
342
- // Each carries TWO layers: `full` (/orc's procedure) and `composed` (what
343
- // `orc diy compile` stitches). A publish missing one breaks BOTH lanes, and
344
- // breaks orc-diy loudly — the compiler names the file and refuses.
345
- "templates/skills/_shared/phases/planning.md",
346
- "templates/skills/_shared/phases/scoring.md",
347
- "templates/skills/_shared/phases/execution.md",
348
- "templates/skills/_shared/phases/review.md",
349
- "templates/skills/_shared/phases/security.md",
350
- "templates/skills/_shared/phases/verify.md",
351
- "templates/skills/_shared/phases/testgen.md",
352
- "templates/skills/_shared/phases/mock-example.md",
353
- "templates/skills/_shared/phases/summary.md",
354
- "templates/skills/_shared/phases/ship.md",
355
- // v1.0.0 W12 — /orc's own phase bodies, W13 — down to the two nothing else
356
- // runs. The spine is loaded IN FULL on activation and these are loaded when
357
- // their phase fires; a publish missing one leaves the manifest naming a file
358
- // that is not there, which is a phase that silently does nothing.
359
- "templates/skills/orc/references/phases/intake.md",
360
- "templates/skills/orc/references/phases/integration.md",
361
- // v1.0.0 W14 — orc-wiki's five phase bodies. A wiki run reaches FEW of them
362
- // (Phase 0 auto-branches into fresh / resume / refresh / repair, 3c is a legacy
363
- // backfill), which is what makes a file per phase pay here and not elsewhere.
364
- // A publish missing one leaves the manifest naming a file that is not there.
365
- "templates/skills/orc-wiki/references/phases/phase-0.md",
366
- "templates/skills/orc-wiki/references/phases/phase-1.md",
367
- "templates/skills/orc-wiki/references/phases/phase-2.md",
368
- "templates/skills/orc-wiki/references/phases/phase-3.md",
369
- "templates/skills/orc-wiki/references/phases/phase-3c.md",
370
- "templates/commands/orc-grill.md",
371
- "templates/commands/orc-route.md",
372
- "templates/commands/orc-explain.md",
373
- "templates/commands/orc.md",
374
- "templates/commands/orc-quick.md",
375
- "templates/commands/orc-diy.md",
376
- "templates/commands/orc-ultra.md",
377
- "templates/commands/orc-fast.md",
378
- "templates/commands/orc-claude.md",
379
- "templates/commands/orc-learn.md",
380
- "templates/commands/orc-poly.md",
381
- "templates/commands/orc-pr-setup.md",
382
- "templates/commands/orc-pr-driver.md",
383
- "templates/agents/MODEL-MAPPING.md",
384
- "templates/agents/orc-advisor-opus-5-xhigh.md",
385
- "templates/agents/orc-judge-opus-5-xhigh.md",
386
- "templates/agents/orc-claude-writer-opus-4-8-high.md",
387
- "templates/agents/orc-learn-writer-opus-5-low.md",
388
- "templates/agents/orc-trace-writer-haiku-4-5.md",
389
- // Core non-generated agents — named explicitly so a dropped file is REPORTED
390
- // by name, not merely absorbed by the count floor. (The 8 executor agents are
391
- // checked separately by `build-agents.js --check`.)
392
- "templates/agents/orc-system-analyst-opus-5-high.md",
393
- "templates/agents/orc-planner-opus-5-med.md",
394
- "templates/agents/orc-reviewer-opus-5-med.md",
395
- "templates/agents/orc-verifier-opus-5-med.md",
396
- "templates/agents/orc-scout-sonnet-4-6-high.md",
397
- "templates/agents/orc-test-author-opus-5-med.md",
398
- "templates/agents/orc-pattern-codifier-sonnet-5-high.md",
399
- "templates/agents/orc-retro-sonnet-5-high.md",
400
- "templates/agents/orc-wiki-scanner-opus-4-8-high.md",
401
- // v0.46.0 — the LIGHT half of the wiki scan tier ladder. Both halves must ship:
402
- // the ladder resolves at dispatch time, so a missing light scanner makes every
403
- // small-delta refresh dispatch a nonexistent agent.
404
- "templates/agents/orc-wiki-scanner-sonnet-5-high.md",
405
- "templates/agents/orc-context-combiner-opus-5-high.md",
406
- // The orc-mini lane's agent pair and the whole Fable 5 role-override feature
407
- // were guarded by nothing but the count floor — a publish missing any of them
408
- // ships a lane that dispatches a nonexistent agent.
409
- "templates/agents/orc-analyze-mini-sonnet-5-high.md",
410
- "templates/agents/orc-planner-mini-sonnet-5-high.md",
411
- // The Opus-5-only mode roster (v0.36.0). Both halves of every pair must ship:
412
- // the mode is a runtime toggle, so a missing variant makes `opus5_only: true`
413
- // dispatch a nonexistent agent for that role.
414
- "templates/agents/orc-analyze-mini-opus-5-med.md",
415
- "templates/agents/orc-planner-mini-opus-5-med.md",
416
- "templates/agents/orc-scout-opus-5-low.md",
417
- "templates/agents/orc-pattern-codifier-opus-5-med.md",
418
- "templates/agents/orc-wiki-scanner-opus-5-med.md",
419
- "templates/agents/orc-claude-writer-opus-5-med.md",
420
- "templates/agents/orc-retro-opus-5-med.md",
421
- // v0.47.0 — the three /orc-challenge agents. All THREE must ship: a cycle that
422
- // cannot dispatch the reader silently loses D4, and one that cannot dispatch
423
- // the advisor turns a FAIL into a list with no order. All three are already
424
- // Opus 5, so `opus5_only` needs no twin for any of them.
425
- "templates/agents/orc-challenge-judge-opus-5-high.md",
426
- "templates/agents/orc-challenge-advisor-opus-5-med.md",
427
- "templates/agents/orc-challenge-reader-opus-5-low.md",
428
- // v0.49.1 — THE COUNCIL. Five DIFFERENT INSTRUMENTS, not five tiers of one:
429
- // the contrarian assumes a fatal flaw, the outsider knows nothing and may not
430
- // be told, the council executor asks what you do Monday morning, the
431
- // first-principles thinker disputes the goal itself, and the expansionist is
432
- // the only lens not looking for a defect. All five must ship: a roster lens
433
- // that cannot be dispatched is a NOT-RUN row a user paid to select, and rule
434
- // 15 makes that loud rather than silent. All five are claude-opus-5, so
435
- // `opus5_only` adds NO pair and the floor moves by exactly five.
436
- "templates/agents/orc-challenge-contrarian-opus-5-high.md",
437
- "templates/agents/orc-challenge-outsider-opus-5-low.md",
438
- "templates/agents/orc-challenge-executor-opus-5-med.md",
439
- "templates/agents/orc-challenge-principles-opus-5-high.md",
440
- "templates/agents/orc-challenge-expansionist-opus-5-med.md",
441
- // v0.48.0 — the two /orc-doc agents. BOTH must ship: a write wave that cannot
442
- // dispatch the writer has nothing to assemble, and a check wave that cannot
443
- // dispatch the checker silently turns the only judgment step into the free
444
- // lint. Both are already Opus 5, so `opus5_only` adds no twin for either.
445
- "templates/agents/orc-doc-writer-opus-5-med.md",
446
- "templates/agents/orc-doc-checker-opus-5-low.md",
447
- "templates/hooks/orc-effort-guard.js",
448
- "templates/hooks/orc-statusline.js",
449
- "templates/hooks/orc-trace.js",
450
- ];
451
-
452
- const missing = [];
453
- for (const rel of required) {
454
- if (!fs.existsSync(path.join(ROOT, rel))) missing.push(rel);
455
- }
456
-
457
- // Every skill dir must contain at least one SKILL.md; every agent file must be non-empty.
458
- function walkCount(dir, ext) {
459
- let n = 0;
460
- if (!fs.existsSync(dir)) return 0;
461
- for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
462
- const p = path.join(dir, e.name);
463
- if (e.isDirectory()) n += walkCount(p, ext);
464
- else if (e.name.endsWith(ext)) n += 1;
465
- }
466
- return n;
467
- }
468
-
469
- const skillCount = walkCount(path.join(ROOT, "templates/skills"), "SKILL.md");
470
- const agentCount = walkCount(path.join(ROOT, "templates/agents"), ".md");
471
- // Floors sit AT current reality (26 skills / 40 agent files: 39 agents +
472
- // MODEL-MAPPING.md — +7 fixed-role variants for the opus5_only mode) so a
473
- // dropped file fails the count check instead of sliding
474
- // into the slack an under-set floor grants. Raise them with the payload.
475
- // v0.38.0: +1 skill (orc-quick) and NO new agent — the quick lane reuses
476
- // shipped executors and dispatches read-only recon ad-hoc by model name.
477
- // v0.42.0: +3 skills (orc-grill, orc-route, orc-explain) and still NO new
478
- // agent same precedent. The agent floor deliberately does NOT move: a QoL
479
- // lane that needed a pinned agent would also need its opus5_only twin, a
480
- // MODEL-MAPPING row and a golden test, which is why none of them has one.
481
- // v0.45.0: +1 skill (orc-brainstorm) and STILL no new agent its divergent
482
- // generation is the orchestrator's own work and its recon is dispatched ad-hoc
483
- // by model+effort, so the agent floor holds at 40.
484
- // v0.46.0: +6 skills (orc-pact, orc-boundary, orc-handoff, orc-budget,
485
- // orc-aftermath, orc-export) and +1 agent and the split is the point. Five of
486
- // the six lanes ship ZERO agents (the v0.38.0/v0.45.0 precedent: read-only recon
487
- // is dispatched ad-hoc by model+effort, and three of them dispatch nothing at
488
- // all because their work is deterministic CLI). The ONE new agent is the wiki
489
- // scan ladder's LIGHT half, which is a real dispatch target with a real name and
490
- // therefore earns a MODEL-MAPPING row, an explicit guard entry above, and a
491
- // place in the opus5_only table's prose.
492
- // v0.47.0: +1 skill (orc-challenge) and +3 agents the first lane since v0.42.0
493
- // to earn any, and it earns three because each is a DIFFERENT INSTRUMENT, not a
494
- // tier of the same one. The reader is `low` on purpose (a harder-thinking reader
495
- // papers over exactly the gaps D4 measures), the judge is `high` because D2 is
496
- // the only dimension no computer can reach, and the advisor is `medium` because
497
- // grouping findings is pattern work. All three are claude-opus-5, so `opus5_only`
498
- // adds NO pair and the floor moves by exactly three.
499
- // v0.48.0: +1 skill (orc-doc) and +2 agents. The split follows v0.47.0's rule
500
- // an agent exists when it is a DIFFERENT INSTRUMENT, not a tier of the same one.
501
- // The writer holds one part file and never `document.md`; the checker holds one
502
- // LINE RANGE and has `Read` only. The checker is `low` on purpose (a
503
- // harder-thinking checker reasons its way past a gap a real reader would trip
504
- // on the challenge cold reader's reasoning), so nothing may upgrade it. Both
505
- // are claude-opus-5, so `opus5_only` adds NO pair and the floor moves by two.
506
- // v0.49.1: +0 skills and +5 agents THE COUNCIL. Same rule as v0.47.0, applied
507
- // five times: each of these is a DIFFERENT INSTRUMENT, not a tier of one. The
508
- // outsider is `low` and the contrarian is `high` for the same class of reason
509
- // the cold reader is `low` effort here is a MEASUREMENT choice, not a cost
510
- // one, and a key that let either be tuned would be a key that let the
511
- // instrument be broken. All five are claude-opus-5, so `opus5_only` adds NO
512
- // pair and the floor moves by exactly five.
513
- // v1.0.0 W3: +0 skills and -5 agents the Fable 5 role override is REMOVED.
514
- // It is the first time this floor has ever gone DOWN, and the reason it may is
515
- // that the five files are not a tier of anything: they were a whole second
516
- // answer to "which model runs a role", competing with `opus5_only` for the same
517
- // decision. Deleting them removes a rank from `fixed-role-model` rather than a
518
- // capability from a lane. Fable 5 survives as a SESSION model (the effort guard
519
- // and the statusline still clear it at medium) that is a different question,
520
- // and this wave does not touch it.
521
- if (skillCount < 38) missing.push(`templates/skills (expected >=38 SKILL.md, found ${skillCount})`);
522
- if (agentCount < 46) missing.push(`templates/agents (expected >=46 .md, found ${agentCount})`);
523
-
524
- // B4 encoding/mojibake guard. The OneDrive corruption rule becomes a gate:
525
- // scan every shipped text file for the U+FFFD replacement char (invalid UTF-8
526
- // decodes to it) and for a whitespace-flanked run of three-or-more question
527
- // marks the shape a mangled em/en-dash or curly quote collapses into (a
528
- // space-flanked dash becoming space-Q-Q-Q-space). A genuine "What???" has no
529
- // leading space, so it is not flagged.
530
- const MOJIBAKE = /(^|\s)\?{3,}(\s|$)/;
531
- // U+FFFD needle built from its code point so this scanner never flags its own source.
532
- const REPL = String.fromCharCode(0xfffd);
533
- function scanEncoding(dir, hits) {
534
- if (!fs.existsSync(dir)) return;
535
- const st = fs.statSync(dir);
536
- if (st.isFile()) {
537
- let text;
538
- try {
539
- text = fs.readFileSync(dir, "utf8");
540
- } catch (_) {
541
- return; // unreadable → not our concern here
542
- }
543
- const rel = path.relative(ROOT, dir).replace(/\\/g, "/");
544
- // Reference U+FFFD via escape, never as a literal, so this scanner does not
545
- // flag its own source.
546
- if (text.includes(REPL)) hits.push(`${rel} (U+FFFD replacement char corrupted bytes)`);
547
- else if (MOJIBAKE.test(text)) hits.push(`${rel} (whitespace-flanked "???" — likely mangled dash/quote)`);
548
- return;
549
- }
550
- for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
551
- scanEncoding(path.join(dir, e.name), hits);
552
- }
553
- }
554
- const encodingHits = [];
555
- scanEncoding(path.join(ROOT, "package.json"), encodingHits);
556
- scanEncoding(path.join(ROOT, "bin"), encodingHits);
557
- scanEncoding(path.join(ROOT, "templates"), encodingHits);
558
- for (const h of encodingHits) missing.push("encoding: " + h);
559
-
560
- if (missing.length) {
561
- console.error("\n❌ ORC package integrity check FAILED. Missing / incomplete:");
562
- for (const m of missing) console.error(" - " + m);
563
- console.error("\nDo NOT publish or push this tree. Likely cause: files were not");
564
- console.error("committed (OneDrive sync can corrupt commits). Rebuild the repo");
565
- console.error("OUTSIDE any cloud-synced folder, `git add -A`, verify, then push.\n");
566
- process.exit(1);
567
- }
568
- console.log(`✅ ORC package OK ${skillCount} skills, ${agentCount} agent files, cli present.`);
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * Package integrity check. Fails LOUDLY if any critical file is missing —
5
+ * so an incomplete push (e.g. corrupted by OneDrive sync) errors immediately
6
+ * instead of installing a dangling `orc` command.
7
+ * Runs on prepack (before publish/pack) and can be run manually: node bin/verify-package.js
8
+ */
9
+ const fs = require("fs");
10
+ const path = require("path");
11
+
12
+ const ROOT = path.join(__dirname, "..");
13
+ const required = [
14
+ "bin/cli.js",
15
+ "package.json",
16
+ "README.md",
17
+ // The `orc ui` web panel (v0.43.0). Named file by file, not covered by a
18
+ // count: the panel is a set of files that only work together, and a publish
19
+ // missing any one of them serves a page that 500s or renders blank. NOTE the
20
+ // folder — `bin/ui.js` is the TERMINAL styling kit and is a different thing.
21
+ "bin/webui/serve.js",
22
+ "bin/webui/api.js",
23
+ "bin/webui/app.html",
24
+ // The stylesheet layers (v0.48.1). The <link> order in app.html is the
25
+ // cascade order; 06-responsive and 04-motion are last on purpose.
26
+ "bin/webui/css/00-tokens.css",
27
+ "bin/webui/css/01-base.css",
28
+ "bin/webui/css/02-shell.css",
29
+ "bin/webui/css/03-components.css",
30
+ "bin/webui/css/04-motion.css",
31
+ "bin/webui/css/05-tour.css",
32
+ "bin/webui/css/06-responsive.css",
33
+ "bin/webui/css/panels/overview.css",
34
+ "bin/webui/css/panels/settings.css",
35
+ "bin/webui/css/panels/lanes.css",
36
+ "bin/webui/css/panels/runs.css",
37
+ "bin/webui/css/panels/knowledge.css",
38
+ // No knowledge.css: that panel is composed entirely from shared primitives
39
+ // (.card, .chip, .tbl, .bar-track). An empty stylesheet would be one more
40
+ // request and one more thing to keep in the manifest for no rules at all.
41
+ "bin/webui/css/panels/stats.css",
42
+ "bin/webui/css/panels/flow.css",
43
+ "bin/webui/css/panels/crosslink.css",
44
+ "bin/webui/css/panels/learn.css",
45
+ "bin/webui/css/panels/mockrun.css",
46
+ "bin/webui/css/panels/maintenance.css",
47
+ "bin/webui/css/panels/pact.css",
48
+ "bin/webui/css/panels/boundary.css",
49
+ "bin/webui/css/panels/wait.css",
50
+ "bin/webui/css/panels/handoff.css",
51
+ "bin/webui/css/panels/challenge.css",
52
+ "bin/webui/css/panels/docs.css",
53
+ "bin/webui/css/panels/extra.css",
54
+ "bin/webui/css/panels/experiment.css",
55
+ // The client modules (v0.48.1). The <script> order in app.html is the load
56
+ // order and the numeric prefix is that order; 99-boot.js must be last.
57
+ "bin/webui/js/00-core.js",
58
+ "bin/webui/js/01-i18n.js",
59
+ "bin/webui/js/02-ui.js",
60
+ "bin/webui/js/03-md.js",
61
+ "bin/webui/js/04-router.js",
62
+ "bin/webui/js/05-banners.js",
63
+ "bin/webui/js/06-edit.js",
64
+ "bin/webui/js/panels/overview.js",
65
+ "bin/webui/js/panels/settings.js",
66
+ "bin/webui/js/panels/lanes.js",
67
+ "bin/webui/js/panels/runs.js",
68
+ "bin/webui/js/panels/knowledge.js",
69
+ "bin/webui/js/panels/stats.js",
70
+ "bin/webui/js/panels/flow.js",
71
+ "bin/webui/js/panels/crosslink.js",
72
+ "bin/webui/js/panels/learn.js",
73
+ "bin/webui/js/panels/mockrun.js",
74
+ "bin/webui/js/panels/experiment.js",
75
+ "bin/webui/js/panels/maintenance.js",
76
+ "bin/webui/js/panels/pact.js",
77
+ "bin/webui/js/panels/boundary.js",
78
+ "bin/webui/js/panels/wait.js",
79
+ "bin/webui/js/panels/handoff.js",
80
+ "bin/webui/js/panels/challenge.js",
81
+ "bin/webui/js/panels/docs.js",
82
+ "bin/webui/js/panels/extra.js",
83
+ "bin/webui/js/90-tour.js",
84
+ "bin/webui/js/91-shortcuts.js",
85
+ "bin/webui/js/99-boot.js",
86
+ // The canned data (v0.48.1), one file per panel. index.js is the ROUTER;
87
+ // every other file is data. --fixtures must carry ONE OF EVERY STATE.
88
+ "bin/webui/fixtures/index.js",
89
+ "bin/webui/fixtures/shell.js",
90
+ "bin/webui/fixtures/settings.js",
91
+ "bin/webui/fixtures/lanes.js",
92
+ "bin/webui/fixtures/knowledge.js",
93
+ "bin/webui/fixtures/runs.js",
94
+ "bin/webui/fixtures/stats.js",
95
+ "bin/webui/fixtures/pact.js",
96
+ "bin/webui/fixtures/boundary.js",
97
+ "bin/webui/fixtures/wait.js",
98
+ "bin/webui/fixtures/handoff.js",
99
+ "bin/webui/fixtures/maintenance.js",
100
+ "bin/webui/fixtures/challenge.js",
101
+ "bin/webui/fixtures/docs.js",
102
+ "bin/webui/fixtures/flow.js",
103
+ "bin/webui/fixtures/crosslink.js",
104
+ "bin/webui/fixtures/mockrun.js",
105
+ "bin/webui/fixtures/extra.js",
106
+ // The string tables (v0.43.6). Named here for the same reason: English is the
107
+ // FALLBACK table every other language falls back to, so a publish that drops
108
+ // it renders raw dotted keys on every panel, in every language.
109
+ // v0.52.0 - the TERM LIST. It is not a string table and is never fetched by
110
+ // the page; it is the one page that keeps the next two hundred strings
111
+ // consistent, and without it a wording pass drifts back within two releases.
112
+ "bin/webui/i18n/TERMS.md",
113
+ "bin/webui/i18n/en/common.json",
114
+ "bin/webui/i18n/en/nav.json",
115
+ "bin/webui/i18n/en/banner.json",
116
+ "bin/webui/i18n/en/overview.json",
117
+ "bin/webui/i18n/en/settings.json",
118
+ "bin/webui/i18n/en/lanes.json",
119
+ "bin/webui/i18n/en/runs.json",
120
+ "bin/webui/i18n/en/knowledge.json",
121
+ "bin/webui/i18n/en/stats.json",
122
+ "bin/webui/i18n/en/flow.json",
123
+ "bin/webui/i18n/en/crosslink.json",
124
+ "bin/webui/i18n/en/learn.json",
125
+ "bin/webui/i18n/en/mockrun.json",
126
+ "bin/webui/i18n/en/maintenance.json",
127
+ "bin/webui/i18n/en/pact.json",
128
+ "bin/webui/i18n/en/boundary.json",
129
+ "bin/webui/i18n/en/wait.json",
130
+ "bin/webui/i18n/en/handoff.json",
131
+ "bin/webui/i18n/en/challenge.json",
132
+ "bin/webui/i18n/en/docs.json",
133
+ "bin/webui/i18n/en/extra.json",
134
+ "bin/webui/i18n/en/experiment.json",
135
+ "bin/webui/i18n/en/tour.json",
136
+ "bin/webui/i18n/id/common.json",
137
+ "bin/webui/i18n/id/nav.json",
138
+ "bin/webui/i18n/id/banner.json",
139
+ "bin/webui/i18n/id/overview.json",
140
+ "bin/webui/i18n/id/settings.json",
141
+ "bin/webui/i18n/id/lanes.json",
142
+ "bin/webui/i18n/id/runs.json",
143
+ "bin/webui/i18n/id/knowledge.json",
144
+ "bin/webui/i18n/id/stats.json",
145
+ "bin/webui/i18n/id/flow.json",
146
+ "bin/webui/i18n/id/crosslink.json",
147
+ "bin/webui/i18n/id/learn.json",
148
+ "bin/webui/i18n/id/mockrun.json",
149
+ "bin/webui/i18n/id/maintenance.json",
150
+ "bin/webui/i18n/id/pact.json",
151
+ "bin/webui/i18n/id/boundary.json",
152
+ "bin/webui/i18n/id/wait.json",
153
+ "bin/webui/i18n/id/handoff.json",
154
+ "bin/webui/i18n/id/challenge.json",
155
+ "bin/webui/i18n/id/docs.json",
156
+ "bin/webui/i18n/id/extra.json",
157
+ "bin/webui/i18n/id/experiment.json",
158
+ "bin/webui/i18n/id/tour.json",
159
+ // The mocked runs (v0.46.x): the catalogue module plus the folder it reads.
160
+ // Both `orc mock-run` and the panel's Mocked Skill Use page are empty without
161
+ // them, and an empty catalogue looks like a broken feature rather than a
162
+ // publish that dropped a folder.
163
+ "bin/mockrun-catalog.js",
164
+ // The two DATED data files (v0.50.0). Both ship inside the package and both
165
+ // are load-bearing on absence rather than on content: without the catalog
166
+ // `orc extra providers` is a packaging bug it reports as one, and without the
167
+ // price table every `usd` reads as an em dash forever. They are named here for
168
+ // the same reason every webui file is — a publish that drops one serves a
169
+ // feature that looks broken rather than missing.
170
+ "bin/providers.json",
171
+ "bin/pricing.json",
172
+ "mock-run",
173
+ "mock-run/INDEX.md",
174
+ "templates",
175
+ "templates/skills/orc/SKILL.md",
176
+ "templates/skills/orc/references/ultra-mode.md",
177
+ "templates/skills/orc-advisor/SKILL.md",
178
+ "templates/skills/orc-judge/SKILL.md",
179
+ "templates/skills/orc-fast/SKILL.md",
180
+ "templates/skills/orc-claude/SKILL.md",
181
+ "templates/skills/orc-claude/references/template.md",
182
+ "templates/skills/orc-claude/references/refresh.md",
183
+ "templates/skills/orc-wiki/references/staleness.md",
184
+ "templates/skills/orc-learn/SKILL.md",
185
+ "templates/skills/orc-learn/references/refresh.md",
186
+ "templates/skills/orc-poly/SKILL.md",
187
+ "templates/skills/orc-poly/references/poly-spec.md",
188
+ "templates/skills/orc-poly/references/gather.md",
189
+ // Stacked pull requests (v0.37.0) — two standalone lanes plus the three
190
+ // canonical shared contracts they and ORC's ship gate all read. A missing
191
+ // shared file makes the ship gate hand off to a lane that cannot preflight.
192
+ "templates/skills/orc-pr-setup/SKILL.md",
193
+ "templates/skills/orc-pr-setup/README.md",
194
+ "templates/skills/orc-pr-setup/references/layer-taxonomy.md",
195
+ "templates/skills/orc-pr-setup/references/certainty-gate.md",
196
+ "templates/skills/orc-pr-driver/SKILL.md",
197
+ "templates/skills/orc-pr-driver/README.md",
198
+ "templates/skills/orc-pr-driver/references/green-gate.md",
199
+ "templates/skills/orc-pr-driver/references/orc-run-split.md",
200
+ "templates/skills/orc-pr-driver/references/conflict-playbook.md",
201
+ "templates/skills/_shared/stack-plan.md",
202
+ "templates/skills/_shared/gh-stack-commands.md",
203
+ "templates/skills/_shared/pr-templates.md",
204
+ "templates/skills/orc/subskills/orc-pr/stack-gate.md",
205
+ "templates/skills/orc-diy/SKILL.md",
206
+ "templates/skills/orc-diy/README.md",
207
+ "templates/skills/orc-diy/references/compile.md",
208
+ "templates/skills/orc-diy/references/flow-schema.md",
209
+ "templates/skills/orc-diy/references/locked-blocks.md",
210
+ "templates/skills/orc-diy/references/blocks/header.md",
211
+ "templates/skills/orc-quick/SKILL.md",
212
+ "templates/skills/orc-quick/README.md",
213
+ "templates/skills/orc-quick/references/context-doc.md",
214
+ "templates/skills/orc-quick/references/dispatch-gate.md",
215
+ "templates/skills/orc-quick/references/gh-mode.md",
216
+ // Quality-of-life lanes (v0.42.0). Three skills, ZERO new agents — the grill
217
+ // dispatches read-only recon ad-hoc (the orc-quick precedent) and the other
218
+ // two dispatch nothing at all. `_shared/interview.md` is the canonical
219
+ // mechanic both the grill and intake.md run; a missing copy of it makes the
220
+ // grill a lane with no procedure.
221
+ "templates/skills/_shared/interview.md",
222
+ "templates/skills/orc-grill/SKILL.md",
223
+ "templates/skills/orc-grill/references/grill-doc.md",
224
+ // v0.45.0 — /orc-brainstorm, again with ZERO new agents. `lane-suspend.md` is
225
+ // the RETURN-TO contract BOTH halves of the brainstorm↔grill trip read: a
226
+ // publish missing it leaves a lane that suspends into another lane with no
227
+ // definition of how (or whether) it comes back. `lenses.md` is the only place
228
+ // ORC generates options on purpose — without it B2 is a mood, not a phase.
229
+ "templates/skills/_shared/lane-suspend.md",
230
+ "templates/skills/orc-brainstorm/SKILL.md",
231
+ "templates/skills/orc-brainstorm/references/brainstorm-doc.md",
232
+ "templates/skills/orc-brainstorm/references/lenses.md",
233
+ "templates/commands/orc-brainstorm.md",
234
+ // v0.46.0 — the six new lanes. Named file by file for the same reason the
235
+ // panel's files are: each SKILL.md is useless without its references (a lane
236
+ // whose card/ledger/surface shape is missing dispatches against a contract it
237
+ // cannot read), and the two CONSUMER gate files are what /orc loads at Phase 1
238
+ // — a publish that drops one leaves the spine pointing at nothing.
239
+ "templates/skills/orc-pact/SKILL.md",
240
+ "templates/skills/orc-pact/references/ledger.md",
241
+ "templates/skills/orc-pact/references/gate.md",
242
+ "templates/skills/orc-boundary/SKILL.md",
243
+ "templates/skills/orc-boundary/references/card.md",
244
+ "templates/skills/orc-boundary/references/gate.md",
245
+ "templates/skills/orc-handoff/SKILL.md",
246
+ "templates/skills/orc-handoff/references/surfaces.md",
247
+ "templates/skills/orc-handoff/references/handoff-log.md",
248
+ "templates/skills/orc-budget/SKILL.md",
249
+ "templates/skills/orc-budget/references/corpus.md",
250
+ "templates/skills/orc-aftermath/SKILL.md",
251
+ "templates/skills/orc-aftermath/references/report.md",
252
+ "templates/skills/orc-export/SKILL.md",
253
+ // W1 — the partial-refresh reference is the whole tier ladder + the budget cap
254
+ // + the retirement offer; without it orc-wiki's spine points at a missing file
255
+ // at exactly the moment it has to choose which scanner to dispatch.
256
+ "templates/skills/orc-wiki/references/partial-refresh.md",
257
+ // v0.47.0 — /orc-challenge. Named file by file for the reason every lane's
258
+ // files are: the SKILL.md is a spine and its references ARE the contract. A
259
+ // publish that drops `sealed-slice.md` ships a judge whose slice has no
260
+ // definition, which is the one thing this lane exists to prevent; a publish
261
+ // that drops `intake.md` ships a lane with no goal contract, so rule 0 becomes
262
+ // a sentence nobody can act on.
263
+ "templates/skills/orc-challenge/SKILL.md",
264
+ "templates/skills/orc-challenge/README.md",
265
+ "templates/skills/orc-challenge/references/intake.md",
266
+ "templates/skills/orc-challenge/references/dimensions.md",
267
+ "templates/skills/orc-challenge/references/kinds.md",
268
+ "templates/skills/orc-challenge/references/rubric.md",
269
+ "templates/skills/orc-challenge/references/sealed-slice.md",
270
+ "templates/skills/orc-challenge/references/cycle-state.md",
271
+ "templates/skills/orc-challenge/references/verdict-doc.md",
272
+ "templates/skills/orc-challenge/references/fix-brief.md",
273
+ "templates/skills/orc-challenge/references/plain-english.md",
274
+ "templates/skills/orc-challenge/references/conservation.md",
275
+ // v0.49.1 — the council's canonical prose. The spine keeps the token and a
276
+ // pointer; this file is the one copy (the `_shared/` discipline).
277
+ "templates/skills/orc-challenge/references/council.md",
278
+ "templates/skills/orc-challenge/examples/council-full-roster.md",
279
+ // v0.48.0 — /orc-doc. Named file by file for the reason every lane's files
280
+ // are: `chunking.md` IS the token architecture (a publish that drops it ships
281
+ // an orchestrator with no definition of what it may hold, which is the one
282
+ // thing this lane exists to bound), `resume-protocol.md` is the whole reason
283
+ // the context is frozen, and `templates/` is the five base skeletons the
284
+ // batching table is pinned to by a golden test.
285
+ "templates/skills/orc-doc/SKILL.md",
286
+ "templates/skills/orc-doc/README.md",
287
+ "templates/skills/orc-doc/references/gates.md",
288
+ "templates/skills/orc-doc/references/chunking.md",
289
+ "templates/skills/orc-doc/references/resume-protocol.md",
290
+ "templates/skills/orc-doc/references/portable-markdown.md",
291
+ "templates/skills/orc-doc/references/plain-language.md",
292
+ "templates/skills/orc-doc/references/import-targets.md",
293
+ // v0.49.2 — the project's own house rules, and ORC's own generation rules.
294
+ // Two files because they are read in that ORDER and the order is the contract.
295
+ "templates/skills/orc-doc/references/house-rules.md",
296
+ "templates/skills/orc-doc/references/generation-rules.md",
297
+ "templates/skills/orc-doc/references/templates/prd.md",
298
+ "templates/skills/orc-doc/references/templates/tsd.md",
299
+ "templates/skills/orc-doc/references/templates/collaboration.md",
300
+ "templates/skills/orc-doc/references/templates/report.md",
301
+ "templates/skills/orc-doc/references/templates/workflow.md",
302
+ "templates/commands/orc-doc.md",
303
+ "templates/commands/orc-challenge.md",
304
+ "templates/commands/orc-pact.md",
305
+ "templates/commands/orc-boundary.md",
306
+ "templates/commands/orc-handoff.md",
307
+ "templates/commands/orc-budget.md",
308
+ "templates/commands/orc-aftermath.md",
309
+ "templates/commands/orc-export.md",
310
+ "templates/skills/orc-route/SKILL.md",
311
+ "templates/skills/orc-explain/SKILL.md",
312
+ "templates/skills/orc-analyze/references/thin-input.md",
313
+ // v1.0.0 W7 — the ONE config doc. `orc/config.md` stopped restating 72 key
314
+ // defaults and now points here for the ranks, the families, the gates, the
315
+ // `announce[]` boundary and the CLI-absent floor. A publish missing this file
316
+ // leaves every lane's `## Config` section pointing at nothing — and the
317
+ // fallback that is supposed to fire when the CLI cannot answer is exactly the
318
+ // moment there is no CLI to ask instead.
319
+ "templates/skills/_shared/config-precedence.md",
320
+ // v1.0.0 W11 — the phase library. The shared phase material already existed
321
+ // and was already shared; it just lived in ONE lane's private folder with 26
322
+ // other lanes reaching across into it. A publish missing any of these leaves
323
+ // every one of those lanes pointing at nothing — and `trace.md` in particular
324
+ // is the file that says how a run records itself, so its absence is silent by
325
+ // construction. README.md carries the CLOSED layer set, which is what stops a
326
+ // trimmed lane reading a full-lane procedure.
327
+ "templates/skills/_shared/phases/README.md",
328
+ "templates/skills/_shared/phases/trace.md",
329
+ "templates/skills/_shared/phases/preflight.md",
330
+ "templates/skills/_shared/phases/stop-resume.md",
331
+ // v1.0.0 W12 — the seven files that were already SHARED while living in one
332
+ // lane's private `references/`. Their consumers are measured, not believed:
333
+ // the C.6 lint asserts every declared reader really points at the file.
334
+ "templates/skills/_shared/phases/intake.md",
335
+ "templates/skills/_shared/phases/plan-handoff.md",
336
+ "templates/skills/_shared/phases/wave-grouping.md",
337
+ "templates/skills/_shared/phases/analyst-gates.md",
338
+ "templates/skills/_shared/phases/wiki-consult.md",
339
+ "templates/skills/_shared/phases/security-checklist.md",
340
+ "templates/skills/_shared/phases/house-rules.md",
341
+ // v1.0.0 W13 — the ten build phases orc-diy became the second reader of.
342
+ // Each carries TWO layers: `full` (/orc's procedure) and `composed` (what
343
+ // `orc diy compile` stitches). A publish missing one breaks BOTH lanes, and
344
+ // breaks orc-diy loudly — the compiler names the file and refuses.
345
+ "templates/skills/_shared/phases/planning.md",
346
+ "templates/skills/_shared/phases/scoring.md",
347
+ "templates/skills/_shared/phases/execution.md",
348
+ "templates/skills/_shared/phases/review.md",
349
+ "templates/skills/_shared/phases/security.md",
350
+ "templates/skills/_shared/phases/verify.md",
351
+ "templates/skills/_shared/phases/testgen.md",
352
+ "templates/skills/_shared/phases/mock-example.md",
353
+ "templates/skills/_shared/phases/summary.md",
354
+ "templates/skills/_shared/phases/ship.md",
355
+ // v1.0.0 W12 — /orc's own phase bodies, W13 — down to the two nothing else
356
+ // runs. The spine is loaded IN FULL on activation and these are loaded when
357
+ // their phase fires; a publish missing one leaves the manifest naming a file
358
+ // that is not there, which is a phase that silently does nothing.
359
+ "templates/skills/orc/references/phases/intake.md",
360
+ "templates/skills/orc/references/phases/integration.md",
361
+ // v1.0.0 W14 — orc-wiki's five phase bodies. A wiki run reaches FEW of them
362
+ // (Phase 0 auto-branches into fresh / resume / refresh / repair, 3c is a legacy
363
+ // backfill), which is what makes a file per phase pay here and not elsewhere.
364
+ // A publish missing one leaves the manifest naming a file that is not there.
365
+ "templates/skills/orc-wiki/references/phases/phase-0.md",
366
+ "templates/skills/orc-wiki/references/phases/phase-1.md",
367
+ "templates/skills/orc-wiki/references/phases/phase-2.md",
368
+ "templates/skills/orc-wiki/references/phases/phase-3.md",
369
+ "templates/skills/orc-wiki/references/phases/phase-3c.md",
370
+ "templates/commands/orc-grill.md",
371
+ "templates/commands/orc-route.md",
372
+ "templates/commands/orc-explain.md",
373
+ "templates/commands/orc.md",
374
+ "templates/commands/orc-quick.md",
375
+ "templates/commands/orc-diy.md",
376
+ "templates/commands/orc-ultra.md",
377
+ "templates/commands/orc-fast.md",
378
+ "templates/commands/orc-claude.md",
379
+ "templates/commands/orc-learn.md",
380
+ "templates/commands/orc-poly.md",
381
+ "templates/commands/orc-pr-setup.md",
382
+ "templates/commands/orc-pr-driver.md",
383
+ "templates/agents/MODEL-MAPPING.md",
384
+ "templates/agents/orc-advisor-opus-5-xhigh.md",
385
+ "templates/agents/orc-judge-opus-5-xhigh.md",
386
+ "templates/agents/orc-claude-writer-opus-4-8-high.md",
387
+ "templates/agents/orc-learn-writer-opus-5-low.md",
388
+ "templates/agents/orc-trace-writer-haiku-4-5.md",
389
+ // Core non-generated agents — named explicitly so a dropped file is REPORTED
390
+ // by name, not merely absorbed by the count floor. (The 8 executor agents are
391
+ // checked separately by `build-agents.js --check`.)
392
+ "templates/agents/orc-system-analyst-opus-5-high.md",
393
+ "templates/agents/orc-planner-opus-5-med.md",
394
+ "templates/agents/orc-reviewer-opus-5-med.md",
395
+ "templates/agents/orc-verifier-opus-5-med.md",
396
+ "templates/agents/orc-scout-sonnet-4-6-high.md",
397
+ "templates/agents/orc-test-author-opus-5-med.md",
398
+ "templates/agents/orc-pattern-codifier-sonnet-5-high.md",
399
+ "templates/agents/orc-retro-sonnet-5-high.md",
400
+ "templates/agents/orc-wiki-scanner-opus-4-8-high.md",
401
+ // v0.46.0 — the LIGHT half of the wiki scan tier ladder. Both halves must ship:
402
+ // the ladder resolves at dispatch time, so a missing light scanner makes every
403
+ // small-delta refresh dispatch a nonexistent agent.
404
+ "templates/agents/orc-wiki-scanner-sonnet-5-high.md",
405
+ "templates/agents/orc-context-combiner-opus-5-high.md",
406
+ // The orc-mini lane's agent pair and the whole Fable 5 role-override feature
407
+ // were guarded by nothing but the count floor — a publish missing any of them
408
+ // ships a lane that dispatches a nonexistent agent.
409
+ "templates/agents/orc-analyze-mini-sonnet-5-high.md",
410
+ "templates/agents/orc-planner-mini-sonnet-5-high.md",
411
+ // The Opus-5-only mode roster (v0.36.0). Both halves of every pair must ship:
412
+ // the mode is a runtime toggle, so a missing variant makes `opus5_only: true`
413
+ // dispatch a nonexistent agent for that role.
414
+ "templates/agents/orc-analyze-mini-opus-5-med.md",
415
+ "templates/agents/orc-planner-mini-opus-5-med.md",
416
+ "templates/agents/orc-scout-opus-5-low.md",
417
+ "templates/agents/orc-pattern-codifier-opus-5-med.md",
418
+ "templates/agents/orc-wiki-scanner-opus-5-med.md",
419
+ "templates/agents/orc-claude-writer-opus-5-med.md",
420
+ "templates/agents/orc-retro-opus-5-med.md",
421
+ // v0.47.0 — the three /orc-challenge agents. All THREE must ship: a cycle that
422
+ // cannot dispatch the reader silently loses D4, and one that cannot dispatch
423
+ // the advisor turns a FAIL into a list with no order. All three are already
424
+ // Opus 5, so `opus5_only` needs no twin for any of them.
425
+ "templates/agents/orc-challenge-judge-opus-5-high.md",
426
+ "templates/agents/orc-challenge-advisor-opus-5-med.md",
427
+ "templates/agents/orc-challenge-reader-opus-5-low.md",
428
+ // v0.49.1 — THE COUNCIL. Five DIFFERENT INSTRUMENTS, not five tiers of one:
429
+ // the contrarian assumes a fatal flaw, the outsider knows nothing and may not
430
+ // be told, the council executor asks what you do Monday morning, the
431
+ // first-principles thinker disputes the goal itself, and the expansionist is
432
+ // the only lens not looking for a defect. All five must ship: a roster lens
433
+ // that cannot be dispatched is a NOT-RUN row a user paid to select, and rule
434
+ // 15 makes that loud rather than silent. All five are claude-opus-5, so
435
+ // `opus5_only` adds NO pair and the floor moves by exactly five.
436
+ "templates/agents/orc-challenge-contrarian-opus-5-high.md",
437
+ "templates/agents/orc-challenge-outsider-opus-5-low.md",
438
+ "templates/agents/orc-challenge-executor-opus-5-med.md",
439
+ "templates/agents/orc-challenge-principles-opus-5-high.md",
440
+ "templates/agents/orc-challenge-expansionist-opus-5-med.md",
441
+ // v0.48.0 — the two /orc-doc agents. BOTH must ship: a write wave that cannot
442
+ // dispatch the writer has nothing to assemble, and a check wave that cannot
443
+ // dispatch the checker silently turns the only judgment step into the free
444
+ // lint. Both are already Opus 5, so `opus5_only` adds no twin for either.
445
+ "templates/agents/orc-doc-writer-opus-5-med.md",
446
+ "templates/agents/orc-doc-checker-opus-5-low.md",
447
+ // v1.2.1 — the status line explained for the person reading it, in
448
+ // Simplified Technical English. It ships INTO .claude/hooks/ next to the hook
449
+ // it describes, because that is where somebody looking at a segment they do
450
+ // not recognise will look for it.
451
+ "templates/hooks/README.md",
452
+ "templates/hooks/orc-effort-guard.js",
453
+ "templates/hooks/orc-statusline.js",
454
+ "templates/hooks/orc-trace.js",
455
+ ];
456
+
457
+ const missing = [];
458
+ for (const rel of required) {
459
+ if (!fs.existsSync(path.join(ROOT, rel))) missing.push(rel);
460
+ }
461
+
462
+ // Every skill dir must contain at least one SKILL.md; every agent file must be non-empty.
463
+ function walkCount(dir, ext) {
464
+ let n = 0;
465
+ if (!fs.existsSync(dir)) return 0;
466
+ for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
467
+ const p = path.join(dir, e.name);
468
+ if (e.isDirectory()) n += walkCount(p, ext);
469
+ else if (e.name.endsWith(ext)) n += 1;
470
+ }
471
+ return n;
472
+ }
473
+
474
+ const skillCount = walkCount(path.join(ROOT, "templates/skills"), "SKILL.md");
475
+ const agentCount = walkCount(path.join(ROOT, "templates/agents"), ".md");
476
+ // Floors sit AT current reality (26 skills / 40 agent files: 39 agents +
477
+ // MODEL-MAPPING.md +7 fixed-role variants for the opus5_only mode) so a
478
+ // dropped file fails the count check instead of sliding
479
+ // into the slack an under-set floor grants. Raise them with the payload.
480
+ // v0.38.0: +1 skill (orc-quick) and NO new agent the quick lane reuses
481
+ // shipped executors and dispatches read-only recon ad-hoc by model name.
482
+ // v0.42.0: +3 skills (orc-grill, orc-route, orc-explain) and still NO new
483
+ // agent same precedent. The agent floor deliberately does NOT move: a QoL
484
+ // lane that needed a pinned agent would also need its opus5_only twin, a
485
+ // MODEL-MAPPING row and a golden test, which is why none of them has one.
486
+ // v0.45.0: +1 skill (orc-brainstorm) and STILL no new agent its divergent
487
+ // generation is the orchestrator's own work and its recon is dispatched ad-hoc
488
+ // by model+effort, so the agent floor holds at 40.
489
+ // v0.46.0: +6 skills (orc-pact, orc-boundary, orc-handoff, orc-budget,
490
+ // orc-aftermath, orc-export) and +1 agent and the split is the point. Five of
491
+ // the six lanes ship ZERO agents (the v0.38.0/v0.45.0 precedent: read-only recon
492
+ // is dispatched ad-hoc by model+effort, and three of them dispatch nothing at
493
+ // all because their work is deterministic CLI). The ONE new agent is the wiki
494
+ // scan ladder's LIGHT half, which is a real dispatch target with a real name and
495
+ // therefore earns a MODEL-MAPPING row, an explicit guard entry above, and a
496
+ // place in the opus5_only table's prose.
497
+ // v0.47.0: +1 skill (orc-challenge) and +3 agents the first lane since v0.42.0
498
+ // to earn any, and it earns three because each is a DIFFERENT INSTRUMENT, not a
499
+ // tier of the same one. The reader is `low` on purpose (a harder-thinking reader
500
+ // papers over exactly the gaps D4 measures), the judge is `high` because D2 is
501
+ // the only dimension no computer can reach, and the advisor is `medium` because
502
+ // grouping findings is pattern work. All three are claude-opus-5, so `opus5_only`
503
+ // adds NO pair and the floor moves by exactly three.
504
+ // v0.48.0: +1 skill (orc-doc) and +2 agents. The split follows v0.47.0's rule —
505
+ // an agent exists when it is a DIFFERENT INSTRUMENT, not a tier of the same one.
506
+ // The writer holds one part file and never `document.md`; the checker holds one
507
+ // LINE RANGE and has `Read` only. The checker is `low` on purpose (a
508
+ // harder-thinking checker reasons its way past a gap a real reader would trip
509
+ // on — the challenge cold reader's reasoning), so nothing may upgrade it. Both
510
+ // are claude-opus-5, so `opus5_only` adds NO pair and the floor moves by two.
511
+ // v0.49.1: +0 skills and +5 agents THE COUNCIL. Same rule as v0.47.0, applied
512
+ // five times: each of these is a DIFFERENT INSTRUMENT, not a tier of one. The
513
+ // outsider is `low` and the contrarian is `high` for the same class of reason
514
+ // the cold reader is `low` effort here is a MEASUREMENT choice, not a cost
515
+ // one, and a key that let either be tuned would be a key that let the
516
+ // instrument be broken. All five are claude-opus-5, so `opus5_only` adds NO
517
+ // pair and the floor moves by exactly five.
518
+ // v1.0.0 W3: +0 skills and -5 agents the Fable 5 role override is REMOVED.
519
+ // It is the first time this floor has ever gone DOWN, and the reason it may is
520
+ // that the five files are not a tier of anything: they were a whole second
521
+ // answer to "which model runs a role", competing with `opus5_only` for the same
522
+ // decision. Deleting them removes a rank from `fixed-role-model` rather than a
523
+ // capability from a lane. Fable 5 survives as a SESSION model (the effort guard
524
+ // and the statusline still clear it at medium) that is a different question,
525
+ // and this wave does not touch it.
526
+ if (skillCount < 38) missing.push(`templates/skills (expected >=38 SKILL.md, found ${skillCount})`);
527
+ if (agentCount < 46) missing.push(`templates/agents (expected >=46 .md, found ${agentCount})`);
528
+
529
+ // B4 encoding/mojibake guard. The OneDrive corruption rule becomes a gate:
530
+ // scan every shipped text file for the U+FFFD replacement char (invalid UTF-8
531
+ // decodes to it) and for a whitespace-flanked run of three-or-more question
532
+ // marks the shape a mangled em/en-dash or curly quote collapses into (a
533
+ // space-flanked dash becoming space-Q-Q-Q-space). A genuine "What???" has no
534
+ // leading space, so it is not flagged.
535
+ const MOJIBAKE = /(^|\s)\?{3,}(\s|$)/;
536
+ // U+FFFD needle built from its code point so this scanner never flags its own source.
537
+ const REPL = String.fromCharCode(0xfffd);
538
+ function scanEncoding(dir, hits) {
539
+ if (!fs.existsSync(dir)) return;
540
+ const st = fs.statSync(dir);
541
+ if (st.isFile()) {
542
+ let text;
543
+ try {
544
+ text = fs.readFileSync(dir, "utf8");
545
+ } catch (_) {
546
+ return; // unreadable not our concern here
547
+ }
548
+ const rel = path.relative(ROOT, dir).replace(/\\/g, "/");
549
+ // Reference U+FFFD via escape, never as a literal, so this scanner does not
550
+ // flag its own source.
551
+ if (text.includes(REPL)) hits.push(`${rel} (U+FFFD replacement char — corrupted bytes)`);
552
+ else if (MOJIBAKE.test(text)) hits.push(`${rel} (whitespace-flanked "???" — likely mangled dash/quote)`);
553
+ return;
554
+ }
555
+ for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
556
+ scanEncoding(path.join(dir, e.name), hits);
557
+ }
558
+ }
559
+ const encodingHits = [];
560
+ scanEncoding(path.join(ROOT, "package.json"), encodingHits);
561
+ scanEncoding(path.join(ROOT, "bin"), encodingHits);
562
+ scanEncoding(path.join(ROOT, "templates"), encodingHits);
563
+ for (const h of encodingHits) missing.push("encoding: " + h);
564
+
565
+ if (missing.length) {
566
+ console.error("\n❌ ORC package integrity check FAILED. Missing / incomplete:");
567
+ for (const m of missing) console.error(" - " + m);
568
+ console.error("\nDo NOT publish or push this tree. Likely cause: files were not");
569
+ console.error("committed (OneDrive sync can corrupt commits). Rebuild the repo");
570
+ console.error("OUTSIDE any cloud-synced folder, `git add -A`, verify, then push.\n");
571
+ process.exit(1);
572
+ }
573
+ console.log(`✅ ORC package OK — ${skillCount} skills, ${agentCount} agent files, cli present.`);