@orkestrel/scaffold 0.0.51 → 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 (55) hide show
  1. package/dist/host/CLAUDE.md +3 -1
  2. package/dist/host/agents/orchestration.md +99 -266
  3. package/dist/host/agents/skills/enterprise-bootstrap/SKILL.md +12 -8
  4. package/dist/host/agents/skills/orkestrel-align-packages/SKILL.md +2 -2
  5. package/dist/host/agents/skills/orkestrel-debrief/SKILL.md +15 -11
  6. package/dist/host/agents/skills/orkestrel-debrief/references/instruction-audit.md +38 -12
  7. package/dist/host/agents/skills/orkestrel-debrief/references/retention.md +107 -0
  8. package/dist/host/agents/skills/{orkestrel-human-journey → orkestrel-prove-journey}/SKILL.md +1 -1
  9. package/dist/host/agents/skills/{orkestrel-human-journey → orkestrel-prove-journey}/agents/openai.yaml +1 -1
  10. package/dist/host/agents/skills/orkestrel-publish/SKILL.md +77 -0
  11. package/dist/host/agents/skills/orkestrel-publish/agents/openai.yaml +4 -0
  12. package/dist/host/agents/skills/orkestrel-publish/references/wave.md +97 -0
  13. package/dist/host/agents/skills/orkestrel-publish/references/window.md +95 -0
  14. package/dist/host/agents/templates/brief.md +157 -0
  15. package/dist/host/{codex/agents/claude.toml → agents/transports/claude.md} +16 -10
  16. package/dist/host/{claude/agents → agents/transports}/codex.md +13 -12
  17. package/dist/host/claude/agents/analyst.md +11 -10
  18. package/dist/host/claude/agents/application.md +6 -3
  19. package/dist/host/claude/agents/builder.md +11 -10
  20. package/dist/host/claude/agents/checker.md +20 -10
  21. package/dist/host/claude/agents/grok.md +8 -7
  22. package/dist/host/claude/agents/implementer.md +7 -4
  23. package/dist/host/claude/agents/orkestrel.md +22 -16
  24. package/dist/host/claude/agents/planner.md +13 -5
  25. package/dist/host/claude/agents/researcher.md +8 -7
  26. package/dist/host/claude/agents/reviewer.md +6 -4
  27. package/dist/host/claude/agents/scout.md +6 -7
  28. package/dist/host/claude/agents/sol.md +9 -8
  29. package/dist/host/claude/agents/verifier.md +6 -3
  30. package/dist/host/claude/rules/documentation.md +2 -0
  31. package/dist/host/claude/skills/enterprise-bootstrap/SKILL.md +12 -8
  32. package/dist/host/claude/skills/orkestrel-debrief/SKILL.md +1 -1
  33. package/dist/host/claude/skills/{orkestrel-human-journey → orkestrel-prove-journey}/SKILL.md +2 -2
  34. package/dist/host/claude/skills/orkestrel-publish/SKILL.md +12 -0
  35. package/dist/host/codex/agents/analyst.toml +3 -0
  36. package/dist/host/codex/agents/application.toml +3 -0
  37. package/dist/host/codex/agents/builder.toml +10 -7
  38. package/dist/host/codex/agents/checker.toml +14 -3
  39. package/dist/host/codex/agents/grok.toml +5 -2
  40. package/dist/host/codex/agents/implementer.toml +3 -2
  41. package/dist/host/codex/agents/opus.toml +4 -3
  42. package/dist/host/codex/agents/orkestrel.toml +14 -9
  43. package/dist/host/codex/agents/planner.toml +7 -5
  44. package/dist/host/codex/agents/researcher.toml +6 -4
  45. package/dist/host/codex/agents/reviewer.toml +4 -3
  46. package/dist/host/codex/agents/scout.toml +4 -1
  47. package/dist/host/codex/agents/verifier.toml +3 -2
  48. package/dist/host/manifest.json +125 -77
  49. package/dist/src/core/index.cjs +4 -2
  50. package/dist/src/core/index.cjs.map +1 -1
  51. package/dist/src/core/index.js +4 -2
  52. package/dist/src/core/index.js.map +1 -1
  53. package/package.json +2 -2
  54. /package/dist/host/agents/skills/{orkestrel-human-journey → orkestrel-prove-journey}/references/captures.md +0 -0
  55. /package/dist/host/agents/skills/{orkestrel-human-journey → orkestrel-prove-journey}/references/layer.md +0 -0
@@ -6,25 +6,51 @@ evidence-first treatment as any surface.
6
6
 
7
7
  ## Blind passes, one brief
8
8
 
9
- Run a subjective lane and an objective lane on the SAME brief, in parallel, neither
10
- seeing the other's answer before both return:
11
-
12
- - **Subjective** (design-fit engine): coherence of the role model, charter voice, whether
13
- each role's job is one job, whether the skill family reads as one system.
14
- - The subjective lenses, so the lane can state its coverage: role-job singularity;
15
- charter voice against dispatched usage; lane-swap residue; bridge minimalism;
16
- vocabulary drift across mirrored files; skill-family seams.
17
- - **Objective** (correctness engine): evidence-only sweeps of the actual files and the
18
- campaign record — the lanes below.
9
+ Run the subjective lane and the objective lane on the SAME brief, in parallel, neither
10
+ seeing the other's answer before both return. `reviewer` holds the subjective lane and
11
+ `analyst` holds the objective lane.
19
12
 
20
13
  Each lane returns numbered findings, most severe first, and exactly one terminal line:
21
- `INSTRAUDIT <LANE>: <n> findings`.
14
+ `INSTRAUDIT <LANE>: <n> findings`. Each charter defaults to the `orkestrel-falsify`
15
+ verdict shape and takes a different shape the dispatch names, so name `orkestrel-debrief`
16
+ in the dispatch and this shape binds.
17
+
18
+ Point each lane's brief at its own section rather than copying that section's lens list
19
+ into the brief. A copied list drops a lens silently, and the lane that lost it reports
20
+ full coverage.
22
21
 
23
22
  Reconcile into rulings; every divergence gets a ruled row with the reason. Convergent
24
23
  findings adopt without contest; a finding neither lane can substantiate dies on the
25
24
  record.
26
25
 
27
- ## The objective lanes
26
+ ## The subjective lens list
27
+
28
+ Held by `reviewer`. It judges coherence of the role model, charter voice, whether each
29
+ role's job is one job, and whether the skill family reads as one system. This section is
30
+ the lens list's only normative home, and the lane states its coverage against it.
31
+
32
+ - **Role-job singularity.** Is each charter's work cohesive? A charter describing bundled
33
+ jobs is either a role to split or a bundle no dispatch sends whole.
34
+ - **Charter voice against dispatched usage.** Read each charter the way an executor reads
35
+ it mid-task, then compare against how the campaign actually dispatched that role.
36
+ Wording that produced a deviation report is a defect in the charter.
37
+ - **Lane-swap residue.** A role holds the other lane when a bench is dark. Check that each
38
+ charter's wording survives the swap: a charter that assumes its default perspective
39
+ everywhere outside the swap clause cannot be dispatched into the other lane, and a round
40
+ run under a swap that reads like the default lane's output is the residue.
41
+ - **Bridge minimalism.** A provider bridge loads one canonical workflow and adds nothing.
42
+ Any instruction beyond the load is a competing instruction.
43
+ - **Vocabulary drift across mirrored files.** The same concept takes the same term across
44
+ the Claude and Codex mirrors and each operating contract's role table.
45
+ - **Skill-family seams.** Do the skills read as one system: the naming axis, the
46
+ load-authority order, the reference depth, and the boundary each draws with the
47
+ contract.
48
+
49
+ ## The objective lens list
50
+
51
+ Held by `analyst`. It runs evidence-only sweeps of the actual files and the campaign
52
+ record. This section is the lens list's only normative home, and the lane states its coverage
53
+ against it.
28
54
 
29
55
  - **Duplication diff.** Whole-line and obligation-level comparison across charters, rules,
30
56
  and skills. A charter that restates a rule drifts from it; a rule restated elsewhere has
@@ -0,0 +1,107 @@
1
+ # Retire a campaign folder
2
+
3
+ Delete a campaign's working artifacts through this procedure. It fixes what the deletion
4
+ covers, the checks that close it, the go-ahead that authorizes it, and the commit message that
5
+ keeps it recoverable.
6
+
7
+ A debrief arrives at its Dispose step, after every finding has a
8
+ carrier. A campaign that accepts with no debrief arrives at acceptance, per
9
+ `.agents/orchestration.md` § Where campaign artifacts live. The procedure is the same through
10
+ either door.
11
+
12
+ Call the `.orkestrel/` folder the campaign folder, never a ledger. The word `ledger` names the
13
+ routing ledger and the carry ledger only.
14
+
15
+ ## The gate order
16
+
17
+ Order is the whole of this rule: the checks close the prune, and the owner's go-ahead authorizes
18
+ it. Run the steps in this sequence.
19
+
20
+ 1. Run the carry, promotion, measurement, and orientation checks that follow. Every one closes, or
21
+ the prune stops there and the open item gets a carrier first.
22
+ 2. Present the disposition to the owner: what the checks found, where each promotion landed, and
23
+ what the deletion removes.
24
+ 3. Delete only on the owner's explicit go-ahead. Never silently, and never as residue left for the
25
+ next session to read as current.
26
+ 4. Commit the deletion with the promotion record as its message.
27
+
28
+ Closed checks authorize nothing on their own, and a go-ahead taken over an open check deletes an
29
+ item nothing carries. Pruning is deletion, so it needs the same evidence as any other destructive
30
+ step.
31
+
32
+ ## What the prune covers
33
+
34
+ Rule on every location in this table before deleting anything.
35
+
36
+ | Location | What it holds | What the prune does |
37
+ | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
38
+ | `.orkestrel/<package>/` | The campaign folder for a campaign about one package: each unit's brief and report, the audit verdicts, the executed instruments, the acceptance evidence. | Deleted in the prune commit. |
39
+ | `.orkestrel/campaign/` | The shared campaign folder for a campaign spanning several packages: the wave's plan, its routing ledger, its verdicts. | Deleted in the prune commit. |
40
+ | `tmp/units/` | A native unit's `<unit>-brief.md` and `<unit>-report.md` pair. | Swept. The durable copy already sits in the campaign folder, so a pair missing there blocks the sweep. |
41
+ | `tmp/<bench>/` | A bench unit's brief, report, event stream, final answer, and any login log. | Swept after the final gate evidence is recorded. Never committed. |
42
+ | `tmp/probe/` | The runtime probes the campaign wrote. | Swept. A probe that settled a claim becomes a test before the prune, per `.claude/rules/quality.md` § Instruments. |
43
+ | `ROADMAP.md` | The repository's sequenced plan of record, where it keeps one. | Kept. Strike the chunks the campaign closed and add the forward work it revealed. |
44
+ | `PROPOSAL.md` | A proposal for work nobody has ruled on yet. | Deleted after the work lands or the proposal is refused. The ruling goes in the prune commit message. |
45
+
46
+ A plan-of-record file is not campaign residue. `ROADMAP.md` outlives every prune and takes the
47
+ campaign's forward work; `PROPOSAL.md` is spent the moment its proposal is ruled on, and a spent
48
+ proposal left in the tree reads as live work.
49
+
50
+ ## Sweep `tmp/` as a tree
51
+
52
+ Sweep the whole `tmp/` tree, not the set of folders this campaign created. A journal, a log, or a
53
+ brief left by an earlier session sits in the same directory, carries no date a reader checks, and
54
+ is read by the next campaign as its own.
55
+
56
+ - Name each file you find before deleting it. A file you cannot attribute to a closed campaign is
57
+ an open item for the carry check rather than residue.
58
+ - Never sweep while a unit is live. `tmp/units/` and `tmp/<bench>/` hold the briefs and journals
59
+ live lanes are reading, and the Orchestrator's own instruments belong in its scratchpad for this
60
+ reason, per `.agents/orchestration.md` § Writing concurrency.
61
+ - Delete a probe from the source tree before its unit returns, per `.claude/rules/tests.md`. A
62
+ leaked type probe is a placement-sweep failure rather than a retention question.
63
+
64
+ ## The carry check
65
+
66
+ List every item the campaign folder leaves open: a defect, a measurement to re-take, a deferred
67
+ decision, a withdrawn claim, an unmet acceptance condition. Each ends the check with a carrier — a
68
+ commit that closed it, a live brief that owns it, or an explicit drop on the record. An item with
69
+ no carrier blocks the prune.
70
+
71
+ Read the register files for this — the plan, the readiness grade, the carry ledger, the triage —
72
+ rather than every brief and report in the folder.
73
+
74
+ ## The promotion check
75
+
76
+ Rule on each remaining file by what it asserts.
77
+
78
+ - Product truth goes to the guide, where the parity gate reaches it.
79
+ - A process law goes to the rule or contract file that owns it, in the commit that states it.
80
+ - A decision goes to the commit message that made it, which is where it already sits.
81
+ - Everything else is process diary and prunes.
82
+
83
+ A section recording live state — adopter republish status, installed version tables, what a sibling
84
+ repository was doing that week — prunes with no promotion. It was stale when it was written, and
85
+ promoting it publishes the staleness.
86
+
87
+ ## The measurement check
88
+
89
+ A number the guide carries out of the campaign folder carries the date it was taken. A measurement
90
+ whose date the folder does not record is re-taken or dropped, never copied.
91
+
92
+ ## The orientation check
93
+
94
+ A cross-session orientation document — a handoff, a package-root narrative file, a session log — is
95
+ not a further category. It duplicates the guide for product truth and the contract for process
96
+ truth, it is gated by nothing, and it drifts. Dissolve it into the artifacts that own it and delete
97
+ it.
98
+
99
+ ## The prune commit
100
+
101
+ Write the prune commit's message as the promotion record: what moved, and where each part landed.
102
+ That message is what makes the deletion recoverable in practice rather than only in principle. Git
103
+ history is the archive; the working tree is the workspace.
104
+
105
+ Name in one message the guide passages the campaign produced, the rule and contract files that took
106
+ its process laws, the measurements re-taken with their dates, and the campaign folder path the
107
+ commit removes.
@@ -1,5 +1,5 @@
1
1
  ---
2
- name: orkestrel-human-journey
2
+ name: orkestrel-prove-journey
3
3
  description: Prove a browser application the way a person uses it — real keystrokes, clicks, and Tab/Enter against only what is visible and reachable — and generate the capture portfolio from those same journeys. Use when accepting a UI build, proving an application end to end, deciding whether a surface is reachable by keyboard alone, proving what a screen refuses as well as what it does, auditing whether the interface speaks the user's vocabulary rather than the engine's, producing the screenshots a design review judges, or whenever the only evidence a screen works is a test that drove it through JavaScript instead of through the interface.
4
4
  ---
5
5
 
@@ -1,4 +1,4 @@
1
1
  interface:
2
2
  display_name: 'Prove Human Journeys'
3
3
  short_description: 'Prove an application through the interface a person uses'
4
- default_prompt: 'Use $orkestrel-human-journey to prove this application through the interface a person uses, and generate the capture portfolio from those journeys.'
4
+ default_prompt: 'Use $orkestrel-prove-journey to prove this application through the interface a person uses, and generate the capture portfolio from those journeys.'
@@ -0,0 +1,77 @@
1
+ ---
2
+ name: orkestrel-publish
3
+ description: Run an Orkestrel release from layer order to registry confirmation. Use when the user asks to publish a package, to run a fleet-wide release wave, or to recover a release that stalled at the npm approval, and follow it for the per-repository visit, the bump ruling, the layer preparation, the login approval, and the five-minute upload window.
4
+ ---
5
+
6
+ # Publish an Orkestrel release
7
+
8
+ ## Load authority
9
+
10
+ Read the current files in this order:
11
+
12
+ 1. `AGENTS.md` and every applicable `.claude/rules/*.md` file.
13
+ 2. `.agents/orchestration.md` § Publishing the fleet and § Long-running commands. Each named
14
+ section binds every step here.
15
+ 3. The reference the moment needs: [wave.md](references/wave.md) before visiting a repository,
16
+ ruling on a bump, or preparing a layer; [window.md](references/window.md) before running
17
+ `npm login` or any upload.
18
+ 4. The live evidence: the registry's packument for every package in the round, each target's
19
+ manifest, and the catalog table the contract names as the layer order.
20
+
21
+ The user's current instruction wins. The contract's § Publishing the fleet owns the credential
22
+ and authorization law; nothing here weakens it.
23
+
24
+ ## The boundary with the contract
25
+
26
+ `.agents/orchestration.md` § Publishing the fleet binds every release, and this skill does not
27
+ repeat it. Read that section for the credential and approval law, the long-running-command
28
+ binding, the serialization of uploads, the tarball swap that serves a consumer whose dependency
29
+ has not published, what a bump obliges downstream, and where the layer order comes from.
30
+
31
+ This skill carries what an operator needs while a release is running: the per-repository visit,
32
+ the bump ruling, the preparation order, the login and approval mechanics, and the window.
33
+
34
+ Where the skill and the contract disagree, the contract wins. Report the drift instead of
35
+ following the skill.
36
+
37
+ ## Run the release
38
+
39
+ 1. **Name the round.** List the packages the release covers, and group them into layers by the
40
+ contract's layer order.
41
+ 2. **Take the registry evidence.** Read what the registry serves for every package in the round.
42
+ Derive each pin from that reading, never from a local manifest.
43
+ 3. **Visit each repository.** Run the visit in [wave.md](references/wave.md) in its stated order,
44
+ in parallel slices of disjoint repositories, each slice serial inside itself.
45
+ 4. **Rule on each package's bump.** Apply the triggers in [wave.md](references/wave.md). A package
46
+ whose published surface did not move takes its re-pin, its gates, and a commit to `main`, and
47
+ does not publish.
48
+ 5. **Prepare the whole layer before authenticating.** Bump, re-pin, install, sweep the self-pins,
49
+ run each package's own `prepublishOnly` to green, commit, and push. Every one of those steps
50
+ happens outside the window.
51
+ 6. **Reach the approval.** Follow [window.md](references/window.md), and launch the login chain
52
+ only after the user signals they are at the keyboard.
53
+ 7. **Spend the window.** Follow [window.md](references/window.md). Open the layer with one
54
+ package, confirm its upload from the registry, then chase the remaining uploads back-to-back.
55
+ 8. **Close the layer from the registry, then prepare the next.** A dependent's new pin cannot
56
+ install until the version it names exists, so preparation and publication interleave and cannot
57
+ be batched ahead.
58
+
59
+ Run that sequence for every layer, from the registry reading to the registry close. Refresh the
60
+ registry evidence between layers rather than carrying the previous round's reading forward.
61
+
62
+ ## Accept the release
63
+
64
+ Completion requires:
65
+
66
+ - every package the round named has ended published at a registry-confirmed version, published on
67
+ a later round with the reason recorded, or ruled as no bump with the evidence that ruled it;
68
+ - every obligation § What a bump obliges places on a published package's dependents has closed as
69
+ that section requires;
70
+ - every tarball swap is restored per § Fixing a dependency before it publishes, and no target
71
+ repository is left holding an uncommitted bump or an unpushed commit;
72
+ - every gate that proved a package ran outside the window and against the artifact that shipped.
73
+
74
+ Report the layers in publish order, each package with its registry-confirmed version, the bump
75
+ rulings and their evidence, the approvals the user granted, and anything still unpublished. End
76
+ with exactly one terminal line — `RELEASE: LANDED` when every package in the round has closed, or
77
+ `RELEASE: OPEN` with the packages that have not.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: 'Publish Orkestrel Release'
3
+ short_description: 'Run a release in layer order through the npm approval window'
4
+ default_prompt: 'Use $orkestrel-publish to run the release - layer order, per-repository visit, bump ruling, layer preparation, login approval, upload window, and registry confirmation.'
@@ -0,0 +1,97 @@
1
+ # The release wave
2
+
3
+ Close a fleet-wide goal of every package on registry-served versions as a release wave in layer
4
+ order: visit every
5
+ repository once per round with one procedure, publish each layer in one window, and only then
6
+ prepare the next.
7
+
8
+ ## Visit a repository
9
+
10
+ Run the visit in this order. A step that reads generated or installed state is invalid before the
11
+ step that writes it.
12
+
13
+ 1. Re-pin the target's `@orkestrel/scaffold` devDependency and install, so the overwrite runs the
14
+ current vendored host.
15
+ 2. Run `scaffold overwrite`.
16
+ 3. Force-verify every `@orkestrel` range against a registry sweep taken after the previous layer
17
+ published.
18
+ 4. Run the full install.
19
+ 5. Run the mutating `format` script to converge generated writes.
20
+ 6. Run the quality gates.
21
+ 7. Compare the rebuilt `dist/` against the published tarball for material content.
22
+
23
+ Restore any unpublished tarball the target is holding before the quality gates run, per
24
+ `.agents/orchestration.md` § Fixing a dependency before it publishes. A distribution proof run
25
+ against a local tarball proves the local tarball.
26
+
27
+ Run visits in parallel slices of disjoint repositories, each slice strictly serial inside itself,
28
+ reporting per target. Refuse a failed target, name it, repair it, and re-run it alone.
29
+
30
+ ## Rule on the bump
31
+
32
+ Bump on either trigger: the rebuilt dist differs materially from the published tarball, or the
33
+ final runtime dependency set differs from the published packument.
34
+
35
+ - Test the final dependency set against the packument, never "did my step move a pin". The
36
+ `declare` step inside `scaffold overwrite` re-pins before any later check, so the step-local
37
+ reading reports nothing moved while the manifest surface did.
38
+ - Treat a re-pinned runtime range as published surface. Without the bump a consumer installs
39
+ duplicate copies of the moved dependency.
40
+ - Compare material content only, as `.agents/orchestration.md` § What a bump obliges defines it,
41
+ and take the blast radius of a bump from that section rather than deciding it here.
42
+ - Ship a dist built before the version bump wherever the bump edits no emitted byte. Check that
43
+ per package rather than assuming it: a package that imports its own `package.json` version into
44
+ published code emits that version, so its pre-bump dist is stale the moment the version moves.
45
+ Rebuild after the bump there and pack from the rebuilt tree. The `npm publish --ignore-scripts`
46
+ command skips `prepack`, so that rebuild is the operator's step rather than the publish's.
47
+
48
+ ## Prepare a layer
49
+
50
+ An unpublished package's first version is `0.0.1`. Do not bump it before that first publish. The
51
+ registry has nothing to serve, so there is no version to move away from, and bumping produces a
52
+ package whose history starts at a number nothing explains.
53
+
54
+ Prepare a published package's layer in this order:
55
+
56
+ 1. **Bump from what the registry serves, not from the local manifest.** A repository's `version`
57
+ field can sit a release behind what was published from another checkout, and bumping that
58
+ produces a version the registry already holds, which fails on upload after the whole gate chain
59
+ has run. Read the registry first.
60
+ 2. **Re-pin every `@orkestrel` range to what the registry serves, and install.**
61
+ 3. **Sweep the self-pins**, per the following section.
62
+ 4. **Run each package's own `prepublishOnly` script to green.**
63
+ 5. **Commit and push before the window opens.**
64
+
65
+ Prepare the next layer only after this one is on the registry. A dependent's new pin cannot
66
+ install until the version it names exists, so preparation and publication interleave and cannot be
67
+ batched ahead.
68
+
69
+ The window is for uploads. Every gate, build, install, and commit happens outside it, which is
70
+ what makes `--ignore-scripts` the right flag at publish time: the artifact was already proved, and
71
+ the flag is what stops the gate chain running a second time inside the five minutes.
72
+
73
+ ## Sweep the self-pins
74
+
75
+ A package's own version appears in its source and its tests as a literal, and a bump falsifies
76
+ every one of them. Run this sweep after the re-pin install, not after the manifest edit.
77
+
78
+ - `grep` the prior version literal across `tests/` and `src/` in the publishing package, and rule
79
+ on every hit. A canned packument in a fixture and a looked-up version in a CLI suite carry the
80
+ version with no tripwire comment beside them, so they surface as a red gate after the bump
81
+ rather than as a planned edit before it.
82
+ - Move a documented tripwire — a golden digest over generated output — in the same change as the
83
+ version bump. That is what the tripwire is for.
84
+ - Re-take a generated artifact's digest after the install, because the generated bytes can derive
85
+ from the installed tree rather than from the manifest. An install that picks up a newly
86
+ published dependency moves such a digest with no manifest edit at all, and reverting the
87
+ manifest pin does not restore it.
88
+ - Prove the cause of a moved digest before recording it. Patch the generated bytes back to the
89
+ prior content and reproduce the prior digest: a digest that stays moved after the pin is
90
+ reverted has a cause the pin does not explain, and a new digest recorded without that control is
91
+ a value nobody can check.
92
+
93
+ ## Refresh the registry between layers
94
+
95
+ Refresh the registry evidence between layers and derive each round's pins from it. A pin can only
96
+ name a version the registry already serves, so a dependency shipping in the same window keeps the
97
+ resolvable previous pin and takes its development-only re-pin after the window closes.
@@ -0,0 +1,95 @@
1
+ # The approval and the upload window
2
+
3
+ The npm approval is the user's click, and the window it opens is five minutes long. Reach that
4
+ click with a live chain, and spend the window without losing it.
5
+
6
+ ## Arm the terminal
7
+
8
+ - Run the login and every publish under `script -qfc '<command>' <log>`. npm offers the approval
9
+ only when it sees a TTY; without one it fails `EOTP` with no way to answer.
10
+ - Pass `--browser=false` to `npm login` and to every `npm publish`. Without it npm prints
11
+ `Press ENTER to open in the browser...` and blocks. Never answer that prompt with a newline: the
12
+ web flow consumes the newline on a later read, drops to a legacy `Username:` prompt, and exits
13
+ **zero** without authenticating. With the flag npm prints the URL and polls, and stdin stays
14
+ untouched.
15
+ - Hold stdin open and write nothing to it. Use a fifo held open by a long `sleep`. EOF drops npm
16
+ to the same legacy prompt a stray newline does.
17
+ - Run `npm login` before any publish. The `npm publish` command does not open the browser flow:
18
+ unauthenticated it returns `E404` on `PUT`, which reads as a missing package rather than as a
19
+ missing credential.
20
+ - Confirm authentication with `npm whoami`, never with an exit code. The legacy fallthrough exits
21
+ zero.
22
+ - Re-probe `whoami` immediately before opening the window. A stored credential expires
23
+ mid-session, so a session-start answer does not hold.
24
+ - Read a login log that shows the spinner and then a legacy `Username:` prompt as an expired
25
+ attempt rather than as a prompt to answer. Kill it by process id and mint a fresh flow.
26
+ - On a Windows host, Git Bash ships no `script` binary, so the upload step is operator-driven:
27
+ prepare the layer, prove the gates, surface the exact `npm publish` command, and the operator
28
+ runs it in a real terminal. Everything before and after the upload — bumps, re-pins, gates,
29
+ registry reads — stays with the Orchestrator. The fifo stdin law still binds on that host.
30
+
31
+ ## Reach the approval
32
+
33
+ - Launch the login chain only when the user has signalled they are at the keyboard and will click
34
+ within ten minutes. An approval URL expires unclicked in about ten to fifteen minutes, and an
35
+ overnight gap expires the session credential with it.
36
+ - Expect an approval for each stage. The `npmjs.com/login/cli/<id>` URL authenticates the session;
37
+ the `npmjs.com/auth/cli/<id>` URL authorizes the publish and opens the five-minute window. Tell
38
+ the user both are coming, or the second link reads as the first having failed.
39
+ - Say that approving the publish one opens a five-minute window covering the rest of the layer.
40
+ - Surface each approval URL the moment it appears in the log, and take the **last** one in log
41
+ order. npm mints a new URL whenever an attempt starts again, and the log accumulates every one,
42
+ so a URL chosen by sorting rather than by position is already dead when the user opens it.
43
+ - Read the URL out of the journal in the foreground and surface it before arming any watcher. A
44
+ watcher-based relay can fail silently, and its silence is indistinguishable from a chain that
45
+ has not reached the URL yet.
46
+ - Relay the URL as plain text. A decorated link did not render for the operator, who then had
47
+ nothing to click while the window ran down.
48
+ - Re-read the log before treating an approval as failed. The chain is usually still alive on a
49
+ later URL, so surface that one rather than starting the chain again.
50
+ - Read a `404` on an approval URL as a publish that already succeeded and consumed it. Read the
51
+ registry before calling it a failure.
52
+
53
+ ## Spend the window
54
+
55
+ - The window opens when the user approves, not when the first publish starts.
56
+ - Open each layer with one package: publish it alone, surface its approval URL the moment the
57
+ journal shows it, and confirm the upload from the registry before starting the rest.
58
+ - Then chase the remaining uploads back-to-back in one process with no gap. An upload started
59
+ within seconds of an approval frequently rides that approval, and each one that does not mints
60
+ its own URL.
61
+ - Relay every new URL to the user the moment it appears, through a journal watcher, and never
62
+ pause the chain to wait for a click: a poll outlives the relay.
63
+ - Tell the user to click only the URL last in log order. A click on a superseded URL poisons the live attempt
64
+ — the current poll fails `403 Forbidden - GET /-/v1/done` mid-flight. After any such 403,
65
+ confirm no publish process is live, then mint one fresh attempt.
66
+ - **Never retry a publish that is still waiting for its authorization.** Each `npm publish`
67
+ attempt mints a new `authId` and invalidates the previous one, so a retry loop makes the URL a
68
+ moving target the user cannot approve in time. The abandoned poll then reports
69
+ `403 Forbidden - GET /-/v1/done?authId=…`, which reads as a permissions problem and is the
70
+ abandoned attempt colliding with the live one. Publish the first package of a layer with exactly
71
+ one attempt.
72
+ - Retry only an upload that failed **inside** an already-open window. `EOTP` there is intermittent
73
+ contention rather than the window closing: retry about three times, and retry a failed set after
74
+ the layer ends. Packages have landed on the third attempt and on a later pass with no new
75
+ approval. These are different failures wearing similar codes; a retry fixes in-window contention
76
+ and causes the moving approval target.
77
+ - Expect a large layer to outlast one window. Size batches to what uploads in five minutes and
78
+ name each planned approval point to the user, rather than discovering them mid-run.
79
+ - The contract's serialization law binds every upload in the window, and
80
+ `.agents/orchestration.md` § Long-running commands binds the chain that runs them.
81
+
82
+ ## Read the verdict from the registry
83
+
84
+ - Read the result from the registry, not from an exit code. A piped `npm publish` reports the exit
85
+ status of the pipeline, and a CDN read straight after a publish can still serve the previous
86
+ version.
87
+ - Treat a `404` after a first publish as pending rather than failed. A first publish creates the
88
+ packument and can serve `404` for minutes after success, so for a package with no prior version
89
+ re-read on an interval before reporting either way. A bump serving the old version is CDN lag,
90
+ same rule.
91
+ - Rule on a pack-time manifest-rewriting warning by fetching the registry's copy of the manifest,
92
+ never by the warning's own text.
93
+ - Re-read the registry before telling the user a package failed. A chain still running, a retry
94
+ that landed, and CDN lag all produce a failure reading that the registry contradicts, and a
95
+ false failure report costs a needless approval and a needless republish.
@@ -0,0 +1,157 @@
1
+ # Dispatch brief template
2
+
3
+ Copy this file for each dispatch and fill every row. Then run
4
+ `.agents/orchestration.md` § "Check the brief before you send it" against what you filled, and save
5
+ the filled copy and the returned report under the names § "Every dispatch is a file before it is a
6
+ launch" fixes.
7
+
8
+ Replace every placeholder written in upper snake case with a concrete value. Retitle the filled
9
+ copy `# Unit UNIT_ID — SHORT_SUBJECT`. Delete each italic reminder as you fill the row it sits
10
+ under, and leave no row blank: fill a row you cannot close with a named unknown label, and
11
+ describe that label under § Unknowns with how the unit reports back on it.
12
+
13
+ ## Role and engine
14
+
15
+ ROLE_NAME on ENGINE_NAME, reached as TRANSPORT.
16
+
17
+ _Name the executor that opens this brief — a native subagent, a bench engine inside its own CLI, or a
18
+ bridge driver — and write every later section for that reader._
19
+
20
+ ## Objective
21
+
22
+ ONE_OUTCOME.
23
+
24
+ _State one outcome. Give a small unrelated obligation its own unit._
25
+
26
+ ## Context
27
+
28
+ **Evidence.** PASTED_COMMANDS_AND_OUTPUT
29
+
30
+ _Paste the command and its output behind every factual claim: paths, counts, registrations, file
31
+ existence. Name the scope each search covered, and check each fact against the code rather than
32
+ against another artifact that states it._
33
+
34
+ **Law.** `AGENTS.md`, RULE_FILES, SKILL_NAME and the references it requires, GUIDE_OR_SPEC.
35
+
36
+ _Name each applicable rule file, the dispatch-named skill and its required references, and the
37
+ governing guide or spec. Write `none` in a slot that is genuinely empty rather than dropping the
38
+ slot._
39
+
40
+ **Host.** SHELL, WORKING_PATH, NETWORK_AND_SANDBOX_LIMITS.
41
+
42
+ _Name the shell, the working path, and the sandbox, network, and approval limits the unit's commands
43
+ run under._
44
+
45
+ **Measurements.** MEASURED_FACTS_AND_THE_CONDITIONS_THEY_WERE_TAKEN_UNDER.
46
+
47
+ _Take each measurement under the conditions the unit runs in, or have the unit take it before doing
48
+ anything else._
49
+
50
+ **Control identifiers.** CONTROL_LABELS.
51
+
52
+ _Keep this brief's control labels inside this brief, and state that a test is named for what it
53
+ proves rather than for the control that specified it._
54
+
55
+ **Standing conditions.** DIRTY_FILES, KNOWN_FAILING_COMMANDS, BLOCKED_TOOLS.
56
+
57
+ _Name each condition the unit meets and must not diagnose as its own: a file expected to be dirty, a
58
+ command known to fail, a gate red at the baseline, a shim the shell blocks, and who repairs each
59
+ one._
60
+
61
+ ## Unknowns
62
+
63
+ UNKNOWN_FACT and HOW_THE_UNIT_REPORTS_IT.
64
+
65
+ _Name what you do not know that the unit needs, as an unknown, with the report-back it takes. Write
66
+ `none` where the brief is fully specified, rather than shipping a guess the unit has to invent an
67
+ answer around._
68
+
69
+ ## Scope
70
+
71
+ **Owned.** OWNED_FILES
72
+
73
+ _Grant a behaviour with the tests that pin it, a constant with every fixture and expectation derived
74
+ from it, a template with the materialized copy the package generates from it, and a mechanism with
75
+ the prose describing it: the comment beside the code it edits and the guide passage stating the
76
+ behaviour it moves._
77
+
78
+ **Shared (report-only).** SHARED_FILES
79
+
80
+ _Name each file another live unit owns. The unit returns an exact patch for serial integration and
81
+ edits nothing in this row._
82
+
83
+ **Off-limits.** OFF_LIMITS_FILES
84
+
85
+ _Name each file the unit must not touch, and read every acceptance criterion against this row line by
86
+ line. Grant the file a criterion needs, or strike that criterion. A file the change breaks that
87
+ appears in no row of this section is unscoped._
88
+
89
+ **What asserts the state this change ends.** FILES_THE_RESULT_MAKES_FALSE
90
+
91
+ _List every file the result makes false rather than every file that declares the thing changing: the
92
+ test asserting the reversed behaviour, the fixture carrying the raised value, the golden digest over
93
+ generated output, the consumer script naming the removed union member. Derive the list by running the
94
+ suite; where you cannot run it, name the search's bound so the unit re-derives the list. End each
95
+ entry in Owned, in Shared, or with a named carrier dispatched before this change ships._
96
+
97
+ **Tools and limits.** ALLOWED_TOOLS, PERMISSION_LIMITS
98
+
99
+ _Check the § Output mechanism and every acceptance criterion's verification method against this
100
+ allowlist. A read-only lane writes no report file and runs no probe, so hand it the rendered evidence
101
+ instead._
102
+
103
+ ## Execution
104
+
105
+ **A native subagent, or a bench engine reading this brief inside its own CLI:** perform the
106
+ assignment directly and spawn nothing.
107
+
108
+ **A bridge driver:** carry this brief across unaltered, launch ENGINE_NAME through its CLI, and
109
+ return the journal path and the session id with the result.
110
+
111
+ _Keep the line written for the reader this brief reaches. Delete the line written for the other
112
+ reader. A bench result that carries no journal path and no session id ran on the driver's own engine:
113
+ refuse it._
114
+
115
+ ## Output
116
+
117
+ RETURN_SHAPE, delivered through OUTPUT_MECHANISM.
118
+
119
+ _State the exact distilled return shape and the mechanism that delivers it. No process diary._
120
+
121
+ ## Deviation contract
122
+
123
+ Stop and report — expected, found, exact evidence, done or not done, and at most one short
124
+ hypothesis — on CONFLICT_WITH_THE_OBJECTIVE. Decide, record, and carry on from
125
+ ANCILLARY_CONFLICT_THE_UNIT_SETTLES.
126
+
127
+ _Scope the contract. A conflict with the objective stops the unit; where a paragraph sits and which
128
+ heading a section takes are the unit's to settle._
129
+
130
+ ## Acceptance criteria
131
+
132
+ 1. REGENERATION_OR_CHEAPEST_GATE_CRITERION
133
+ 2. SCOPED_GATE_CRITERION
134
+ 3. ARTIFACT_CRITERION
135
+
136
+ _Order the criteria cheap-first, so an unreachable criterion cannot hide a typecheck or a lint
137
+ criterion behind it. Where the change edits a file the repository vendors or digests, put the
138
+ regeneration step ahead of every gate that reads the generated artifact. Ask what the change does
139
+ to every fact you measured, and fix each criterion to the state the unit finishes in. Close each
140
+ criterion with owned files alone, and name the property the unit must change; record a consequence
141
+ you expect to follow as an observation, never as a criterion. A scoped run over the unit's own
142
+ owned files stays a legitimate criterion._
143
+
144
+ **Observations, not criteria.** TIMING_SENSITIVE_OR_WHOLE_SUITE_GATES
145
+
146
+ _Name each timing-sensitive or whole-suite gate as an observation the unit reports with its own
147
+ reading. Take the authoritative run yourself after the unit exits._
148
+
149
+ ## Review evidence
150
+
151
+ EVIDENCE_FOR_EVERY_ROW_THIS_SUBJECT_OCCUPIES.
152
+
153
+ _Supply what `orkestrel-falsify` § "Evidence, by subject type" requires of each row the subject
154
+ occupies: for a code change the actual diff and the actual status output, for a rendered or
155
+ externally driven surface the capture portfolio as primary and source as corroboration, and for a
156
+ policy, design, or process proposal the proposal, the canon it must satisfy, and the record of what
157
+ motivated it. A subject occupying more than one row takes the evidence of every row._