swarm-orchestrator 14.2.0 → 14.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +93 -1
- package/README.md +140 -124
- package/dist/action/artifacts.js +72 -0
- package/dist/action/artifacts.js.map +1 -0
- package/dist/action/comment.js +139 -0
- package/dist/action/comment.js.map +1 -0
- package/dist/action/environment.js +106 -0
- package/dist/action/environment.js.map +1 -0
- package/dist/action/verdict.js +103 -0
- package/dist/action/verdict.js.map +1 -0
- package/dist/action/verify.js +424 -0
- package/dist/action/verify.js.map +1 -0
- package/dist/cli-action.js +117 -0
- package/dist/cli-action.js.map +1 -0
- package/dist/cli-check.js +341 -0
- package/dist/cli-check.js.map +1 -0
- package/dist/cli-ci.js +27 -3
- package/dist/cli-ci.js.map +1 -1
- package/dist/cli-command-definitions.js +43 -1
- package/dist/cli-command-definitions.js.map +1 -1
- package/dist/cli-gates.js +33 -10
- package/dist/cli-gates.js.map +1 -1
- package/dist/cli-integrations.js +145 -0
- package/dist/cli-integrations.js.map +1 -0
- package/dist/cli-options.js +32 -0
- package/dist/cli-options.js.map +1 -1
- package/dist/cli-strengthen.js +527 -0
- package/dist/cli-strengthen.js.map +1 -0
- package/dist/cli-task-goal.js +58 -9
- package/dist/cli-task-goal.js.map +1 -1
- package/dist/cli-verdict.js +144 -0
- package/dist/cli-verdict.js.map +1 -0
- package/dist/cli-verify-options.js +85 -0
- package/dist/cli-verify-options.js.map +1 -1
- package/dist/cli.js +82 -8
- package/dist/cli.js.map +1 -1
- package/dist/config/init.js +1 -1
- package/dist/config/init.js.map +1 -1
- package/dist/config/package-discovery.js +47 -1
- package/dist/config/package-discovery.js.map +1 -1
- package/dist/durable/recovery-context.js +3 -2
- package/dist/durable/recovery-context.js.map +1 -1
- package/dist/evidence/blob-manifest.js +9 -0
- package/dist/evidence/blob-manifest.js.map +1 -1
- package/dist/evidence/bundle.js +17 -2
- package/dist/evidence/bundle.js.map +1 -1
- package/dist/evidence/challenge-lines.js +21 -0
- package/dist/evidence/challenge-lines.js.map +1 -0
- package/dist/evidence/ci-summary.js +5 -1
- package/dist/evidence/ci-summary.js.map +1 -1
- package/dist/evidence/goal-contract.js +132 -1
- package/dist/evidence/goal-contract.js.map +1 -1
- package/dist/evidence/signing.js +3 -1
- package/dist/evidence/signing.js.map +1 -1
- package/dist/evidence/verifier/challenges.d.mts +19 -0
- package/dist/evidence/verifier/challenges.mjs +203 -0
- package/dist/evidence/verifier/rederive.mjs +20 -2
- package/dist/evidence/verifier/status.d.mts +2 -0
- package/dist/evidence/verifier/status.mjs +638 -38
- package/dist/evidence/verifier/strengthening.d.mts +18 -0
- package/dist/evidence/verifier/strengthening.mjs +200 -0
- package/dist/evidence/verifier/upgrade.mjs +1 -0
- package/dist/evidence/verifier/verify.mjs +25 -1
- package/dist/exec/child-environment.js +30 -0
- package/dist/exec/child-environment.js.map +1 -1
- package/dist/exec/container-backend.js +103 -12
- package/dist/exec/container-backend.js.map +1 -1
- package/dist/exec/controlled-network.js +20 -1
- package/dist/exec/controlled-network.js.map +1 -1
- package/dist/exec/execution-mode.js +25 -13
- package/dist/exec/execution-mode.js.map +1 -1
- package/dist/exec/runtime-resource.js +6 -1
- package/dist/exec/runtime-resource.js.map +1 -1
- package/dist/gates/base-control.js +7 -2
- package/dist/gates/base-control.js.map +1 -1
- package/dist/gates/certification.js +4 -0
- package/dist/gates/certification.js.map +1 -1
- package/dist/gates/change-source.js +29 -29
- package/dist/gates/change-source.js.map +1 -1
- package/dist/gates/check-admission.js +218 -0
- package/dist/gates/check-admission.js.map +1 -0
- package/dist/gates/check-network-probe.js +42 -0
- package/dist/gates/check-network-probe.js.map +1 -0
- package/dist/gates/check-plan.js +269 -0
- package/dist/gates/check-plan.js.map +1 -0
- package/dist/gates/checkout-environment.js +119 -0
- package/dist/gates/checkout-environment.js.map +1 -0
- package/dist/gates/contract-executor.js +7 -4
- package/dist/gates/contract-executor.js.map +1 -1
- package/dist/gates/default-gates.js +2 -2
- package/dist/gates/default-gates.js.map +1 -1
- package/dist/gates/deferred-setup.js +250 -0
- package/dist/gates/deferred-setup.js.map +1 -0
- package/dist/gates/dependency-install.js +200 -41
- package/dist/gates/dependency-install.js.map +1 -1
- package/dist/gates/engine.js +7 -1
- package/dist/gates/engine.js.map +1 -1
- package/dist/gates/failure-attribution.js +444 -0
- package/dist/gates/failure-attribution.js.map +1 -0
- package/dist/gates/gate-definition.js.map +1 -1
- package/dist/gates/gate-runner.js +31 -5
- package/dist/gates/gate-runner.js.map +1 -1
- package/dist/gates/git-workspace.js +36 -5
- package/dist/gates/git-workspace.js.map +1 -1
- package/dist/gates/goal-challenge-runner.js +99 -0
- package/dist/gates/goal-challenge-runner.js.map +1 -0
- package/dist/gates/goal-challenges.js +337 -0
- package/dist/gates/goal-challenges.js.map +1 -0
- package/dist/gates/harness-reporting.js +7 -3
- package/dist/gates/harness-reporting.js.map +1 -1
- package/dist/gates/independent-checks.js +63 -2
- package/dist/gates/independent-checks.js.map +1 -1
- package/dist/gates/independent-verification.js +569 -82
- package/dist/gates/independent-verification.js.map +1 -1
- package/dist/gates/inspection-gates.js +5 -5
- package/dist/gates/inspection-gates.js.map +1 -1
- package/dist/gates/instrument-dependencies.js +249 -0
- package/dist/gates/instrument-dependencies.js.map +1 -0
- package/dist/gates/instrument-identity.js +794 -0
- package/dist/gates/instrument-identity.js.map +1 -0
- package/dist/gates/mutant-parse.js +23 -0
- package/dist/gates/mutant-parse.js.map +1 -1
- package/dist/gates/node-command-runner.js +16 -2
- package/dist/gates/node-command-runner.js.map +1 -1
- package/dist/gates/node-gates.js +39 -8
- package/dist/gates/node-gates.js.map +1 -1
- package/dist/gates/node-test-command.js +22 -4
- package/dist/gates/node-test-command.js.map +1 -1
- package/dist/gates/noninteractive-runner.js +106 -0
- package/dist/gates/noninteractive-runner.js.map +1 -0
- package/dist/gates/oracle-instrumentation.js +1 -4
- package/dist/gates/oracle-instrumentation.js.map +1 -1
- package/dist/gates/oracle-mutants.js +13 -3
- package/dist/gates/oracle-mutants.js.map +1 -1
- package/dist/gates/parsers.js +110 -4
- package/dist/gates/parsers.js.map +1 -1
- package/dist/gates/patch-paths.js +304 -14
- package/dist/gates/patch-paths.js.map +1 -1
- package/dist/gates/prepare-dependencies.js +2 -0
- package/dist/gates/prepare-dependencies.js.map +1 -1
- package/dist/gates/prepared-tools.js +18 -0
- package/dist/gates/prepared-tools.js.map +1 -0
- package/dist/gates/project-environment.js +1 -0
- package/dist/gates/project-environment.js.map +1 -1
- package/dist/gates/project-type.js +131 -14
- package/dist/gates/project-type.js.map +1 -1
- package/dist/gates/python-gates.js +58 -32
- package/dist/gates/python-gates.js.map +1 -1
- package/dist/gates/python-mutants.js +176 -0
- package/dist/gates/python-mutants.js.map +1 -0
- package/dist/gates/python-offline-build.js +274 -0
- package/dist/gates/python-offline-build.js.map +1 -0
- package/dist/gates/runner-results.js +96 -23
- package/dist/gates/runner-results.js.map +1 -1
- package/dist/gates/scratch-index.js +112 -3
- package/dist/gates/scratch-index.js.map +1 -1
- package/dist/gates/setup-effect.js +16 -0
- package/dist/gates/setup-effect.js.map +1 -0
- package/dist/gates/setup-follow-up.js +113 -0
- package/dist/gates/setup-follow-up.js.map +1 -0
- package/dist/gates/structured-runner.js +37 -8
- package/dist/gates/structured-runner.js.map +1 -1
- package/dist/gates/unified-diff.js +39 -9
- package/dist/gates/unified-diff.js.map +1 -1
- package/dist/gates/upgrade-contract.js +1 -0
- package/dist/gates/upgrade-contract.js.map +1 -1
- package/dist/gates/upgrade-resolution.js +8 -1
- package/dist/gates/upgrade-resolution.js.map +1 -1
- package/dist/install/health.js +3 -3
- package/dist/install/health.js.map +1 -1
- package/dist/integrations/claude-hook.js +200 -0
- package/dist/integrations/claude-hook.js.map +1 -0
- package/dist/integrations/launcher.js +17 -0
- package/dist/integrations/launcher.js.map +1 -0
- package/dist/integrations/mcp-server.js +270 -0
- package/dist/integrations/mcp-server.js.map +1 -0
- package/dist/integrations/pre-commit.js +169 -0
- package/dist/integrations/pre-commit.js.map +1 -0
- package/dist/machine-output.js +1 -0
- package/dist/machine-output.js.map +1 -1
- package/dist/node-floor.js +46 -17
- package/dist/node-floor.js.map +1 -1
- package/dist/swarm-verify.js +30 -5
- package/dist/swarm-verify.js.map +1 -1
- package/dist/workers/bootstrap-history.js +4 -3
- package/dist/workers/bootstrap-history.js.map +1 -1
- package/dist/workers/worktree.js +72 -30
- package/dist/workers/worktree.js.map +1 -1
- package/docs/README.md +17 -3
- package/docs/claims.md +31 -7
- package/docs/security-coverage.md +3 -1
- package/package.json +6 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,96 @@
|
|
|
1
|
-
# Changelog
|
|
1
|
+
# Changelog: swarm-orchestrator
|
|
2
|
+
|
|
3
|
+
The coding agent. The standalone verifier it is built on, `swarm-verify`, has its own changelog at
|
|
4
|
+
[packages/swarm-verify/CHANGELOG.md](packages/swarm-verify/CHANGELOG.md); an agent release names
|
|
5
|
+
the verifier version it carries rather than repeating those entries.
|
|
6
|
+
|
|
7
|
+
## 14.4.0 - 2026-10-08
|
|
8
|
+
|
|
9
|
+
Swarm Orchestrator is the product of this repository again. 14.3.0's README and repository
|
|
10
|
+
description presented Swarm Verify as the product and the coding agent as an optional beta mode
|
|
11
|
+
of it; this release reverses that ([ADR 0013](docs/adr/0013-two-products-one-verifier.md)) and
|
|
12
|
+
gives the verifier its own product home. No runtime behaviour of the agent changed; the verifier
|
|
13
|
+
carried is `swarm-verify` 1.3.1, whose engine is 1.3.0's.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- **The README, package description and repository description describe the coding agent**:
|
|
18
|
+
what it does, why it is not an ordinary coding agent, install, one task, what verification
|
|
19
|
+
happens, what evidence is produced, what it does not prove, and how Swarm Verify relates to
|
|
20
|
+
it. `docs/agent.md` is the long form of that page rather than a beta notice.
|
|
21
|
+
- **The changelog is split.** This file holds the agent's releases; the verifier's 1.x entries
|
|
22
|
+
moved whole to `packages/swarm-verify/CHANGELOG.md`, which ships in that package.
|
|
23
|
+
- **The Action manifest lives beside the package it ships**, at `packages/swarm-verify/action.yml`,
|
|
24
|
+
so this repository no longer presents itself as a GitHub Action; the control workflow runs it
|
|
25
|
+
from there. The Action is branded Swarm Verify.
|
|
26
|
+
- **The verifier's product repository is generated whole**: README, changelog, an Action
|
|
27
|
+
reference rendered from the manifest, the example workflows, the hook manifest, the license
|
|
28
|
+
and the source record, by `scripts/build-action-distribution.mjs`, which refuses a README that
|
|
29
|
+
links to a file it does not write.
|
|
30
|
+
- Issue forms: an agent bug form beside the verifier's; the setup form takes either version.
|
|
31
|
+
`SUPPORT.md` and `SECURITY.md` name both products.
|
|
32
|
+
|
|
33
|
+
### Added
|
|
34
|
+
|
|
35
|
+
- `src/product-boundary.test.ts` holds each product's package metadata, binary, dependencies,
|
|
36
|
+
changelog and README front matter to the product it names, and keeps the inverted phrasing
|
|
37
|
+
out of the documents a reader is pointed at.
|
|
38
|
+
- The standalone verifier's import-boundary test now also refuses any bare import outside Node
|
|
39
|
+
and the two packages `swarm-verify` declares, so a model SDK cannot enter the published
|
|
40
|
+
verifier through a module the build allows.
|
|
41
|
+
- `scripts/build-action-distribution.test.mjs` holds the generated distribution to the source
|
|
42
|
+
manifest, the package README and the examples.
|
|
43
|
+
|
|
44
|
+
## 14.3.0 - 2026-09-30
|
|
45
|
+
|
|
46
|
+
The coding agent, `swarm-orchestrator`, released for the first time since the verifier-first
|
|
47
|
+
work began. The `swarm` binary shares its verifier with `swarm-verify`, so every change published
|
|
48
|
+
for `swarm-verify` 1.0.0 through 1.3.0 (now in [packages/swarm-verify/CHANGELOG.md](packages/swarm-verify/CHANGELOG.md))
|
|
49
|
+
is in this release too. What follows is what the
|
|
50
|
+
agent itself gained; the verifier stays the primary product and the agent its advanced mode.
|
|
51
|
+
|
|
52
|
+
### Added
|
|
53
|
+
|
|
54
|
+
- **The verifier's commands in the `swarm` binary**: `swarm check`, `verdict`, `hook`, `mcp`,
|
|
55
|
+
`pre-commit` and `action`, as published for `swarm-verify` and documented there.
|
|
56
|
+
- **Requirement-level challenges on the agent's preset path.** `--challenges off|report|required`
|
|
57
|
+
(with `--preset` and `--goal-contract`) runs the base control, mechanical mutations of the
|
|
58
|
+
changed lines witnessed by the repository's suite, and the contract's sealed fixtures against
|
|
59
|
+
the agent's own change; `required` refuses a run whose checks demonstrated no detection. The
|
|
60
|
+
challenge conclusions are stated the same way in the terminal, the summary and the comment.
|
|
61
|
+
- **Check strengthening and repair.** `--strengthen` (with `--strengthen-rounds` and
|
|
62
|
+
`--strengthen-per-requirement`, which can only lower the defaults of two rounds and one check
|
|
63
|
+
per requirement) answers a witnessed gap: the model proposes one additive check, the harness
|
|
64
|
+
admits it only where it rejects the counterexample and accepts every sealed reference, the
|
|
65
|
+
admitted checks revise the contract with their lineage, and the implementation is repaired
|
|
66
|
+
under the same seal with a bounded brief. The JSON result carries `strengthening` (rounds,
|
|
67
|
+
admitted checks, why it stopped, contract digest). Nothing is asked of the model before the
|
|
68
|
+
criteria are sealed or after cancellation; a run killed mid-admission resumes with that
|
|
69
|
+
admission named once and never repeated. The bundle's verifier re-derives every admission and
|
|
70
|
+
revision offline.
|
|
71
|
+
|
|
72
|
+
### Fixed
|
|
73
|
+
|
|
74
|
+
- **Check strengthening reads the token budget before every proposal, and asks for no more than
|
|
75
|
+
is left.** The controller checked the budget once at the start of a round, then asked one
|
|
76
|
+
proposal per requirement with a floor of 256 output tokens: with 128 tokens left it asked for
|
|
77
|
+
256, and after that call it asked the next requirement's proposal against nothing. The budget,
|
|
78
|
+
the task's allowance less every recorded model call, is now read before each proposal and
|
|
79
|
+
before the repair; a proposal is asked for at most what is left, never a floor; and a spent
|
|
80
|
+
budget stops the loop where it stands, with the reason recorded (`budget-spent`) and any check
|
|
81
|
+
admitted before the stop kept on the revised contract for the final verification. Usage a
|
|
82
|
+
provider did not report still spends the whole budget, and an uncapped run is unchanged. The
|
|
83
|
+
cap is on requested output; a provider's actual usage, input included, is what the chain
|
|
84
|
+
records and the next check reads. Found by review before the feature was published; no
|
|
85
|
+
released version carried the defect.
|
|
86
|
+
- **Dispatched workers no longer break each other's worktree add**: one worktree command runs at
|
|
87
|
+
a time against a repository. An unrelated worker counts as running from the moment the
|
|
88
|
+
controller admits it, not from its first model call.
|
|
89
|
+
- **The Claude Code hook routes a test command piped through `tail`, `head` or `grep`** (such
|
|
90
|
+
as `npm test 2>&1 | tail -5`) through the verifier and keeps the filters, so the run is
|
|
91
|
+
recorded rather than left alone; any other pipeline or shell syntax is still untouched.
|
|
92
|
+
- **The goal run's final verification is bound to the worker's own recorded diff**, held by a
|
|
93
|
+
regression test.
|
|
2
94
|
|
|
3
95
|
## 14.2.0 - 2026-09-27
|
|
4
96
|
|
package/README.md
CHANGED
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
<div align="center">
|
|
4
4
|
|
|
5
|
-
<h1>
|
|
5
|
+
<h1>Swarm Orchestrator</h1>
|
|
6
6
|
|
|
7
|
-
<p><strong>A coding agent
|
|
7
|
+
<p><strong>A coding agent that must prove its work.</strong></p>
|
|
8
8
|
|
|
9
9
|
<p>
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
It makes bounded repository changes, runs the project's real checks, challenges weak evidence,<br />
|
|
11
|
+
retries failures without trading away test quality, and records what actually happened,<br />
|
|
12
|
+
so the agent's own summary is never the source of truth.
|
|
12
13
|
</p>
|
|
13
14
|
|
|
14
15
|
<p>
|
|
@@ -16,11 +17,13 @@ It cannot make a check pass, mark a claim verified, or change a record after the
|
|
|
16
17
|
·
|
|
17
18
|
<a href="docs/evidence/2026-08-18/live-tasks.md">See a real run</a>
|
|
18
19
|
·
|
|
19
|
-
<a href="https://github.com/moonrunnerkc/swarm-
|
|
20
|
+
<a href="https://github.com/moonrunnerkc/swarm-verify">Swarm Verify, the standalone verifier</a>
|
|
21
|
+
·
|
|
22
|
+
<a href="https://github.com/moonrunnerkc/swarm-orchestrator/issues/new/choose">Report a bug</a>
|
|
20
23
|
</p>
|
|
21
24
|
|
|
22
25
|
[](https://github.com/moonrunnerkc/swarm-orchestrator/actions/workflows/gates.yml)
|
|
23
|
-
[](https://www.npmjs.com/package/swarm-orchestrator)
|
|
24
27
|
[](package.json)
|
|
25
28
|
[](LICENSE)
|
|
26
29
|
|
|
@@ -28,34 +31,50 @@ It cannot make a check pass, mark a claim verified, or change a record after the
|
|
|
28
31
|
|
|
29
32
|
---
|
|
30
33
|
|
|
31
|
-
## What it
|
|
32
|
-
|
|
33
|
-
`swarm` takes a task and a git repository,
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
its
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
Node/Python initialization and selected packages; CLI, local HTTP and optional Playwright checks;
|
|
51
|
-
one explicit escalation; and bugfix, refactor and dependency-upgrade presets. The full and
|
|
52
|
-
standalone CLIs share the verifier. [Delivery evidence](docs/upgrade-completion.md) distinguishes
|
|
53
|
-
implemented source, exact-source validation and remote delivery. These additions are not an
|
|
54
|
-
npm publication; use the documented source tarball installation until a release is verified.
|
|
34
|
+
## What it does
|
|
35
|
+
|
|
36
|
+
`swarm` takes a task and a git repository. It plans, declares the files it intends to touch,
|
|
37
|
+
edits through one recording chokepoint, runs your project's checks as sealed gates, and retries
|
|
38
|
+
failures under a ratchet that refuses a fix which trades away tests, assertions or coverage.
|
|
39
|
+
When the gates pass it exports a signed, hash-chained evidence bundle that carries its own
|
|
40
|
+
dependency-free verifier, so anyone can check what ran, and what passed, with nothing but Node
|
|
41
|
+
and without trusting the machine that produced it.
|
|
42
|
+
|
|
43
|
+
```text
|
|
44
|
+
task
|
|
45
|
+
-> the agent plans and declares its files
|
|
46
|
+
-> a bounded change, every tool call recorded
|
|
47
|
+
-> the project's checks run as sealed gates
|
|
48
|
+
-> weak evidence is challenged: a passing check must be shown able to fail
|
|
49
|
+
-> the ratchet: a retry may not trade away tests, assertions or coverage
|
|
50
|
+
-> retry, accept, or refuse with the reason on the record
|
|
51
|
+
-> evidence: a signed bundle anyone can verify offline
|
|
52
|
+
```
|
|
55
53
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
Here is a real run, committed: [`live-tasks.md`](docs/evidence/2026-08-18/live-tasks.md),
|
|
55
|
+
with its bundle in [`live-frontier/`](docs/evidence/2026-08-18/live-frontier). And here is the
|
|
56
|
+
packaged tool doing it, installed from a tarball into a directory holding nothing else, against
|
|
57
|
+
a workspace it had never seen, recorded in a real terminal:
|
|
58
|
+
[`installed-package-run.md`](docs/evidence/2026-08-23/installed-package-run.md).
|
|
59
|
+
|
|
60
|
+
## Why it is not an ordinary coding agent
|
|
61
|
+
|
|
62
|
+
The model can say whatever it likes. It cannot make a check pass, mark a claim verified, or
|
|
63
|
+
change a record after the fact. Those are the harness's to decide.
|
|
64
|
+
|
|
65
|
+
- **A claim is not evidence.** A structured claim the model makes names a predicate and a
|
|
66
|
+
record; the harness evaluates it against its own records and renders the verdict. Narrative
|
|
67
|
+
never renders green, and a claim the harness cannot evaluate renders `UNVERIFIED` without
|
|
68
|
+
stopping the run.
|
|
69
|
+
- **A pass must be able to fail.** Each passing gate is handed one fixture it has to refuse,
|
|
70
|
+
so a check that cannot fail is caught rather than counted.
|
|
71
|
+
- **A retry cannot buy green by deleting tests.** Tests collected, assertions in touched tests
|
|
72
|
+
and covered changed lines cannot decrease across retries; skips cannot increase.
|
|
73
|
+
- **Regression and task acceptance are two answers.** A suite passing says nothing broke. Only
|
|
74
|
+
a requirement contract or an acceptance check you supply can say the work was done, and the
|
|
75
|
+
tool reports when neither was given.
|
|
76
|
+
- **Unmeasured is a verdict.** Nobody checked is not the same as checked and passed, and it is
|
|
77
|
+
never rendered as a pass.
|
|
59
78
|
|
|
60
79
|
## Install
|
|
61
80
|
|
|
@@ -63,13 +82,15 @@ required checks prevent complete verification. See the linked broad-use guide fo
|
|
|
63
82
|
npm install -g swarm-orchestrator
|
|
64
83
|
```
|
|
65
84
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
85
|
+
This installs the registry’s `latest` release and leaves `swarm` on your path.
|
|
86
|
+
The source version is **14.4.0**; publication is tracked in
|
|
87
|
+
[the delivery record](docs/release-delivery-2026-10-10.md). It runs on Node 22 or newer; Node 24 or
|
|
88
|
+
newer is recommended, because the changed-line coverage measurement spawns Node's test runner
|
|
89
|
+
with process isolation, which Node 22 below 22.8 rejects. Below that, the measurement reports
|
|
90
|
+
unmeasured and never counts as a pass. `swarm doctor` says which Node it found and what owns
|
|
91
|
+
the `swarm` command, and `--fix` repairs an install that an older build is shadowing.
|
|
71
92
|
|
|
72
|
-
##
|
|
93
|
+
## Run one task
|
|
73
94
|
|
|
74
95
|
```sh
|
|
75
96
|
export ANTHROPIC_API_KEY=... # or OPENAI_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY,
|
|
@@ -80,43 +101,53 @@ swarm "make slugify collapse whitespace and strip punctuation"
|
|
|
80
101
|
|
|
81
102
|
Keys come from the environment or your OS keychain, never from `swarm.toml`: that file is
|
|
82
103
|
committed and cloned, so a key in it has already been shared with everyone holding the
|
|
83
|
-
repository.
|
|
104
|
+
repository. The run shows each step, each gate and each retry as it happens, and ends on the
|
|
105
|
+
evidence panel. `swarm review <bundle>` opens a run's review page later; `swarm verify <bundle>`
|
|
106
|
+
checks its integrity and who signed it. Every command and flag is in
|
|
107
|
+
[docs/cli.md](docs/cli.md); sessions, several workers at once and the screen are in
|
|
108
|
+
[docs/using.md](docs/using.md).
|
|
84
109
|
|
|
85
110
|
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
86
111
|
|
|
87
|
-
##
|
|
112
|
+
## What verification happens
|
|
88
113
|
|
|
89
114
|
Every tool call and every check goes through one recording chokepoint, and the record is an
|
|
90
|
-
append-only, hash-chained ledger that lives outside the workspace.
|
|
91
|
-
|
|
92
|
-
|
|
115
|
+
append-only, hash-chained ledger that lives outside the workspace. The gates, their severities,
|
|
116
|
+
their parsers and the budgets are sealed before the first model call, so nothing the model
|
|
117
|
+
does during the run can change what it is measured against.
|
|
93
118
|
|
|
94
|
-
|
|
119
|
+
Six words carry most of the weight. A **gate** is a check declared as data: a command, a
|
|
95
120
|
parser, and whether it blocks. The **ratchet** is the rule that a retry may not trade away
|
|
96
121
|
tests, assertions or coverage to turn a gate green. A **bond** is one file a passing gate is
|
|
97
122
|
handed that it must refuse, so a pass that cannot fail is caught. An **oracle** is the check
|
|
98
123
|
you supply that says the task was done, as distinct from nothing broke. **Reach** is whether
|
|
99
|
-
that oracle executed the lines a patch added. And **unmeasured** is a verdict of its own
|
|
100
|
-
|
|
124
|
+
that oracle executed the lines a patch added. And **unmeasured** is a verdict of its own.
|
|
125
|
+
|
|
126
|
+
With a goal contract (`--goal-contract`), the contract's own checks are challenged
|
|
127
|
+
(`--challenges report|required`): a base control per requirement, mechanical mutations of the
|
|
128
|
+
changed lines witnessed by the suite, and sealed fixtures, so a check that could not have
|
|
129
|
+
caught wrong work is named. With `--strengthen`, the model may propose one additive check per
|
|
130
|
+
witnessed gap; the harness admits it only where it observes the check reject the counterexample
|
|
131
|
+
and accept every sealed reference, then repairs the code under the revised contract. Nothing is
|
|
132
|
+
asked of the model before the criteria are sealed.
|
|
101
133
|
|
|
102
134
|
The mechanics, the nine-answer report and worked examples are in
|
|
103
|
-
[docs/verifying.md](docs/verifying.md).
|
|
104
|
-
|
|
135
|
+
[docs/verifying.md](docs/verifying.md). The goal contracts, presets and package scope are in
|
|
136
|
+
[docs/broad-use.md](docs/broad-use.md).
|
|
105
137
|
|
|
106
|
-
##
|
|
138
|
+
## What evidence is produced
|
|
107
139
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
none of the agent. The walkthrough, over the committed tamper demo, and the install for the
|
|
113
|
-
standalone package are in [docs/verify-only.md](docs/verify-only.md).
|
|
140
|
+
A run writes its ledger under `~/.swarm/sessions`, never inside the workspace, and exports a
|
|
141
|
+
bundle: the manifest with the chain head and the signature, the records, every blob by
|
|
142
|
+
SHA-256, the review page, the summary, and `verify.mjs`, a dependency-free verifier that
|
|
143
|
+
re-derives every verdict from the records alone.
|
|
114
144
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
145
|
+
```sh
|
|
146
|
+
node <bundle>/verify.mjs <bundle> # anywhere, nothing installed
|
|
147
|
+
swarm verify <bundle> --signer <fp> # here, with the signer judged too
|
|
148
|
+
```
|
|
118
149
|
|
|
119
|
-
Every number here links to the committed artifact of the thing happening
|
|
150
|
+
Every number here links to the committed artifact of the thing happening; the full table, and
|
|
120
151
|
the list of things that may not be said, is [docs/claims.md](docs/claims.md).
|
|
121
152
|
|
|
122
153
|
- **One changed byte breaks verification.** The same bundle verified and then tampered with in
|
|
@@ -128,32 +159,21 @@ the list of things that may not be said, is [docs/claims.md](docs/claims.md).
|
|
|
128
159
|
- **A green verdict is computed by the harness, and the model cannot produce one.** In a real
|
|
129
160
|
run the model asserted a predicate the language does not parse; the harness rendered it
|
|
130
161
|
`UNVERIFIED` and carried on, twice: [shakedown results](docs/evidence/2026-08-18/shakedown/results.md).
|
|
131
|
-
- **A suite passing is not the task being done.** Four of eighteen
|
|
132
|
-
|
|
133
|
-
|
|
162
|
+
- **A suite passing is not the task being done.** Four of eighteen patches this project's own
|
|
163
|
+
agent and a baseline arm produced over three public TypeScript repositories passed their
|
|
164
|
+
project's whole suite and failed a hidden acceptance test, which is why `regression` and
|
|
165
|
+
`task` are two answers: [docs/verifying.md](docs/verifying.md). That is a measurement of
|
|
166
|
+
those eighteen patches, not a rate for AI-written changes in general.
|
|
134
167
|
- **The oracle is judged too.** Certified tasks turned out to rest on oracles that could not
|
|
135
|
-
fail
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
-
|
|
140
|
-
two oracles per task, one handed to the tool and one held back:
|
|
141
|
-
[mined-corpus](docs/evidence/2026-09-06/mined-corpus/README.md). The denominator moved when
|
|
142
|
-
the tool did: four patches both oracles accept are refused because the tool's own oracle never
|
|
143
|
-
ran part of what they changed, five because the sealed half rejects work the held-back half
|
|
144
|
-
accepts, and one because its oracle accepted a change to a line it had run.
|
|
145
|
-
- **Twelve tasks reported as unjudgeable were the agent having written nothing at all**, which
|
|
146
|
-
is a model failure and is recorded as one. An earlier 0-of-18 was withdrawn rather than
|
|
147
|
-
corrected quietly: the same test was handed to the tool and then used as the ground truth it
|
|
148
|
-
was scored against, so it agreed with itself:
|
|
149
|
-
[false-green-measurement.md](docs/evidence/2026-09-05/false-green-measurement.md).
|
|
150
|
-
- **Of the gates this project agreed not to call itself production-ready without**, the
|
|
151
|
-
historical assessment records eight passing, two partial, two unproven, and two reported
|
|
152
|
-
rather than barred: [docs/beta-gates.md](docs/beta-gates.md).
|
|
168
|
+
fail; the last false green standing was refused because its oracle accepted a change to a
|
|
169
|
+
line it had run: [docs/verifying.md](docs/verifying.md#the-oracle-is-judged-too).
|
|
170
|
+
- **The September 6 mined-corpus false-green rate was 0 in 15**, 95% CI [0.0, 20.4], with two
|
|
171
|
+
oracles per task, one handed to the tool and one held back:
|
|
172
|
+
[mined-corpus](docs/evidence/2026-09-06/mined-corpus/README.md).
|
|
153
173
|
|
|
154
174
|
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
155
175
|
|
|
156
|
-
## What
|
|
176
|
+
## What it does not prove
|
|
157
177
|
|
|
158
178
|
The five that matter most. The full list is in
|
|
159
179
|
[docs/verifying.md](docs/verifying.md#what-is-not-claimed).
|
|
@@ -168,56 +188,52 @@ The five that matter most. The full list is in
|
|
|
168
188
|
and recorded on the chain rather than quietly assumed, but it is not containment.
|
|
169
189
|
- **0 in 15 says "under 20%", not "zero".** That upper bound is the honest half of the rate,
|
|
170
190
|
and it is a rate for that corpus and that build, not for this one.
|
|
171
|
-
- **Shown its oracle, a model still gets past this.**
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
patch left out, and that is what an adversarial patch does.
|
|
191
|
+
- **Shown its oracle, a model still gets past this.** Bonding and challenges ask whether the
|
|
192
|
+
checks judged what the patch added. They cannot ask what the patch left out, and that is
|
|
193
|
+
what an adversarial patch does.
|
|
175
194
|
|
|
176
195
|
Gates prove mechanical quality, not design quality. What a bundle buys you is that reviewing the
|
|
177
196
|
change is fast and its claims are checkable, not that review is unnecessary.
|
|
178
197
|
|
|
179
|
-
|
|
198
|
+
## Swarm Verify, the standalone verifier
|
|
199
|
+
|
|
200
|
+
The verification the agent is held to is a product of its own. [Swarm Verify](https://github.com/moonrunnerkc/swarm-verify)
|
|
201
|
+
checks a change from any source, this agent, Claude Code, Codex, Copilot, another agent or a
|
|
202
|
+
person, with no model, no key and no configuration:
|
|
203
|
+
|
|
204
|
+
```sh
|
|
205
|
+
npx swarm-verify # run a repository's declared checks and report what that establishes
|
|
206
|
+
npx swarm-verify ci --pr owner/repo#123 # verify a pull request in a fresh checkout of its base
|
|
207
|
+
npx swarm-verify verify <bundle> --signer <fp> # check a bundle this agent, or anything else, produced
|
|
208
|
+
```
|
|
180
209
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
- [x] Build the campaign machinery: separate case author, checker and solver models; admission
|
|
191
|
-
controls before grading; frozen schedules; actual baseline dispatch; every failed launch
|
|
192
|
-
retained; raw evidence that can be checked from the checkout.
|
|
193
|
-
- [x] Run the available Docker security and cleanup matrix. Fourteen declared observations
|
|
194
|
-
passed, with working attack controls and a separate check that ordinary work still runs.
|
|
195
|
-
Repair after abrupt harness death was exercised too.
|
|
196
|
-
- [ ] A false-green interval that supports a population claim. The historical 0 in 15 has a
|
|
197
|
-
20.4% upper bound. The new synthetic pilot admits one evaluation case and cannot narrow
|
|
198
|
-
that bound for real work. Freeze an independent population and a sufficient sample first.
|
|
199
|
-
- [ ] A denominator the tool did not choose. The new admission pass checks references and
|
|
200
|
-
predetermined counterexamples, but model authorship alone does not establish independence
|
|
201
|
-
or complete requirements. Independent admission and review are still needed.
|
|
202
|
-
- [ ] An adversarial verification corpus that covers omitted requirements. Separate local
|
|
203
|
-
models supplied fresh checks and attacks. Mutation of added lines still cannot establish
|
|
204
|
-
that a patch implemented something it left out; the report keeps those outcomes visible.
|
|
205
|
-
- [ ] Task success non-inferior to the strongest alternative. The two local baseline arms now
|
|
206
|
-
execute, with matched tasks and budgets. This pilot is too small to establish which tool
|
|
207
|
-
is strongest or to support a non-inferiority claim.
|
|
208
|
-
- [ ] Security evidence for every supported backend. Docker was measured here; Podman and
|
|
209
|
-
nerdctl were unavailable. Independent attacks and those runtime matrices remain open.
|
|
210
|
-
- [ ] No surviving daemons across the supported runtime boundaries. Docker cleanup passed the
|
|
211
|
-
declared lifecycle cases. Restricted host execution still cannot own a descendant that
|
|
212
|
-
leaves its process group; abrupt harness death requires supervision or later repair.
|
|
213
|
-
- [ ] A new user productive in under ten minutes. The fixture and observer procedure are ready.
|
|
214
|
-
No new users were observed, so setup checks cannot close this item.
|
|
215
|
-
|
|
216
|
-
Each broader claim stays open until its own evidence meets the bar in
|
|
217
|
-
[docs/beta-gates.md](docs/beta-gates.md).
|
|
210
|
+
It also ships as the GitHub Action `moonrunnerkc/swarm-verify@v1`, a Claude Code hook, an MCP
|
|
211
|
+
server and a pre-commit hook. The same commands are in the `swarm` binary: `swarm check`,
|
|
212
|
+
`swarm ci`, `swarm verify`, `swarm verdict` and `swarm gates` need no model, and
|
|
213
|
+
[docs/verify-only.md](docs/verify-only.md) walks through them over committed artifacts.
|
|
214
|
+
|
|
215
|
+
There is one implementation. The `swarm-verify` package is built from this repository's
|
|
216
|
+
verification modules under [packages/swarm-verify](packages/swarm-verify), behind a build-time
|
|
217
|
+
boundary that refuses any provider, worker or screen module; the agent composes those same
|
|
218
|
+
modules. Swarm Orchestrator uses Swarm Verify. It is not Swarm Verify.
|
|
218
219
|
|
|
219
220
|
<p align="right">(<a href="#readme-top">back to top</a>)</p>
|
|
220
221
|
|
|
222
|
+
## Versions
|
|
223
|
+
|
|
224
|
+
The package name has carried three different programs, and the majors are the boundary:
|
|
225
|
+
|
|
226
|
+
| Versions | What it was |
|
|
227
|
+
| --- | --- |
|
|
228
|
+
| 8.x | a contract-first coding orchestrator: a goal compiled to typed obligations, persona candidates raced per obligation, verifier-gated commits, a hash-chained ledger |
|
|
229
|
+
| 10.x to 12.x | a pull-request auditor: static cheat-pattern detectors over AI-written diffs, advisory by default, with a merge gate. The last of that line is the `v12-final` tag |
|
|
230
|
+
| 13.x and later | this coding agent, with no migration path from 12.x and nothing of its interface |
|
|
231
|
+
| 14.1.0 | the verification path extracted as the `swarm-verify` package, the same code with none of the agent |
|
|
232
|
+
| 14.3.0 | the README and repository description presented Swarm Verify as this repository's product and the agent as a beta mode; 14.4.0 restores the agent as the product of this repository and gives the verifier its own home |
|
|
233
|
+
|
|
234
|
+
Pin a major. Each release names the verifier version it carries in [CHANGELOG.md](CHANGELOG.md);
|
|
235
|
+
the verifier's own changelog is [packages/swarm-verify/CHANGELOG.md](packages/swarm-verify/CHANGELOG.md).
|
|
236
|
+
|
|
221
237
|
## Contributing
|
|
222
238
|
|
|
223
239
|
The bar is the one the tool applies to itself: `npm run gates` green with the output shown, new
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { copyFileSync, lstatSync, mkdirSync, readdirSync, readFileSync, writeFileSync, } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
const byteLimit = 32_000_000;
|
|
5
|
+
const fileByteLimit = 8_000_000;
|
|
6
|
+
const fileLimit = 4096;
|
|
7
|
+
const depthLimit = 8;
|
|
8
|
+
/** Copy the named entries of `directory` under `directory/retained`, within the bounds. */
|
|
9
|
+
export function retainActionArtifacts(directory, names = [
|
|
10
|
+
"bundle",
|
|
11
|
+
"report.json",
|
|
12
|
+
"summary.md",
|
|
13
|
+
"verdict.json",
|
|
14
|
+
"attestation",
|
|
15
|
+
"diagnostic.txt",
|
|
16
|
+
]) {
|
|
17
|
+
const destination = join(directory, "retained");
|
|
18
|
+
mkdirSync(destination, { mode: 0o700, recursive: true });
|
|
19
|
+
const inventory = [];
|
|
20
|
+
let remaining = byteLimit;
|
|
21
|
+
let complete = true;
|
|
22
|
+
const visit = (path, relative, depth) => {
|
|
23
|
+
if (depth > depthLimit || inventory.length >= fileLimit) {
|
|
24
|
+
complete = false;
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const stat = lstatSync(path);
|
|
28
|
+
if (stat.isDirectory()) {
|
|
29
|
+
mkdirSync(join(destination, relative), { recursive: true, mode: 0o700 });
|
|
30
|
+
for (const name of readdirSync(path))
|
|
31
|
+
visit(join(path, name), join(relative, name), depth + 1);
|
|
32
|
+
}
|
|
33
|
+
else if (stat.isFile() && stat.size <= fileByteLimit && stat.size <= remaining) {
|
|
34
|
+
const bytes = readFileSync(path);
|
|
35
|
+
const digest = `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
|
|
36
|
+
copyFileSync(path, join(destination, relative));
|
|
37
|
+
remaining -= bytes.length;
|
|
38
|
+
inventory.push({ path: relative, bytes: bytes.length, digest, retained: true });
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
complete = false;
|
|
42
|
+
inventory.push({
|
|
43
|
+
path: relative,
|
|
44
|
+
bytes: stat.size,
|
|
45
|
+
retained: false,
|
|
46
|
+
reason: "retention bound or unsupported file type",
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
for (const name of names) {
|
|
51
|
+
try {
|
|
52
|
+
lstatSync(join(directory, name));
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
visit(join(directory, name), name, 0);
|
|
59
|
+
}
|
|
60
|
+
catch (cause) {
|
|
61
|
+
complete = false;
|
|
62
|
+
inventory.push({
|
|
63
|
+
path: name,
|
|
64
|
+
retained: false,
|
|
65
|
+
reason: cause.code ?? "copy failed",
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
writeFileSync(join(destination, "retention.json"), JSON.stringify({ version: 1, complete, byteLimit, fileLimit, inventory }, null, 2), { mode: 0o600 });
|
|
70
|
+
return { destination, complete, inventory };
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=artifacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../src/action/artifacts.ts"],"names":[],"mappings":"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"}
|