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.
Files changed (192) hide show
  1. package/CHANGELOG.md +93 -1
  2. package/README.md +140 -124
  3. package/dist/action/artifacts.js +72 -0
  4. package/dist/action/artifacts.js.map +1 -0
  5. package/dist/action/comment.js +139 -0
  6. package/dist/action/comment.js.map +1 -0
  7. package/dist/action/environment.js +106 -0
  8. package/dist/action/environment.js.map +1 -0
  9. package/dist/action/verdict.js +103 -0
  10. package/dist/action/verdict.js.map +1 -0
  11. package/dist/action/verify.js +424 -0
  12. package/dist/action/verify.js.map +1 -0
  13. package/dist/cli-action.js +117 -0
  14. package/dist/cli-action.js.map +1 -0
  15. package/dist/cli-check.js +341 -0
  16. package/dist/cli-check.js.map +1 -0
  17. package/dist/cli-ci.js +27 -3
  18. package/dist/cli-ci.js.map +1 -1
  19. package/dist/cli-command-definitions.js +43 -1
  20. package/dist/cli-command-definitions.js.map +1 -1
  21. package/dist/cli-gates.js +33 -10
  22. package/dist/cli-gates.js.map +1 -1
  23. package/dist/cli-integrations.js +145 -0
  24. package/dist/cli-integrations.js.map +1 -0
  25. package/dist/cli-options.js +32 -0
  26. package/dist/cli-options.js.map +1 -1
  27. package/dist/cli-strengthen.js +527 -0
  28. package/dist/cli-strengthen.js.map +1 -0
  29. package/dist/cli-task-goal.js +58 -9
  30. package/dist/cli-task-goal.js.map +1 -1
  31. package/dist/cli-verdict.js +144 -0
  32. package/dist/cli-verdict.js.map +1 -0
  33. package/dist/cli-verify-options.js +85 -0
  34. package/dist/cli-verify-options.js.map +1 -1
  35. package/dist/cli.js +82 -8
  36. package/dist/cli.js.map +1 -1
  37. package/dist/config/init.js +1 -1
  38. package/dist/config/init.js.map +1 -1
  39. package/dist/config/package-discovery.js +47 -1
  40. package/dist/config/package-discovery.js.map +1 -1
  41. package/dist/durable/recovery-context.js +3 -2
  42. package/dist/durable/recovery-context.js.map +1 -1
  43. package/dist/evidence/blob-manifest.js +9 -0
  44. package/dist/evidence/blob-manifest.js.map +1 -1
  45. package/dist/evidence/bundle.js +17 -2
  46. package/dist/evidence/bundle.js.map +1 -1
  47. package/dist/evidence/challenge-lines.js +21 -0
  48. package/dist/evidence/challenge-lines.js.map +1 -0
  49. package/dist/evidence/ci-summary.js +5 -1
  50. package/dist/evidence/ci-summary.js.map +1 -1
  51. package/dist/evidence/goal-contract.js +132 -1
  52. package/dist/evidence/goal-contract.js.map +1 -1
  53. package/dist/evidence/signing.js +3 -1
  54. package/dist/evidence/signing.js.map +1 -1
  55. package/dist/evidence/verifier/challenges.d.mts +19 -0
  56. package/dist/evidence/verifier/challenges.mjs +203 -0
  57. package/dist/evidence/verifier/rederive.mjs +20 -2
  58. package/dist/evidence/verifier/status.d.mts +2 -0
  59. package/dist/evidence/verifier/status.mjs +638 -38
  60. package/dist/evidence/verifier/strengthening.d.mts +18 -0
  61. package/dist/evidence/verifier/strengthening.mjs +200 -0
  62. package/dist/evidence/verifier/upgrade.mjs +1 -0
  63. package/dist/evidence/verifier/verify.mjs +25 -1
  64. package/dist/exec/child-environment.js +30 -0
  65. package/dist/exec/child-environment.js.map +1 -1
  66. package/dist/exec/container-backend.js +103 -12
  67. package/dist/exec/container-backend.js.map +1 -1
  68. package/dist/exec/controlled-network.js +20 -1
  69. package/dist/exec/controlled-network.js.map +1 -1
  70. package/dist/exec/execution-mode.js +25 -13
  71. package/dist/exec/execution-mode.js.map +1 -1
  72. package/dist/exec/runtime-resource.js +6 -1
  73. package/dist/exec/runtime-resource.js.map +1 -1
  74. package/dist/gates/base-control.js +7 -2
  75. package/dist/gates/base-control.js.map +1 -1
  76. package/dist/gates/certification.js +4 -0
  77. package/dist/gates/certification.js.map +1 -1
  78. package/dist/gates/change-source.js +29 -29
  79. package/dist/gates/change-source.js.map +1 -1
  80. package/dist/gates/check-admission.js +218 -0
  81. package/dist/gates/check-admission.js.map +1 -0
  82. package/dist/gates/check-network-probe.js +42 -0
  83. package/dist/gates/check-network-probe.js.map +1 -0
  84. package/dist/gates/check-plan.js +269 -0
  85. package/dist/gates/check-plan.js.map +1 -0
  86. package/dist/gates/checkout-environment.js +119 -0
  87. package/dist/gates/checkout-environment.js.map +1 -0
  88. package/dist/gates/contract-executor.js +7 -4
  89. package/dist/gates/contract-executor.js.map +1 -1
  90. package/dist/gates/default-gates.js +2 -2
  91. package/dist/gates/default-gates.js.map +1 -1
  92. package/dist/gates/deferred-setup.js +250 -0
  93. package/dist/gates/deferred-setup.js.map +1 -0
  94. package/dist/gates/dependency-install.js +200 -41
  95. package/dist/gates/dependency-install.js.map +1 -1
  96. package/dist/gates/engine.js +7 -1
  97. package/dist/gates/engine.js.map +1 -1
  98. package/dist/gates/failure-attribution.js +444 -0
  99. package/dist/gates/failure-attribution.js.map +1 -0
  100. package/dist/gates/gate-definition.js.map +1 -1
  101. package/dist/gates/gate-runner.js +31 -5
  102. package/dist/gates/gate-runner.js.map +1 -1
  103. package/dist/gates/git-workspace.js +36 -5
  104. package/dist/gates/git-workspace.js.map +1 -1
  105. package/dist/gates/goal-challenge-runner.js +99 -0
  106. package/dist/gates/goal-challenge-runner.js.map +1 -0
  107. package/dist/gates/goal-challenges.js +337 -0
  108. package/dist/gates/goal-challenges.js.map +1 -0
  109. package/dist/gates/harness-reporting.js +7 -3
  110. package/dist/gates/harness-reporting.js.map +1 -1
  111. package/dist/gates/independent-checks.js +63 -2
  112. package/dist/gates/independent-checks.js.map +1 -1
  113. package/dist/gates/independent-verification.js +569 -82
  114. package/dist/gates/independent-verification.js.map +1 -1
  115. package/dist/gates/inspection-gates.js +5 -5
  116. package/dist/gates/inspection-gates.js.map +1 -1
  117. package/dist/gates/instrument-dependencies.js +249 -0
  118. package/dist/gates/instrument-dependencies.js.map +1 -0
  119. package/dist/gates/instrument-identity.js +794 -0
  120. package/dist/gates/instrument-identity.js.map +1 -0
  121. package/dist/gates/mutant-parse.js +23 -0
  122. package/dist/gates/mutant-parse.js.map +1 -1
  123. package/dist/gates/node-command-runner.js +16 -2
  124. package/dist/gates/node-command-runner.js.map +1 -1
  125. package/dist/gates/node-gates.js +39 -8
  126. package/dist/gates/node-gates.js.map +1 -1
  127. package/dist/gates/node-test-command.js +22 -4
  128. package/dist/gates/node-test-command.js.map +1 -1
  129. package/dist/gates/noninteractive-runner.js +106 -0
  130. package/dist/gates/noninteractive-runner.js.map +1 -0
  131. package/dist/gates/oracle-instrumentation.js +1 -4
  132. package/dist/gates/oracle-instrumentation.js.map +1 -1
  133. package/dist/gates/oracle-mutants.js +13 -3
  134. package/dist/gates/oracle-mutants.js.map +1 -1
  135. package/dist/gates/parsers.js +110 -4
  136. package/dist/gates/parsers.js.map +1 -1
  137. package/dist/gates/patch-paths.js +304 -14
  138. package/dist/gates/patch-paths.js.map +1 -1
  139. package/dist/gates/prepare-dependencies.js +2 -0
  140. package/dist/gates/prepare-dependencies.js.map +1 -1
  141. package/dist/gates/prepared-tools.js +18 -0
  142. package/dist/gates/prepared-tools.js.map +1 -0
  143. package/dist/gates/project-environment.js +1 -0
  144. package/dist/gates/project-environment.js.map +1 -1
  145. package/dist/gates/project-type.js +131 -14
  146. package/dist/gates/project-type.js.map +1 -1
  147. package/dist/gates/python-gates.js +58 -32
  148. package/dist/gates/python-gates.js.map +1 -1
  149. package/dist/gates/python-mutants.js +176 -0
  150. package/dist/gates/python-mutants.js.map +1 -0
  151. package/dist/gates/python-offline-build.js +274 -0
  152. package/dist/gates/python-offline-build.js.map +1 -0
  153. package/dist/gates/runner-results.js +96 -23
  154. package/dist/gates/runner-results.js.map +1 -1
  155. package/dist/gates/scratch-index.js +112 -3
  156. package/dist/gates/scratch-index.js.map +1 -1
  157. package/dist/gates/setup-effect.js +16 -0
  158. package/dist/gates/setup-effect.js.map +1 -0
  159. package/dist/gates/setup-follow-up.js +113 -0
  160. package/dist/gates/setup-follow-up.js.map +1 -0
  161. package/dist/gates/structured-runner.js +37 -8
  162. package/dist/gates/structured-runner.js.map +1 -1
  163. package/dist/gates/unified-diff.js +39 -9
  164. package/dist/gates/unified-diff.js.map +1 -1
  165. package/dist/gates/upgrade-contract.js +1 -0
  166. package/dist/gates/upgrade-contract.js.map +1 -1
  167. package/dist/gates/upgrade-resolution.js +8 -1
  168. package/dist/gates/upgrade-resolution.js.map +1 -1
  169. package/dist/install/health.js +3 -3
  170. package/dist/install/health.js.map +1 -1
  171. package/dist/integrations/claude-hook.js +200 -0
  172. package/dist/integrations/claude-hook.js.map +1 -0
  173. package/dist/integrations/launcher.js +17 -0
  174. package/dist/integrations/launcher.js.map +1 -0
  175. package/dist/integrations/mcp-server.js +270 -0
  176. package/dist/integrations/mcp-server.js.map +1 -0
  177. package/dist/integrations/pre-commit.js +169 -0
  178. package/dist/integrations/pre-commit.js.map +1 -0
  179. package/dist/machine-output.js +1 -0
  180. package/dist/machine-output.js.map +1 -1
  181. package/dist/node-floor.js +46 -17
  182. package/dist/node-floor.js.map +1 -1
  183. package/dist/swarm-verify.js +30 -5
  184. package/dist/swarm-verify.js.map +1 -1
  185. package/dist/workers/bootstrap-history.js +4 -3
  186. package/dist/workers/bootstrap-history.js.map +1 -1
  187. package/dist/workers/worktree.js +72 -30
  188. package/dist/workers/worktree.js.map +1 -1
  189. package/docs/README.md +17 -3
  190. package/docs/claims.md +31 -7
  191. package/docs/security-coverage.md +3 -1
  192. 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>swarm-orchestrator</h1>
5
+ <h1>Swarm Orchestrator</h1>
6
6
 
7
- <p><strong>A coding agent for the terminal that leaves a signed, offline-checkable record of what it ran and what passed.</strong></p>
7
+ <p><strong>A coding agent that must prove its work.</strong></p>
8
8
 
9
9
  <p>
10
- The model can say whatever it likes.<br />
11
- It cannot make a check pass, mark a claim verified, or change a record after the fact.
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-orchestrator/issues/new?labels=bug">Report a bug</a>
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
  [![gates](https://img.shields.io/github/actions/workflow/status/moonrunnerkc/swarm-orchestrator/gates.yml?branch=v13-main&style=for-the-badge&label=gates)](https://github.com/moonrunnerkc/swarm-orchestrator/actions/workflows/gates.yml)
23
- [![npm](https://img.shields.io/npm/v/swarm-orchestrator?style=for-the-badge&label=npm&color=CB3837)](https://www.npmjs.com/package/swarm-orchestrator)
26
+ [![npm](https://img.shields.io/npm/v/swarm-orchestrator?style=for-the-badge&label=swarm-orchestrator&color=CB3837)](https://www.npmjs.com/package/swarm-orchestrator)
24
27
  [![node](https://img.shields.io/badge/node-%E2%89%A522-5FA04E?style=for-the-badge)](package.json)
25
28
  [![license](https://img.shields.io/badge/license-ISC-blue?style=for-the-badge)](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 is
32
-
33
- `swarm` takes a task and a git repository, makes a bounded change, runs your project's checks
34
- over it, and writes a record of every command it ran and every check that passed or failed.
35
- The record is a hash-chained ledger, exported as a signed bundle that carries its own
36
- dependency-free verifier, so anyone can check it later with nothing but Node and without
37
- trusting the machine that produced it.
38
-
39
- It is for two kinds of people. Engineers who want an agent to make a change and want to review
40
- what it did from evidence rather than from the agent's own summary. And reviewers who are handed
41
- somebody else's patch or bundle and need to check it without installing the agent or believing
42
- its author.
43
-
44
- **Upgrading from 12.x?** That was a pull-request auditor; 13 and later are a coding agent under
45
- the same package name, with no migration path. Stay on the `v12-final` tag, or pin the major.
46
-
47
- ## Source upgrade workflows
48
-
49
- The [broad-use source guide](docs/broad-use.md) covers model-free patch, branch and PR verification;
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
- Browser acceptance requires a sealed `instrument` and an immutable Playwright container runtime.
57
- Project `argv` reports remain unjudged. Unavailable package checks remain visible; missing
58
- required checks prevent complete verification. See the linked broad-use guide for migration.
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
- That is **14.1.0**. It runs on Node 22 or newer. Node 24 or newer is recommended, because the
67
- changed-line coverage measurement spawns node's test runner with `--test-isolation=process`,
68
- which Node 22 rejects; below 24 that one measurement reports unmeasured and never counts as a
69
- pass. `swarm doctor` says which Node it found and what owns the `swarm` command, and `--fix`
70
- repairs an install that an older build is shadowing.
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
- ## Try it
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. Every command and flag is in [docs/cli.md](docs/cli.md).
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
- ## How it verifies
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. When a run ends it is
91
- exported as a signed bundle carrying a dependency-free verifier, so the bundle can be checked
92
- anywhere with plain Node.
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
- Five words carry most of the weight. A **gate** is a check declared as data: a command, a
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
- nobody checked is not the same as checked and passed, and it never renders green.
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). Retries under the ratchet, sessions and several workers
104
- at once are in [docs/using.md](docs/using.md).
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
- ## Use it without a model
138
+ ## What evidence is produced
107
139
 
108
- Three commands need no model, no API key and no local backend. `swarm gates` measures a
109
- workspace, `swarm ci --patch <file>` verifies a patch in a fresh checkout of its base, and
110
- `swarm verify <bundle>` checks a bundle and who signed it. They also ship on their own as the
111
- `swarm-verify` package under [packages/swarm-verify](packages/swarm-verify), the same code with
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
- <p align="right">(<a href="#readme-top">back to top</a>)</p>
116
-
117
- ## Measured
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. The full table, and
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 real-repository patches
132
- passed their project's whole suite and failed a hidden acceptance test, which is why `swarm ci`
133
- reports `regression` and `task` as two answers: [docs/verifying.md](docs/verifying.md).
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. The last false green standing, `commander#1671`, was certified by an oracle that runs
136
- every line the patch adds and never tests the precedence those lines decide; it is refused now
137
- because that oracle accepted a change to a line it had run:
138
- [docs/verifying.md](docs/verifying.md#the-oracle-is-judged-too).
139
- - **The September 6 mined-corpus false-green rate was 0 in 15**, 0.0%, 95% CI [0.0, 20.4], with
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 is not claimed
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.** A patch written to satisfy a visible test
172
- has its added lines tested by that test, so the oracle refuses every mutant of them and is
173
- right to. Bonding asks whether the oracle judged what the patch added. It cannot ask what the
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
- <p align="right">(<a href="#readme-top">back to top</a>)</p>
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
- ## Roadmap
182
-
183
- The implementation is ahead of the evidence needed to call this production-ready. The audit
184
- repairs are recorded in [the implementation record](docs/audit-implementation-2026-09-11.md);
185
- the local campaign and every excluded case are in
186
- [the September 11 report](docs/evidence/2026-09-11/local-campaign/report.md).
187
-
188
- - [x] Connect verification, displayed acceptance, cancellation, budgets and recovery to the
189
- records that establish them. Use standard DSSE signing bytes and literal replacement text.
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":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EACL,YAAY,EACZ,SAAS,EACT,SAAS,EACT,WAAW,EACX,YAAY,EACZ,aAAa,GACd,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAsBjC,MAAM,SAAS,GAAG,UAAU,CAAC;AAC7B,MAAM,aAAa,GAAG,SAAS,CAAC;AAChC,MAAM,SAAS,GAAG,IAAI,CAAC;AACvB,MAAM,UAAU,GAAG,CAAC,CAAC;AAErB,2FAA2F;AAC3F,MAAM,UAAU,qBAAqB,CACnC,SAAiB,EACjB,KAAK,GAAsB;IACzB,QAAQ;IACR,aAAa;IACb,YAAY;IACZ,cAAc;IACd,aAAa;IACb,gBAAgB;CACjB;IAED,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAChD,SAAS,CAAC,WAAW,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzD,MAAM,SAAS,GAAyB,EAAE,CAAC;IAC3C,IAAI,SAAS,GAAG,SAAS,CAAC;IAC1B,IAAI,QAAQ,GAAG,IAAI,CAAC;IACpB,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,QAAgB,EAAE,KAAa,EAAQ,EAAE;QACpE,IAAI,KAAK,GAAG,UAAU,IAAI,SAAS,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;YACxD,QAAQ,GAAG,KAAK,CAAC;YACjB,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACvB,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YACzE,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,IAAI,CAAC;gBAClC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;QAC7D,CAAC;aAAM,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,IAAI,IAAI,aAAa,IAAI,IAAI,CAAC,IAAI,IAAI,SAAS,EAAE,CAAC;YACjF,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACjC,MAAM,MAAM,GAAG,UAAU,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5E,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC;YAChD,SAAS,IAAI,KAAK,CAAC,MAAM,CAAC;YAC1B,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAClF,CAAC;aAAM,CAAC;YACN,QAAQ,GAAG,KAAK,CAAC;YACjB,SAAS,CAAC,IAAI,CAAC;gBACb,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,IAAI,CAAC,IAAI;gBAChB,QAAQ,EAAE,KAAK;gBACf,MAAM,EAAE,0CAA0C;aACnD,CAAC,CAAC;QACL,CAAC;IACH,CAAC,CAAC;IACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;QACnC,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,CAAC;YACH,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,GAAG,KAAK,CAAC;YACjB,SAAS,CAAC,IAAI,CAAC;gBACb,IAAI,EAAE,IAAI;gBACV,QAAQ,EAAE,KAAK;gBACf,MAAM,EAAG,KAA2B,CAAC,IAAI,IAAI,aAAa;aAC3D,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,aAAa,CACX,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,EACnC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAClF,EAAE,IAAI,EAAE,KAAK,EAAE,CAChB,CAAC;IACF,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AAC9C,CAAC"}