@orkestrel/scaffold 0.0.50 → 0.0.52

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 (66) hide show
  1. package/dist/bin/main.js +46 -17
  2. package/dist/bin/main.js.map +1 -1
  3. package/dist/host/AGENTS.md +2 -2
  4. package/dist/host/CLAUDE.md +3 -1
  5. package/dist/host/agents/orchestration.md +109 -274
  6. package/dist/host/agents/skills/enterprise-bootstrap/SKILL.md +12 -8
  7. package/dist/host/agents/skills/orkestrel-align-packages/SKILL.md +2 -2
  8. package/dist/host/agents/skills/orkestrel-debrief/SKILL.md +15 -11
  9. package/dist/host/agents/skills/orkestrel-debrief/references/instruction-audit.md +38 -12
  10. package/dist/host/agents/skills/orkestrel-debrief/references/retention.md +107 -0
  11. package/dist/host/agents/skills/{orkestrel-human-journey → orkestrel-prove-journey}/SKILL.md +1 -1
  12. package/dist/host/agents/skills/{orkestrel-human-journey → orkestrel-prove-journey}/agents/openai.yaml +1 -1
  13. package/dist/host/agents/skills/orkestrel-publish/SKILL.md +77 -0
  14. package/dist/host/agents/skills/orkestrel-publish/agents/openai.yaml +4 -0
  15. package/dist/host/agents/skills/orkestrel-publish/references/wave.md +97 -0
  16. package/dist/host/agents/skills/orkestrel-publish/references/window.md +95 -0
  17. package/dist/host/agents/templates/brief.md +157 -0
  18. package/dist/host/{codex/agents/claude.toml → agents/transports/claude.md} +16 -10
  19. package/dist/host/{claude/agents → agents/transports}/codex.md +13 -12
  20. package/dist/host/claude/agents/analyst.md +11 -10
  21. package/dist/host/claude/agents/application.md +6 -3
  22. package/dist/host/claude/agents/builder.md +11 -10
  23. package/dist/host/claude/agents/checker.md +20 -10
  24. package/dist/host/claude/agents/grok.md +8 -7
  25. package/dist/host/claude/agents/implementer.md +7 -4
  26. package/dist/host/claude/agents/orkestrel.md +27 -21
  27. package/dist/host/claude/agents/planner.md +13 -5
  28. package/dist/host/claude/agents/researcher.md +8 -7
  29. package/dist/host/claude/agents/reviewer.md +6 -4
  30. package/dist/host/claude/agents/scout.md +6 -7
  31. package/dist/host/claude/agents/sol.md +9 -8
  32. package/dist/host/claude/agents/verifier.md +6 -3
  33. package/dist/host/claude/rules/architecture.md +6 -6
  34. package/dist/host/claude/rules/documentation.md +2 -0
  35. package/dist/host/claude/rules/tests.md +4 -2
  36. package/dist/host/claude/rules/workspace.md +1 -1
  37. package/dist/host/claude/skills/enterprise-bootstrap/SKILL.md +12 -8
  38. package/dist/host/claude/skills/orkestrel-debrief/SKILL.md +1 -1
  39. package/dist/host/claude/skills/{orkestrel-human-journey → orkestrel-prove-journey}/SKILL.md +2 -2
  40. package/dist/host/claude/skills/orkestrel-publish/SKILL.md +12 -0
  41. package/dist/host/codex/agents/analyst.toml +3 -0
  42. package/dist/host/codex/agents/application.toml +3 -0
  43. package/dist/host/codex/agents/builder.toml +10 -7
  44. package/dist/host/codex/agents/checker.toml +14 -3
  45. package/dist/host/codex/agents/grok.toml +5 -2
  46. package/dist/host/codex/agents/implementer.toml +3 -2
  47. package/dist/host/codex/agents/opus.toml +4 -3
  48. package/dist/host/codex/agents/orkestrel.toml +14 -9
  49. package/dist/host/codex/agents/planner.toml +7 -5
  50. package/dist/host/codex/agents/researcher.toml +6 -4
  51. package/dist/host/codex/agents/reviewer.toml +4 -3
  52. package/dist/host/codex/agents/scout.toml +4 -1
  53. package/dist/host/codex/agents/verifier.toml +3 -2
  54. package/dist/host/codex/config.toml +1 -1
  55. package/dist/host/guides/scaffold.md +48 -44
  56. package/dist/host/manifest.json +132 -84
  57. package/dist/host/tests/config.test.ts +57 -0
  58. package/dist/src/core/index.cjs +455 -406
  59. package/dist/src/core/index.cjs.map +1 -1
  60. package/dist/src/core/index.d.cts +51 -48
  61. package/dist/src/core/index.d.ts +51 -48
  62. package/dist/src/core/index.js +455 -406
  63. package/dist/src/core/index.js.map +1 -1
  64. package/package.json +2 -2
  65. /package/dist/host/agents/skills/{orkestrel-human-journey → orkestrel-prove-journey}/references/captures.md +0 -0
  66. /package/dist/host/agents/skills/{orkestrel-human-journey → orkestrel-prove-journey}/references/layer.md +0 -0
@@ -13,7 +13,7 @@
13
13
  - External delegates, including Cursor and Codex models, have no exemption. Every dispatch restates the non-negotiables, applicable rules, guide or spec, and owned files. Every result receives independent review.
14
14
  - Before working, read in order:
15
15
  1. this file;
16
- 2. every applicable file in `.claude/rules/` from the rule map below;
16
+ 2. every applicable file in `.claude/rules/` from the Rule map section;
17
17
  3. every explicitly invoked or dispatch-named skill and the references it requires;
18
18
  4. `guides/README.md`, the matching guide or spec, and `ROADMAP.md` when present.
19
19
  - Rules state **how to write**. Guides and specs state **what to build** and the domain workflow. When they conflict, stop and surface the conflict.
@@ -115,7 +115,7 @@ npm run format:check → npm run lint:check → npm run check → npm run build
115
115
 
116
116
  ## Rule map
117
117
 
118
- Every file below is a normative extension of this root. Read every rule relevant to the files or concepts you touch. Path frontmatter only controls Claude's automatic loading.
118
+ Every file in the following table is a normative extension of this root. Read every rule relevant to the files or concepts you touch. Path frontmatter only controls Claude's automatic loading.
119
119
 
120
120
  | Rule | Governs |
121
121
  | -------------------------------- | ---------------------------------------------------------------------- |
@@ -28,7 +28,9 @@ follows it. This file adds only what Claude Code does differently, and cannot we
28
28
  and confirm from its journal that it reached Sol. A bridge driver that answers from its own engine
29
29
  collapses the round to one engine and its ruling still reads as normal.
30
30
  - Claude role frontmatter accepts Claude models only. Reach Grok through `grok`, and Sol through
31
- `analyst` and `codex`. Never put an external model in `model:`.
31
+ `analyst` and `sol`. Never put an external model in `model:`. Treat
32
+ `.agents/transports/codex.md` as the transport contract for those bridges, never as a
33
+ dispatchable role.
32
34
  - Claude Code hot-reloads edits to existing role files.
33
35
 
34
36
  ## Bench wiring
@@ -7,7 +7,7 @@ harness follows this file.
7
7
 
8
8
  Read in this order before acting:
9
9
 
10
- 1. The user's current instruction. It wins over everything below.
10
+ 1. The user's current instruction. It wins over every later item.
11
11
  2. `AGENTS.md` and the applicable `.claude/rules/*.md` files. They govern code substance.
12
12
  3. This file. It governs agent operation only and cannot weaken the coding contract.
13
13
  4. The dispatch-named skill and the references it requires.
@@ -16,6 +16,9 @@ Read in this order before acting:
16
16
  `CLAUDE.md`, `.codex/config.toml`, and `.cursor/rules/` are bridges. Each points here and adds
17
17
  only what its harness needs. None of them restates this file.
18
18
 
19
+ A line stays in this file when an executor who is not doing that thing is worse off without it. A
20
+ line becomes a skill when it fires on a named trigger and its reader is one agent at one moment.
21
+
19
22
  Every dispatch tells its executor to read every item after the user's current instruction before
20
23
  acting.
21
24
 
@@ -32,7 +35,8 @@ One workflow runs across all providers. Each engine has one job and never takes
32
35
  - Route each nontrivial implementation unit to Opus or Sol. Objective, constraint-heavy,
33
36
  mechanical-precision work goes to Sol. API-shape, naming, and documentation-voice work goes to
34
37
  Opus. Cursor Composer is not an implementation route, and no `composer` role exists.
35
- - Design and audit always run the adversarial pass.
38
+ - Design runs the adversarial pass. An audit runs the lanes its round names, with at least one whose
39
+ engine did not write the work.
36
40
 
37
41
  ## Orchestration by harness
38
42
 
@@ -93,9 +97,10 @@ Record the substitution.
93
97
  - Never assign Grok to either lane in Claude Code or Codex. If the remaining native engine is also
94
98
  unavailable there, the pass cannot run: stop and report rather than substituting Grok.
95
99
  - Grok takes every lane only in Cursor, and only when Opus 5 and Sol are both unavailable.
96
- - Treat a lane that returns no verdicts as a lane that did not run. A bench lane reporting that its
97
- driver executed and its engine was never reached is a dark bench, not a result. Record the bench
98
- dark from that report, re-run the lane on the substitute engine from the table above, and name in
100
+ - Treat a lane that returns no verdicts as a lane that did not run. Re-probe the bench before ruling
101
+ on why, per Bench laws rule "One lane at a time per bench". A bench lane reporting that its driver
102
+ executed and its engine was never reached is a dark bench, not a result. Record the bench dark
103
+ from that report, re-run the lane on the substitute engine from the preceding table, and name in
99
104
  the routing ledger which lane ran on which engine. Never accept a round with one lane empty.
100
105
  - Re-read bench liveness at dispatch, not at session start. A bench that probed live can be dark when
101
106
  the lane launches.
@@ -142,7 +147,7 @@ when the role file already pins it.
142
147
  | Design-fit review and audit | `reviewer` | `reviewer` | Opus 5 (native / bridge) |
143
148
  | Objective analysis and correctness audit | `analyst` | `analyst` | GPT-5.6 Sol (bridge / native) |
144
149
  | Nontrivial implementation (objective) | `sol` | `implementer` | GPT-5.6 Sol (bridge / native) |
145
- | Nontrivial implementation (subjective) | `implementer` | `implementer` route `opus` | Opus 5 (native / bridge) |
150
+ | Nontrivial implementation (subjective) | `implementer` | `opus` | Opus 5 (native / bridge) |
146
151
  | Bounded primary-source research | `researcher` | `researcher` | Grok → Luna → Sonnet |
147
152
  | Repository reconnaissance | `scout` | `scout` | Grok → Luna → Sonnet |
148
153
  | Mechanical conformance evidence | `checker` | `checker` | Grok → Luna → Sonnet |
@@ -153,6 +158,9 @@ when the role file already pins it.
153
158
 
154
159
  - A **bridge** role is a cheap driver whose only work is invoking another provider's CLI. It never
155
160
  implements, judges, or endorses the result.
161
+ - `implementer` names the harness's native implementation lane, so the token means Opus in Claude
162
+ Code and Sol in Codex. An engine-named bridge — `sol`, `opus` — names the other engine. Read a
163
+ role name against the harness you are running in, and state the engine anyway.
156
164
  - Give every role a file on both sides. The role file is where engine, effort, tools, permissions,
157
165
  and charter are pinned, and the tool allowlist is what makes the read-only floor real. A role
158
166
  with no file has nowhere to pin either.
@@ -162,11 +170,15 @@ when the role file already pins it.
162
170
  has stepped past Grok. Record which step you are on.
163
171
  - `orkestrel` stays native because it carries the package catalog in its own role file. Sending its
164
172
  job to a bench means shipping that catalog across, which costs more than the bench saves.
165
- - `codex` is the shared Sol transport contract, not a route. `analyst` and `sol` are the named
166
- bridges; both bind that contract by reference and pin only their route and sandbox.
167
- - Mirroring is by work class, not filename. A transport contract is provider-specific:
168
- `.claude/agents/codex.md` carries the Sol transport on the Claude side, `.codex/agents/claude.toml`
169
- the Opus transport on the Codex side, and each side's bridges bind their own by reference.
173
+ - A transport contract lives in `.agents/transports/`, not in an agents directory. A harness lists
174
+ its dispatchable agents from that directory, so a contract that is never dispatched sits outside
175
+ it. `.agents/transports/codex.md` is the shared Sol transport contract and
176
+ `.agents/transports/claude.md` the shared Opus transport contract. Neither is a route: `analyst`
177
+ and `sol` are the named Sol bridges, `planner`, `reviewer`, and `opus` the named Opus bridges, and
178
+ each binds its own contract by reference and pins only its route and sandbox.
179
+ - Mirroring is by work class, not filename. A transport contract is provider-specific: the Codex
180
+ contract carries the Sol transport the Claude-side bridges follow, the Claude contract carries the
181
+ Opus transport the Codex-side bridges follow, and each side's bridges bind their own.
170
182
  - Opus and Sol roles use high effort. Native cheap-tier roles use low or medium. Bridge drivers use
171
183
  the cheapest tier that can run a CLI.
172
184
  - Never route orchestration or acceptance across a bridge.
@@ -288,13 +300,14 @@ owns each bench's exact probe.
288
300
 
289
301
  The local steps still run, because they route the recovery rather than decide the verdict: an
290
302
  unresolved CLI is an install problem, a failed authentication-state check starts the login ladder
291
- below, and a bench that passes both and still cannot round-trip is dark for a reason no local check
292
- can see. Record every dark bench with its fallback and the lane substitution it forces, and never
293
- absorb one silently. A readiness script reports readiness and performs no model call, so the round
294
- trip belongs to the Orchestrator's own probe or to the bridge carrying the unit, never to the hook.
295
- Liveness also expires: a dispatch that fails on quota, model access, or the network is a fresh
296
- liveness result rather than a unit-level fault, so record the bench dark from there and re-plan the
297
- lane instead of re-dispatching against a session-start answer that no longer holds.
303
+ in Recovering a dark bench, and a bench that passes both and still cannot round-trip is dark for a
304
+ reason no local check can see. Record every dark bench with its fallback and the lane substitution
305
+ it forces, and never absorb one silently. A readiness script reports readiness and performs no
306
+ model call, so the round trip belongs to the Orchestrator's own probe or to the bridge carrying
307
+ the unit, never to the hook. Liveness also expires: a dispatch that fails on quota, model access,
308
+ or the network is a fresh liveness result rather than a unit-level fault, so record the bench dark
309
+ from there and re-plan the lane instead of re-dispatching against a session-start answer that no
310
+ longer holds.
298
311
 
299
312
  1. **Absorb.** Dispatch `grok` for terrain, prior art, and the reading the decision needs. In an
300
313
  Orkestrel repo dispatch `orkestrel` alongside it for live package state. Skip only when the
@@ -319,10 +332,12 @@ lane instead of re-dispatching against a session-start answer that no longer hol
319
332
  criterion discovered at integration is a successor brief routed to a writer, never an
320
333
  integration edit.
321
334
  5. **Audit adversarially.** Audit every nontrivial implementation with at least one lane whose
322
- engine did not write it. Run another lane when the first returns FAIL, when the subject is a
323
- rendered or externally driven surface, or when the unit's claims span both correctness and
324
- shape. Dispatch `checker` when the acceptance criteria are mechanical counts, paths, parity
325
- rows, scope honesty. Record in the round's verdict file when a lane or the checker did not run.
335
+ engine did not write it: `reviewer` for the subjective lane and `analyst` for the objective lane,
336
+ the way step 2 names its lanes. Run the second lane when the first returns FAIL, when the subject
337
+ is a rendered or externally driven surface, or when the unit's claims span both correctness and
338
+ shape. Dispatch `checker` in addition when the acceptance criteria are mechanical counts,
339
+ paths, parity rows, scope honesty — never in place of a lane. Record in the round's verdict file
340
+ when a lane or the checker did not run.
326
341
  - State the audit's subject as numbered falsifiable claims and require per-claim verdicts with
327
342
  evidence, per the Falsification law in `.claude/rules/quality.md` and the `orkestrel-falsify`
328
343
  value set, unless the dispatch names a different skill that fixes another.
@@ -395,7 +410,9 @@ The harness bridge names the concrete mechanism for each of these.
395
410
 
396
411
  - Write the brief to a file under `tmp/`, named for its unit, before launching the unit, whatever
397
412
  engine executes it. A brief composed only inside a launch argument cannot be corrected, resumed,
398
- or re-run once that call ends.
413
+ or re-run after that call ends. A native unit's pair is `tmp/units/<unit>-brief.md` and
414
+ `tmp/units/<unit>-report.md`. A bench unit's pair sits under the bench directory its role file
415
+ names, beside the journal.
399
416
  - Write the unit's returned report in the SAME action that commits its code, never afterwards. A
400
417
  commit message states what changed; the report states what the unit measured, what it decided, what
401
418
  it could not close, and which of its own claims it flagged. An auditor's subject is the report,
@@ -405,6 +422,11 @@ The harness bridge names the concrete mechanism for each of these.
405
422
  - Amend a brief on re-run rather than restating it. A mid-campaign correction produces a successor
406
423
  file recording what changed and why, and the original stays. A fix round's brief names the
407
424
  findings it carries and where each came from.
425
+ - Name a corrected unit's effective brief and report and the pair they supersede before that unit
426
+ integrates. A unit whose correction landed as a serial patch or a direct reconciliation, with no
427
+ successor pair on disk, cannot be re-run from what the campaign kept.
428
+ - Write the round's verdict to `.orkestrel/<package>/<unit>-audit-verdict.md`. That file is where
429
+ the audit step records a lane or a checker that did not run.
408
430
  - Read the copy the executor will open, not the one you wrote. A brief written in the orchestrator's
409
431
  repository and staged into the subject's checkout so a `-C` invocation can reach it is a second
410
432
  file, and staging can rewrite a path or drop a clause. The executor rules on what it opens, so a
@@ -433,7 +455,8 @@ The harness bridge names the concrete mechanism for each of these.
433
455
  - Put every campaign artifact in the **orchestrator's** repository under `.orkestrel/<package>/`,
434
456
  named for the package the campaign is about.
435
457
  - Give a campaign spanning several packages one shared `.orkestrel/campaign/` folder instead, so the
436
- wave's plan, ledger, and verdicts sit together rather than split across the packages they rule on.
458
+ wave's plan, routing ledger, and verdicts sit together rather than split across the packages they
459
+ rule on.
437
460
  - Never put them in the package they are about. A published package's tree is its product.
438
461
  - Claim nothing outside `.orkestrel/` unless Orkestrel scaffold mandates it. Everything Orkestrel
439
462
  owns in a consumer's tree lives beneath that folder, so a convention can be settled there without
@@ -441,40 +464,14 @@ The harness bridge names the concrete mechanism for each of these.
441
464
  - Keep the campaign narrative and every ruling in the durable artifact that owns it — the guide for
442
465
  product truth, a rule or role file for process truth, the commit message for the decision itself.
443
466
  Use `ROADMAP.md` only where the repository already keeps one.
444
- - Prefer a mechanism that recomputes a fact over a document that records it. A ledger of live state
445
- is stale from the moment it is written, and the next campaign reads it as current. Where the fact
446
- can be derived, derive it: the fleet's publish order lives in the catalog table `scaffold catalog`
447
- regenerates, not in a written order anyone has to remember to update.
448
- - Prune the campaign folder in a commit at acceptance. The tree ends clean and the record stays
449
- recoverable by hash. Git history is the archive; the working tree is the workspace.
450
-
451
- ### Before you prune
452
-
453
- Pruning is deletion, so it needs the same evidence as any other destructive step. Run these
454
- checks, and prune only when every one closes.
455
-
456
- 1. **Carry check.** List every item the folder leaves open — a defect, a measurement to re-take, a
457
- deferred decision, a withdrawn claim, an unmet acceptance condition. Each ends the check with a
458
- carrier: a commit that closed it, a live brief that owns it, or an explicit drop on the record.
459
- An item with no carrier blocks the prune. Read the register files for this — the plan, the
460
- readiness grade, the carry ledger, the triage — not every brief and report in the folder.
461
- 2. **Promotion check.** Rule on each remaining file by what it asserts. Product truth goes to the
462
- guide, where the parity gate reaches it. A process law goes to the rule or contract file that
463
- owns it. A decision goes to the commit message that made it, which is where it already is.
464
- Everything else is process diary and prunes.
465
- 3. **Measurement check.** A number the guide carries out of the folder carries the date it was
466
- taken. A measurement whose date the folder does not record is re-taken or dropped, never copied.
467
- 4. **Orientation check.** A cross-session orientation document — a handoff, a package-root narrative
468
- file, a session log — is not a further category. It duplicates the guide for product truth and
469
- the contract for process truth, it is gated by nothing, and it drifts. Dissolve it into the
470
- artifacts that own it and delete it.
471
-
472
- A section recording live state — adopter republish status, installed version tables, what a sibling
473
- repository was doing that week — prunes with no promotion. It was stale when it was written, and
474
- promoting it publishes the staleness.
475
-
476
- Write the prune commit's message as the promotion record: what moved, and where each part landed.
477
- That message is what makes the deletion recoverable in practice rather than only in principle.
467
+ - Prefer a mechanism that recomputes a fact over a document that records it. A document recording
468
+ live state is stale from the moment it is written, and the next campaign reads it as current.
469
+ Where the fact can be derived, derive it: the fleet's publish order lives in the catalog table
470
+ `scaffold catalog` regenerates, not in a written order anyone has to remember to update.
471
+ - Prune the campaign folder in a commit at acceptance. Git history is the archive; the working tree
472
+ is the workspace. `.agents/skills/orkestrel-debrief/references/retention.md` owns the procedure
473
+ the checks that close the prune, the artifact locations it sweeps, and the promotion record
474
+ the commit message carries. Run it before deleting anything.
478
475
 
479
476
  ### Required sections
480
477
 
@@ -516,90 +513,44 @@ That message is what makes the deletion recoverable in practice rather than only
516
513
 
517
514
  ### Check the brief before you send it
518
515
 
519
- Run these checks on every brief. Each is cheap, and skipping one costs a full dispatch cycle that
520
- produces no work, because a unit given a brief that is internally consistent and factually wrong is
521
- right to stop.
522
-
523
- - Name the executor that will actually read the brief, and write its transport for that reader. The
524
- same unit goes either to a bridge driver that invokes a bench CLI or to the bench engine already
525
- running inside that CLI, and the sections that are essential for the first are nonsense to the
526
- second: a brief telling an engine to launch its own CLI fails on arrival. Describe the route the
527
- reader takes, not the route the work travels.
528
- - Paste the command and its output for every factual claim — paths, counts, registrations, file
529
- existence. A description of a result is not the result, and a name recalled beside a counted set
530
- is a guess. A claim about a search names the scope the search covered: a search bounded to one
531
- directory proves something about that directory and nothing about the rest of the tree, and a
532
- filtered set proves something about the filter's membership rule and nothing about the population
533
- it was drawn from. Where several artifacts state the fact, check it against the code rather than
534
- against the other copies: agreement proves one copy was taken from another.
535
- - Take every measurement under the conditions the unit will run in, or have the unit take it. A
536
- number measured in your environment and asserted as a criterion is unreachable when the
537
- executor's sandbox denies what yours permitted, and no edit to the owned files can close it.
538
- Where the unit is better placed to measure than you are, have it take the measurement before doing
539
- anything else and fix the criterion to the property you want rather than to the number you saw.
540
- - Read the acceptance criteria against the off-limits list, line by line. Every criterion closes
541
- using owned files alone. A criterion that needs an off-limits file gets that file granted or gets
542
- struck. A file the change will break that appears in neither list is an unscoped file; grant it or
543
- strike the criterion.
544
- - Give a small unrelated obligation its own unit. Ride it along in a large one and its scope error
545
- blocks the primary work, which is a whole unit lost to a detail.
546
- - Never make a timing-sensitive or whole-suite gate result a criterion for a unit that runs inside its
547
- own exec. The exec is load, so the unit cannot take that reading validly however carefully it
548
- isolates, and a criterion it cannot close either stalls it or invites it to explain the failure away.
549
- Name the gate as an observation the unit reports with both readings, and take the authoritative run
550
- yourself after the unit exits, per **Writing concurrency**'s rule on re-running a timing or
551
- resource failure alone. A scoped run over the unit's own
552
- owned files stays a legitimate criterion.
553
- - Order the criteria so an unreachable one cannot hide the others. A deviation contract fires on the
554
- first criterion the unit cannot close and stops it there, so an unreachable criterion placed ahead
555
- of a typecheck or a lint criterion skips that gate entirely and the unit ships a defect its own
556
- brief would have caught. Put the cheap non-timing gates first, and never let a whole-suite result
557
- gate a scoped one. Cheap-first has one exception: where the change edits a file the repository
558
- vendors or otherwise digests, the regeneration step precedes every gate that reads the generated
559
- artifact. A parity or inventory gate ordered ahead of it cannot pass, because the edit restaled the
560
- digest that gate reads, and the unit stops on a criterion its own work already satisfied.
561
- - Ask what the change will do to the facts you just measured. A criterion fixed to a measured set is
562
- unreachable if the change alters that set, and a file marked off-limits is wrong if the change
563
- writes to it. Measure the state the unit will finish in, not only the state it starts from.
564
- - Grant both halves of a template change where the package generates the configuration it runs on.
565
- The template and the repository's own materialized copy of that template's output are one change:
566
- adding a fixed Vitest project moves the template, `vite.config.ts`, `package.json`, and the proof
567
- file that project includes. Withhold either half and no edit to the owned files can reach the
568
- gates the brief requires.
569
- - Name the property the unit must change, and stop. A consequence you expect to follow from it is an
570
- observation for the report, not a criterion. Bundled together, the unit can satisfy neither and
571
- cannot tell which half you meant.
572
- - Keep the brief's control identifiers inside the brief. Label controls so the brief's own table can
573
- be read, and say in the brief that a test is named for what it proves, never for the control that
574
- specified it. An implementer writing one test per control otherwise takes the label as the obvious
575
- name, and a private brief vocabulary becomes a permanent test name.
516
+ Fill `.agents/templates/brief.md`, which carries the named scope rows and the worked reason behind
517
+ each check. Then run this checklist against what you filled.
518
+
519
+ - Name the executor that will open the brief, and write the transport for that reader. A bridge
520
+ driver and the bench engine inside that driver's CLI need opposite instructions.
521
+ - Paste the command and its output behind every factual claim paths, counts, registrations, file
522
+ existence. Name the scope any search covered, and check a fact against the code rather than
523
+ against another artifact that states it.
524
+ - Take every measurement under the conditions the unit runs in, or have the unit take it before
525
+ doing anything else.
526
+ - Ask what the change does to every fact you measured, and fix each criterion to the state the unit
527
+ finishes in.
528
+ - Scope the change by the files its result makes **false**, not by the files that declare the thing
529
+ changing: the test asserting the reversed behaviour, the fixture carrying the raised value, the
530
+ golden digest over generated output, the consumer script naming the removed union member.
531
+ - Derive that set by running the suite. Where you cannot run it, name the search's bound in the
532
+ brief so the unit re-derives the set.
533
+ - Grant a behaviour with the tests that pin it, a constant with every fixture and expectation
534
+ derived from it, and a template change with the materialized copy the package generates from it.
535
+ - Read each criterion against the off-limits list, line by line. Grant the file a criterion needs or
536
+ strike that criterion. A file the change will break that appears in neither list is unscoped.
537
+ - Scope a unit that changes a mechanism to own the prose describing it. Where a brief scopes that
538
+ prose out, name the carrier and dispatch it before the change ships.
539
+ - Give a small unrelated obligation its own unit.
540
+ - Name the property the unit must change, and stop. Record an expected consequence as an
541
+ observation, never as a second criterion.
542
+ - Order the criteria cheap-first, so an unreachable one cannot hide a typecheck or a lint criterion
543
+ behind it. Where the change edits a file the repository vendors or digests, the regeneration step
544
+ precedes every gate that reads the generated artifact.
545
+ - Never make a timing-sensitive or whole-suite gate result a criterion for a unit running inside its
546
+ own exec. Name it as an observation the unit reports with its own reading, and take the
547
+ authoritative run yourself after the unit exits. A scoped run over the unit's owned files stays a
548
+ legitimate criterion.
576
549
  - Check the brief's output mechanism and its verification method against the executor's tool
577
- allowlist. A read-only role cannot write a report file, cannot write a probe, and cannot run a
578
- sandbox that writes, so naming any of those stops the unit on arrival over a detail the allowlist
579
- already settled. Where a read-only lane needs executed evidence, produce it separately and hand it
580
- over: the Orchestrator supplies the evidence and the lane rules on it. When the evidence a lane
581
- needs is a `prove` verdict and the lane's allowlist omits that tool, the Orchestrator takes the
582
- call outside the lane's live interval and hands over the complete rendered verdict.
583
- - Scope a change by the files its result makes **false**, not by the files that declare the thing
584
- changing. Counting importers finds only part of that set. A test asserting the behaviour being
585
- reversed, a fixture carrying a value being raised, a golden digest over generated output, and a
586
- consumer script naming a union member being removed each go false without importing anything new,
587
- and a brief scoped to the declaration alone sends the unit into a failure in a file it cannot edit.
588
- The unit is then right to stop, and a whole dispatch cycle produces no work.
589
- Ask of every criterion: what asserts the state this change ends? Own every answer, or strike the
590
- criterion. Grant a behaviour and the tests that pin it together; grant a constant and every fixture
591
- and expectation derived from it together.
592
- - Find that set by running the suite, not by searching for the assertion's shape. A search returns
593
- the assertions that look right and cannot say which ones the change actually reaches: a fixture
594
- that never builds the directory the new code reads is a match the change cannot touch, and a
595
- fixture that reaches it through a path the search never named is a miss. Both errors appear in one
596
- grep. Where the change is already written somewhere — a scratch copy, an earlier unit, a probe —
597
- run the suite against it and read the failures. Where it is not, name the search's bound in the
598
- brief so the unit re-derives the set instead of trusting it.
599
- - Scope a unit that changes a mechanism to own the prose describing that mechanism: the comment
600
- beside the code it edits, and the guide passage stating the behaviour it moves. Where a brief
601
- scopes that prose out so writers do not share a file, name the carrier that takes it and dispatch
602
- that carrier before the change ships.
550
+ allowlist. A read-only lane writes no report file and runs no probe, so hand it the rendered
551
+ evidence instead.
552
+ - Keep the brief's control identifiers inside the brief, and say in the brief that a test is named
553
+ for what it proves rather than for the control that specified it.
603
554
 
604
555
  ### Carry every finding
605
556
 
@@ -740,7 +691,12 @@ transport.
740
691
  3. **Tracked, never loose.** Register every bench unit in the session task registry at launch with
741
692
  its subject, journal path, and session id, and complete it there at acceptance. "What is
742
693
  running" always has a first-class answer instead of a recollection of a command.
743
- 4. **A bench sandbox spawns a child and denies that child's child.** Under `workspace-write` a bench
694
+ 4. **One lane at a time per bench.** Launch one `grok` lane at a time and queue the rest. Lanes past
695
+ that starve the bench: it accepts each launch and the lanes come back empty, which reads as the
696
+ work failing. Re-probe before ruling on an empty lane. A probe that round-trips while the lanes
697
+ return empty names starvation, not darkness — cut the concurrency and re-run the lane, rather
698
+ than recording the bench dark and substituting an engine.
699
+ 5. **A bench sandbox spawns a child and denies that child's child.** Under `workspace-write` a bench
744
700
  exec runs a test suite and spawns children normally, and every operation one level deeper fails:
745
701
  a grandchild process is denied `EPERM`, and a nested `npm install` is denied the same way. So a
746
702
  proof needing a process tree, a tree-kill, a detached group, or an installed package cannot be
@@ -774,7 +730,7 @@ transport.
774
730
  **When a brief assigns a bench unit a path outside the obvious source tree, name the write limit
775
731
  in the brief.** If the sandbox rejects the patch, the unit stops and reports the rejection. Never
776
732
  find another write mechanism.
777
- 5. **Ephemeral streams, durable records.** A journal proves a bench is alive and recovers an
733
+ 6. **Ephemeral streams, durable records.** A journal proves a bench is alive and recovers an
778
734
  interrupted session. Keep journals under `tmp/`, never commit them, and sweep them at acceptance
779
735
  after the final gate evidence is recorded. Durable retention — brief, distillate, verdict,
780
736
  instrument, acceptance evidence — is owned by **Dispatch anatomy**; this rule owns only the
@@ -801,7 +757,14 @@ the conversation.
801
757
 
802
758
  A publish chain is a long-running command, so every law under **Long-running commands** binds it:
803
759
  write the chain to a file, detach it with `setsid`, and confirm the previous one is dead before
804
- starting another.
760
+ starting another. Publish serially, because concurrent publishes collide on the authentication
761
+ handshake and fail each other.
762
+
763
+ The release itself runs from the `orkestrel-publish` skill: the wave's per-repo visit and its bump
764
+ triggers in `references/wave.md`, and the preparation order, the login approval, and the
765
+ five-minute upload window in `references/window.md`. Load the skill when the user asks for a
766
+ release, and follow it there rather than reconstructing the procedure here. What remains in this
767
+ section binds an executor who is not publishing.
805
768
 
806
769
  ### Fixing a dependency before it publishes
807
770
 
@@ -846,8 +809,8 @@ either publishes packages nobody needed to publish or leaves a consumer pinned t
846
809
  whitespace-only differences; a superfluous diff (formatting, blank lines, map noise) moves
847
810
  nothing and obliges nothing. A material diff — tokens, declarations, logic — means the published
848
811
  surface moved — a forced `src` or `app` edit and a toolchain-changed emit both surface here — so
849
- that package bumps and publishes on its own account, and its own dependents follow the runtime
850
- rule above.
812
+ that package bumps and publishes on its own account, and its own dependents follow the preceding
813
+ runtime rule.
851
814
 
852
815
  Every package is `0.0.x`, where a caret pins one exact release. A dependent therefore sees a new
853
816
  version only after it re-pins and republishes, so the fleet publishes in topological layer order
@@ -885,134 +848,6 @@ and propagates as files rather than as a cascade.
885
848
  target. Scope a fleet-wide refactor to the files each target owns, and record the vendored
886
849
  exclusion in the brief rather than letting each unit rediscover it.
887
850
 
888
- ### The release wave
889
-
890
- Close a fleet-wide "everything on latest" goal as a release wave in layer order: visit every repo
891
- once per round with one procedure, publish each layer in one window, and only then prepare the next.
892
-
893
- - The visit, in order: re-pin the target's `@orkestrel/scaffold` devDependency and install, so the
894
- overwrite runs the current vendored host; `scaffold overwrite`; force-verify every `@orkestrel`
895
- range against a registry sweep taken after the previous layer published; full install; mutating
896
- `format` to converge generated writes; the quality gates; the material-dist comparison against the
897
- published tarball.
898
- - Bump on either trigger: the rebuilt dist differs materially from the published tarball, or the
899
- final runtime dependency set differs from the published packument. Test the final set against the
900
- packument, never "did my step move a pin" — overwrite's `declare` re-pins before any later check,
901
- so the step-local reading reports nothing moved while the manifest surface did. A re-pinned
902
- runtime range is published surface: without the bump a consumer installs duplicate copies of the
903
- moved dependency.
904
- - A dist built before the version bump is the release artifact wherever the bump edits no emitted
905
- byte. Check that per package rather than assuming it: a package that imports its own
906
- `package.json` version into published code emits that version, so its pre-bump dist is stale the
907
- moment the version moves. Rebuild after the bump there, and pack from the rebuilt tree. Because
908
- `npm publish --ignore-scripts` skips `prepack`, that rebuild is the operator's step, not the
909
- publish's.
910
- - Refresh the registry evidence between layers and derive each round's pins from it. A pin can only
911
- name a version the registry already serves, so a dependency shipping in the same window keeps the
912
- resolvable previous pin and takes its dev-only re-pin after the window closes.
913
- - Run visits in parallel slices of disjoint repos, each slice strictly serial inside itself,
914
- reporting per-target. Refuse a failed target, name it, repair, and re-run it alone.
915
-
916
- ### Preparing
917
-
918
- 0. **An unpublished package's first version is `0.0.1`.** Do not bump it before that first publish.
919
- The registry has nothing to serve, so there is no version to move away from, and bumping produces
920
- a package whose history starts at a number nothing explains.
921
- 1. **Bump from what the registry serves, not from the local manifest.** A repository's `version`
922
- can sit a release behind what was published from another checkout, and bumping that produces a
923
- version the registry already holds, which fails on upload after the whole gate chain has run.
924
- Read the registry first.
925
- 2. **Prepare a whole layer before authenticating.** Bump each version, re-pin every `@orkestrel`
926
- range to what the registry serves now, install, and run the package's own `prepublishOnly` to
927
- green. Move any self-pin in source with the manifest. Commit and push before the window opens.
928
- 3. **Prepare the next layer only after this one is on the registry.** A dependent's new pin cannot
929
- install until the version it names exists, so preparation and publication interleave and cannot
930
- be batched ahead.
931
-
932
- The window is for uploads. Every gate, build, install, and commit happens outside it, which is what
933
- makes `--ignore-scripts` the right flag at publish time: the artifact was already proved, and the
934
- flag is what stops the gate chain running a second time inside the five minutes.
935
-
936
- ### Reaching the approval
937
-
938
- - Launch the login chain only when the user has signalled they are at the keyboard and will click
939
- within ten minutes. An approval URL expires unclicked in about ten to fifteen minutes, and an
940
- overnight gap expires the session credential with it.
941
- - Run `npm login` before any publish. `npm publish` does not open the browser flow: unauthenticated
942
- it returns `E404` on `PUT`, which reads as a missing package rather than a missing credential.
943
- - Pass `--browser=false` to `npm login` and to every `npm publish`. Without it npm prints
944
- `Press ENTER to open in the browser...` and blocks. Never answer that prompt with a newline: the
945
- web flow consumes the newline on a later read, drops to a legacy `Username:` prompt, and exits
946
- **zero** without authenticating. With the flag npm prints the URL and polls, and stdin stays
947
- untouched.
948
- - Hold stdin open and write nothing to it. Use a fifo held open by a long `sleep`. EOF drops npm to
949
- the same legacy prompt a stray newline does.
950
- - A login log showing the spinner and then a legacy `Username:` prompt is an expired attempt, not a
951
- prompt to answer: kill it by process id and mint a fresh flow.
952
- - Run the login and every publish under `script -qfc '<command>' <log>`. npm offers the approval only
953
- when it sees a TTY; without one it fails `EOTP` with no way to answer.
954
- - Git Bash on Windows ships no `script` binary, so the upload step there is operator-driven: prepare
955
- the layer, prove the gates, surface the exact `npm publish` command, and the operator runs it in a
956
- real terminal. Everything before and after the upload — bumps, re-pins, gates, registry reads —
957
- stays with the Orchestrator. The fifo stdin law still binds on that host.
958
- - Expect an approval for each stage. `npmjs.com/login/cli/<id>` authenticates the session;
959
- `npmjs.com/auth/cli/<id>` authorizes the publish and opens the five-minute window. Tell the user
960
- both are coming, or the second link reads as the first having failed.
961
- - Confirm authentication with `npm whoami`, never with an exit code. The legacy fallthrough exits
962
- zero.
963
- - Re-probe `whoami` immediately before opening the window. A stored credential expires mid-session,
964
- so a session-start answer does not hold.
965
- - Surface each approval URL the moment it appears in the log, and take the **last** one in log order.
966
- npm mints a new URL whenever an attempt restarts, and the log accumulates every one, so a URL
967
- chosen by sorting rather than by position is already dead when the user opens it. Read it out of
968
- the journal in the foreground and surface it before arming any watcher: a watcher-based relay can
969
- fail silently, and its silence is indistinguishable from a chain that has not reached the URL yet.
970
- Relay the URL as plain text. A decorated link did not render for the operator, who then had nothing
971
- to click while the window ran down.
972
- - Re-read the log before treating an approval as failed. The chain is usually still alive on a newer
973
- URL, so surface that one rather than relaunching.
974
- - A `404` on an approval URL usually means the publish already succeeded and consumed it. Read the
975
- registry before calling it a failure.
976
- - Say that approving the publish one opens a five-minute window covering the rest of the layer.
977
-
978
- ### Spending the window
979
-
980
- - The window opens when the user approves, not when the first publish starts. Open each layer with
981
- one package: publish it alone, surface its approval URL the moment the journal shows it, and
982
- confirm the upload from the registry before starting the rest. Then chase the remaining uploads
983
- back-to-back in one process with no gap — an upload started within seconds of an approval
984
- frequently rides that approval, and each one that does not mints its own URL. Relay every new URL
985
- to the user the moment it appears, through a journal watcher, and never pause the chain to wait
986
- for a click: a poll outlives the relay.
987
- - A click on a superseded URL poisons the live attempt — the current poll fails
988
- `403 Forbidden - GET /-/v1/done` mid-flight. Tell the user to click only the newest URL. After
989
- any such 403, confirm no publish process is live, then mint one fresh attempt.
990
- - Publish serially. Concurrent publishes collide on the auth handshake and fail each other.
991
- - **Never retry a publish that is still waiting for its authorization.** Each `npm publish` attempt
992
- mints a new `authId` and invalidates the previous one, so a retry loop makes the URL a moving
993
- target the user cannot approve in time. The abandoned poll then reports
994
- `403 Forbidden - GET /-/v1/done?authId=…`, which reads as a permissions problem and is the
995
- abandoned attempt colliding with the live one. Publish the first package of a layer with exactly
996
- one attempt.
997
- - Retry only an upload that failed **inside** an already-open window. `EOTP` there is intermittent
998
- contention rather than the window closing: retry about three times, and retry a failed set once the
999
- layer ends. Packages have landed on the third attempt and on a later pass with no new approval.
1000
- These are different failures wearing similar codes; a retry fixes in-window contention and causes
1001
- the moving approval target.
1002
- - Expect a large layer to outlast one window. Size batches to what uploads in five minutes and tell
1003
- the user how many approvals to expect, rather than discovering it mid-run.
1004
- - Read the result from the registry, not from an exit code: a piped `npm publish` reports the exit
1005
- status of the pipeline, and a CDN read straight after a publish can still serve the previous
1006
- version.
1007
- - A first publish creates the packument and can serve 404 for minutes after success. For a package
1008
- with no prior version treat 404 as pending, not failed, and re-read on an interval before
1009
- reporting either way. A bump serving the old version is CDN lag, same rule.
1010
- - Rule on a pack-time manifest-rewriting warning by fetching the registry's copy of the manifest,
1011
- never by the warning's own text.
1012
- - Re-read the registry before telling the user a package failed. A chain still running, a retry that
1013
- landed, and CDN lag all produce a failure reading that the registry contradicts, and a false
1014
- failure report costs a needless approval and a needless republish.
1015
-
1016
851
  ## Acceptance laws
1017
852
 
1018
853
  - No writer's and no external engine's self-assessment is authoritative.
@@ -2,14 +2,18 @@
2
2
  name: enterprise-bootstrap
3
3
  description: >-
4
4
  Design and build distinctive, production-grade user interfaces with Bootstrap
5
- 5.3 and intentional frontend craft. Use for ANY UI work creating, restyling,
6
- reviewing, or extending pages, screens, components, layouts, app shells,
7
- dashboards, admin panels, SaaS tools, data tables, filter bars, forms,
8
- wizards, navigation, modals, empty/loading/error states, dark mode, marketing
9
- surfaces whenever the task touches HTML/CSS/visual design, mentions
10
- Bootstrap or its components, or must look professional and avoid templated
11
- defaults. Covers aesthetics, typography, color modes, design tokens,
12
- accessibility (WCAG 2.2 AA), responsive layout, and enterprise app patterns.
5
+ 5.3 and intentional frontend craft, in any host project and on any stack. Use
6
+ for Bootstrap user-interface work creating, restyling, or
7
+ extending pages, screens, components, layouts, app shells, dashboards, admin
8
+ panels, SaaS tools, data tables, filter bars, forms, wizards, navigation,
9
+ modals, empty/loading/error states, dark mode, marketing surfaces whenever
10
+ the task touches HTML/CSS/visual design, mentions Bootstrap or its components,
11
+ or must look professional and avoid templated defaults. Covers aesthetics,
12
+ typography, color modes, design tokens, accessibility (WCAG 2.2 AA),
13
+ responsive layout, and enterprise app patterns. The `orkestrel-polish-surface`
14
+ skill owns a requested verdict, round, or campaign over a surface that already
15
+ renders, including a review that changes nothing. In that campaign's fix
16
+ units, use this skill for Bootstrap craft.
13
17
  ---
14
18
 
15
19
  # Enterprise Bootstrap
@@ -10,8 +10,8 @@ description: Audit and improve how two or more Orkestrel packages, or their core
10
10
  Read the current authority in this order:
11
11
 
12
12
  1. `AGENTS.md` and applicable `.claude/rules/*.md`.
13
- 2. The `integration.md` and `fleet.md` references selected below.
14
- 3. `.agents/orchestration.md` for orchestration.
13
+ 2. `.agents/orchestration.md` for orchestration.
14
+ 3. The `integration.md` and `fleet.md` references selected later in this section.
15
15
  4. Relevant package guides, `guides/scaffold.md`, and the configured Orkestrel specialist.
16
16
 
17
17
  Explicit user scope wins.