{"_id":"@anthill-tec/crucible-server","_rev":"6-ff9f5bd6b28f0ece8aa595d7b3a0824b","name":"@anthill-tec/crucible-server","dist-tags":{"latest":"0.2.2"},"versions":{"0.1.1":{"name":"@anthill-tec/crucible-server","version":"0.1.1","_id":"@anthill-tec/crucible-server@0.1.1","maintainers":[{"name":"fragger71","email":"dull.sail8487@fastmail.com"}],"homepage":"https://github.com/anthill-tec/crucible#readme","bugs":{"url":"https://github.com/anthill-tec/crucible/issues"},"bin":{"crucible-server":"bin/crucible-server.mjs"},"dist":{"shasum":"5a9644ccdebcac2180e25c5229f15518199df11e","tarball":"https://registry.npmjs.org/@anthill-tec/crucible-server/-/crucible-server-0.1.1.tgz","fileCount":23,"integrity":"sha512-J8GGdLKUvsjS+B28pO1xUNOxd5QLkVmbYs09ulCvjk6caCx0lwPAzXC94v5Zfm8rcAWawG9kJcNUkvbSfhIOmw==","signatures":[{"sig":"MEYCIQDhyjsTifvGmaL+lmC1aGHBda4IEUiMPdaymclbs2Wq4wIhAPUNemEnW9jc8NseTzs/yUqBKHu1mQue/irCLyXF4/zc","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@anthill-tec%2fcrucible-server@0.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1763933},"type":"module","engines":{"bun":">=1.2"},"gitHead":"abc30d5732e71ed11f8d0b81d6248f95b68b2b12","scripts":{"test":"bun test","start":"bun run src/server.ts","test:e2e":"bunx bddgen && bunx playwright test"},"_npmUser":{"name":"fragger71","email":"dull.sail8487@fastmail.com"},"repository":{"url":"git+https://github.com/anthill-tec/crucible.git","type":"git"},"_npmVersion":"12.0.2","description":"Crucible is the test-reporting and orchestration backbone for the Model-B workflow. It is two cooperating stacks behind one product:","directories":{},"_nodeVersion":"22.23.2","dependencies":{"@toon-format/toon":"^4.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"bun-types":"^1.3.14","happy-dom":"^20.10.6","playwright-bdd":"^9.2.0","@playwright/test":"^1.61.1","@cucumber/gherkin":"^41.0.0","@happy-dom/global-registrator":"^20.10.6"},"_npmOperationalInternal":{"tmp":"tmp/crucible-server_0.1.1_1787151737518_0.8218268890075604","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@anthill-tec/crucible-server","version":"0.1.2","_id":"@anthill-tec/crucible-server@0.1.2","maintainers":[{"name":"fragger71","email":"dull.sail8487@fastmail.com"}],"homepage":"https://github.com/anthill-tec/crucible#readme","bugs":{"url":"https://github.com/anthill-tec/crucible/issues"},"bin":{"crucible-server":"bin/crucible-server.mjs"},"dist":{"shasum":"c651918c1f3b759975321b7ef2e4587f5661d0db","tarball":"https://registry.npmjs.org/@anthill-tec/crucible-server/-/crucible-server-0.1.2.tgz","fileCount":23,"integrity":"sha512-DX9fJbqyaIJNs3sGXYy1kYyMSsJzHGZ8E0FaiZzltGTcpt/hmqS12Hn3P27OUR4O6Tvr1Dp2ziDiUr3r8zYQ+Q==","signatures":[{"sig":"MEYCIQCqR9NZky55P1k9IMjc/A74OwUIJdeFDtYbzlGSxNxpkgIhAKZRCmxH06+4nNSTbW9buzdU18jbNaznMOFH5Lkaisuu","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@anthill-tec%2fcrucible-server@0.1.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1765510},"type":"module","engines":{"bun":">=1.2"},"gitHead":"9ef24b1867ab33f34c66c7acf4633fb3995bf339","scripts":{"test":"bun test","start":"bun run src/server.ts","test:e2e":"bunx bddgen && bunx playwright test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0cb1a1d7-a554-4a38-9e0f-1e4f14d64b6e"}},"repository":{"url":"git+https://github.com/anthill-tec/crucible.git","type":"git"},"_npmVersion":"12.0.2","description":"Crucible is the test-reporting and orchestration backbone for the Model-B workflow. It is two cooperating stacks behind one product:","directories":{},"_nodeVersion":"22.23.2","dependencies":{"@toon-format/toon":"^4.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"bun-types":"^1.3.14","happy-dom":"^20.10.6","playwright-bdd":"^9.2.0","@playwright/test":"^1.61.1","@cucumber/gherkin":"^41.0.0","@happy-dom/global-registrator":"^20.10.6"},"_npmOperationalInternal":{"tmp":"tmp/crucible-server_0.1.2_1787181485543_0.11286490707181862","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@anthill-tec/crucible-server","version":"0.1.3","_id":"@anthill-tec/crucible-server@0.1.3","maintainers":[{"name":"fragger71","email":"dull.sail8487@fastmail.com"}],"homepage":"https://github.com/anthill-tec/crucible#readme","bugs":{"url":"https://github.com/anthill-tec/crucible/issues"},"bin":{"crucible-server":"bin/crucible-server.mjs"},"dist":{"shasum":"d190694616b06d8bb90c8a3ed07840b1f9e22e0a","tarball":"https://registry.npmjs.org/@anthill-tec/crucible-server/-/crucible-server-0.1.3.tgz","fileCount":23,"integrity":"sha512-6om4LoP/MksM8XmQTrFVZHbqkHp3oYEGN174PcDtGiLa5TejFhq7Ms3HhBHHeN20/cD7WLhu5OfD4zBe46CZ6Q==","signatures":[{"sig":"MEQCIF5pfYJ5PvlakQg+o4sjoPSiVDsnLRvLliTosGaCaVDIAiAEwx5PmXhBeZV4MhUUvMDtHlABxn66oNac3byViBdlvw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@anthill-tec%2fcrucible-server@0.1.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":1765785},"type":"module","engines":{"bun":">=1.2"},"gitHead":"74088863dfb250dfb8d75917b79ec4e29de8b685","scripts":{"test":"bun test","start":"bun run src/server.ts","test:e2e":"bunx bddgen && bunx playwright test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0cb1a1d7-a554-4a38-9e0f-1e4f14d64b6e"}},"repository":{"url":"git+https://github.com/anthill-tec/crucible.git","type":"git"},"_npmVersion":"12.0.2","description":"Crucible is the test-reporting and orchestration backbone for the Model-B workflow. It is two cooperating stacks behind one product:","directories":{},"_nodeVersion":"22.23.2","dependencies":{"@toon-format/toon":"^4.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"bun-types":"^1.3.14","happy-dom":"^20.10.6","playwright-bdd":"^9.2.0","@playwright/test":"^1.61.1","@cucumber/gherkin":"^41.0.0","@happy-dom/global-registrator":"^20.10.6"},"_npmOperationalInternal":{"tmp":"tmp/crucible-server_0.1.3_1787824328512_0.3768077833454253","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@anthill-tec/crucible-server","version":"0.2.0","_id":"@anthill-tec/crucible-server@0.2.0","maintainers":[{"name":"fragger71","email":"dull.sail8487@fastmail.com"}],"homepage":"https://github.com/anthill-tec/crucible#readme","bugs":{"url":"https://github.com/anthill-tec/crucible/issues"},"bin":{"crucible-server":"bin/crucible-server.mjs"},"dist":{"shasum":"b06c701fbac1112841c596101c95d75a8d2379d4","tarball":"https://registry.npmjs.org/@anthill-tec/crucible-server/-/crucible-server-0.2.0.tgz","fileCount":24,"integrity":"sha512-KosqZEPKlomuryGAL9F1ncQe6MNfpb4yAdWZEQDHt7vUg3WUa2BRIajPBi23Z/N5nV0FgI1oQ6oSyOkWASPLzg==","signatures":[{"sig":"MEYCIQCph0Vk8n5Irqlkip4D/9vhewYk6Mo/jJIcY4LCO54eCAIhAK8S5GRBFW9mBqz980AJuHYpYTG55ekXHeHkA7jCf257","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQD0dCBgTDaHj7dSxei8JMtvCChEYBH1bM4HewZcTouMxQIhAKMT2StJE8QAfCmF0UzJblUMdW7ZrgL47zPQCeIVoEzH","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@anthill-tec%2fcrucible-server@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2278770},"type":"module","engines":{"bun":">=1.2"},"gitHead":"eb6e33f042d61eb479ea1e7318d44f54d4ac7f7b","scripts":{"test":"bun test","start":"bun run src/server.ts","test:e2e":"bunx bddgen && bunx playwright test","test:unit":"bun scripts/run-test-target.ts unit","test:client":"python3 -m unittest discover -s tests/client -t .","test:regression":"bun scripts/run-test-target.ts regression","test:integration":"bun scripts/run-test-target.ts integration"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0cb1a1d7-a554-4a38-9e0f-1e4f14d64b6e"}},"crucible":{"reportPath":{"test:e2e":"env:PLAYWRIGHT_JUNIT_OUTPUT_NAME"}},"repository":{"url":"git+https://github.com/anthill-tec/crucible.git","type":"git"},"_npmVersion":"12.0.2","description":"Crucible is the test-reporting and orchestration backbone for the Model-B workflow. It is two cooperating stacks behind one product:","directories":{},"_nodeVersion":"22.23.2","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"bun-types":"^1.3.14","happy-dom":"^20.10.6","playwright-bdd":"^9.2.0","@playwright/test":"^1.61.1","@cucumber/gherkin":"^41.0.0","@toon-format/toon":"^4.1.0","@happy-dom/global-registrator":"^20.10.6"},"_npmOperationalInternal":{"tmp":"tmp/crucible-server_0.2.0_1789553396300_0.4546587473224706","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@anthill-tec/crucible-server","version":"0.2.1","_id":"@anthill-tec/crucible-server@0.2.1","maintainers":[{"name":"fragger71","email":"dull.sail8487@fastmail.com"}],"homepage":"https://github.com/anthill-tec/crucible#readme","bugs":{"url":"https://github.com/anthill-tec/crucible/issues"},"bin":{"crucible-server":"bin/crucible-server.mjs"},"dist":{"shasum":"302e32c00d31d712d9fa81d65a7518caa6ebe3d2","tarball":"https://registry.npmjs.org/@anthill-tec/crucible-server/-/crucible-server-0.2.1.tgz","fileCount":24,"integrity":"sha512-c6OrBZA8cISh5f9DsVzCd5Y96ilEwG2utDm5JvI+XFr3cg62L0glmBIETqk7rR8V6x7NPhIoPc4hwA4TtLD1oQ==","signatures":[{"sig":"MEUCIQDCzkryJXd391GpnPT+iJgKenx4PQNpZA9DQqb+rb2vwQIgGGwhzeCehVtJvjwT+Lm6P6/5MRXwHtDxyyrC3GMyfpE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIE7DV76r8p6s8JoaKw0ddOLhN5iBsQlTgfxU2TNGGGK8AiBjty9hRDiy6x2q1R77L96Zv9T6qULXCvPWepEspfOLMw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@anthill-tec%2fcrucible-server@0.2.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2278770},"type":"module","engines":{"bun":">=1.2"},"gitHead":"de877f9d3ab5a73f109e7090061c33d0e7d3bb8d","scripts":{"test":"bun test","start":"bun run src/server.ts","test:e2e":"bunx bddgen && bunx playwright test","test:unit":"bun scripts/run-test-target.ts unit","test:client":"python3 -m unittest discover -s tests/client -t .","test:regression":"bun scripts/run-test-target.ts regression","test:integration":"bun scripts/run-test-target.ts integration"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0cb1a1d7-a554-4a38-9e0f-1e4f14d64b6e"}},"crucible":{"reportPath":{"test:e2e":"env:PLAYWRIGHT_JUNIT_OUTPUT_NAME"}},"repository":{"url":"git+https://github.com/anthill-tec/crucible.git","type":"git"},"_npmVersion":"12.0.2","description":"Crucible is the test-reporting and orchestration backbone for the Model-B workflow. It is two cooperating stacks behind one product:","directories":{},"_nodeVersion":"22.23.2","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"bun-types":"^1.3.14","happy-dom":"^20.10.6","playwright-bdd":"^9.2.0","@playwright/test":"^1.61.1","@cucumber/gherkin":"^41.0.0","@toon-format/toon":"^4.1.0","@happy-dom/global-registrator":"^20.10.6"},"_npmOperationalInternal":{"tmp":"tmp/crucible-server_0.2.1_1789568059897_0.07600952276498552","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"_id":"@anthill-tec/crucible-server@0.2.2","bin":{"crucible-server":"bin/crucible-server.mjs"},"bugs":{"url":"https://github.com/anthill-tec/crucible/issues"},"dist":{"shasum":"487c81f95c4189f034d506498a38594093ca62f1","tarball":"https://registry.npmjs.org/@anthill-tec/crucible-server/-/crucible-server-0.2.2.tgz","fileCount":25,"integrity":"sha512-ehsd7gr30W8IEuVMlnM9rS5LUpKrbnmoyITLpu2hDPk7mrn7VpLmq2rG4umpASmSw4GyBUbv4RlIByx20cRMkA==","signatures":[{"sig":"MEUCICqnGwa7bYAr/ONUm8KpuO++W246dkD+q/WpKd7+s4iKAiEA7OWz92ecBz3TX6Uf067FgPUuuOFtG7gLz2OIjpApxsg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCmd85ylF03MMwyNSYKBsaVDAW8YXOy6/7d6FGu+CPGQgIhALf1H0yTznTLg4veXp/JLp3SDiFzHthBJ4/zXLNVPT2c"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@anthill-tec%2fcrucible-server@0.2.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":2318655},"name":"@anthill-tec/crucible-server","type":"module","engines":{"bun":">=1.2"},"gitHead":"87ec641d9d4f7888c74e48fb8c4376bd0b437749","license":"GPL-3.0-only","scripts":{"test":"bun test","start":"bun run src/server.ts","test:e2e":"bunx bddgen && bunx playwright test","test:unit":"bun scripts/run-test-target.ts unit","test:client":"python3 -m unittest discover -s tests/client -t .","test:regression":"bun scripts/run-test-target.ts regression","test:integration":"bun scripts/run-test-target.ts integration"},"version":"0.2.2","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0cb1a1d7-a554-4a38-9e0f-1e4f14d64b6e"}},"crucible":{"reportPath":{"test:e2e":"env:PLAYWRIGHT_JUNIT_OUTPUT_NAME"}},"homepage":"https://github.com/anthill-tec/crucible#readme","repository":{"url":"git+https://github.com/anthill-tec/crucible.git","type":"git"},"_npmVersion":"12.0.2","description":"Crucible is the test-reporting and orchestration backbone for the Model-B workflow. It is two cooperating stacks behind one product:","directories":{},"maintainers":[{"name":"fragger71","email":"dull.sail8487@fastmail.com"}],"_nodeVersion":"22.23.2","dependencies":{},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"bun-types":"^1.3.14","happy-dom":"^20.10.6","playwright-bdd":"^9.2.0","@playwright/test":"^1.61.1","@cucumber/gherkin":"^41.0.0","@toon-format/toon":"^4.1.0","@happy-dom/global-registrator":"^20.10.6"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/crucible-server_0.2.2_1789654526952_0.5793096413845589"}}},"time":{"created":"2026-08-19T15:02:14.918Z","modified":"2026-09-17T14:15:27.739Z","0.1.1":"2026-08-19T15:02:17.662Z","0.1.2":"2026-08-19T23:18:05.762Z","0.1.3":"2026-08-27T09:52:08.665Z","0.2.0":"2026-09-16T10:09:56.398Z","0.2.1":"2026-09-16T14:14:20.042Z","0.2.2":"2026-09-17T14:15:27.061Z"},"bugs":{"url":"https://github.com/anthill-tec/crucible/issues"},"homepage":"https://github.com/anthill-tec/crucible#readme","repository":{"url":"git+https://github.com/anthill-tec/crucible.git","type":"git"},"description":"Crucible is the test-reporting and orchestration backbone for the Model-B workflow. It is two cooperating stacks behind one product:","maintainers":[{"name":"fragger71","email":"dull.sail8487@fastmail.com"}],"readme":"# Crucible\n\nCrucible is the test-reporting and orchestration backbone for the Model-B\nworkflow. It is two cooperating stacks behind one product:\n\n- a **Bun server** (`src/server.ts`) that ingests test runs, tracks agents,\n  cycles and events, and streams live changes over SSE; and\n- a **Python client fleet** (`crucible-axi` — `_crucible_axi.py` plus the\n  per-stack `{bun,python,rust,mvn,arduino}-crucible.py` scripts) that runs a\n  stack's tests AND ingests the results to the server under an agent id.\n\nRED/GREEN/VERIFY agents report every run through the stack client; the server\ngives orchestrators a live picture of the fleet, the cycle plan, and coverage.\n\n## Quick start\n\nOne-line, distro-agnostic bootstrap — the only prerequisites are `curl` + `sh`\n(no `apt`/`dnf`/`pacman`, no pre-existing system Python or Node):\n\n```sh\ncurl -fsSL https://raw.githubusercontent.com/anthill-tec/crucible/master/install.sh | sh\n```\n\nThe bootstrap ensures **`uv`** (Astral's single static binary, which brings its\nown Python) is present, then installs the primary orchestrator and provisions\nthe server:\n\n```sh\nuv tool install crucible-axi\ncrucible-axi install\n```\n\n`crucible-axi install` provisions and then **exits** — it never starts anything.\nIt guarantees **Bun** (the server's runtime: detected on `PATH`, otherwise\nbootstrapped from <https://bun.sh>, re-resolved under `$BUN_INSTALL/bin` and\nverified by running `bun --version`; if Bun still cannot be resolved the install\nfails outright with that remedy), provisions the server user-scoped via\n`bun add -g @anthill-tec/crucible-server@<pinned>` — Bun's global prefix lives\nunder `$HOME`, so there is no system-permission problem — then creates its\ntarget directory (`--target-dir`, default `~/.crucible`), lays the\n`*-crucible.py` **client fleet** (the five clients, the two shared modules they\nload by path, and `STATUS-CONTRACT.md`) down in `<target-dir>/clients/`, and\nwrites the client discovery **manifest** naming those paths into it. Those\nthree stages — `server`, `fleet`, `manifest`, in that order, so the manifest is\nwritten only after the paths it names exist — are the whole install. It reports\na TOON-AXI envelope naming each stage's installed\npath plus the absolute Bun it resolved. A second run at the same version is a\nno-op; re-running after an upgrade re-provisions the server, because the\n`server` stage counts as converged only when the installed server is exactly\nthe pinned version. `--force` re-runs every stage regardless.\n`uvx crucible-axi …` is the on-demand form.\n\nRather not pipe a remote script into a shell? Install Bun yourself first and\npass `--no-bun-bootstrap` (or set `CRUCIBLE_NO_BUN_BOOTSTRAP=1`): an absent Bun\nthen fails immediately with the remedy instead of fetching an installer.\n\n**Upgrading is the same one-liner.** Re-run it (or `install.sh` directly) and\nthe script advances an existing install instead of no-opping on it: it reports\n`crucible-axi upgraded: 0.1.1 -> 0.1.2`, then re-runs the staged install so the\nserver half is re-provisioned to the new release's pin — CLI and server move in\nlockstep. On a machine that is already current it says so and stops, doing no\nwork. Note that plain `uv tool upgrade crucible-axi` is *not* sufficient by\nhand: it resolves within the constraint the tool was installed under, so a\npinned install reports \"already current\" forever. The installer uses\n`uv tool install --upgrade`, which ignores that pin. Version selection is\nentirely uv's — the installer never pins a `crucible-axi` version.\n\nRunning the server is a separate, explicit step. Start it in the foreground and\ncheck its health:\n\n```sh\ncrucible-axi serve              # loopback default; see docs/RUNBOOK.md\ncurl -fsSL http://127.0.0.1:3849/api/health\n```\n\n`crucible-axi serve` execs the provisioned server by absolute path, honours\n`CRUCIBLE_HOST` / `CRUCIBLE_PORT` (overridable per run with `--host` /\n`--port`), and passes the server's exit code straight through so a shell — or a\nprocess supervisor — sees the real failure.\n\nOn a systemd machine the install also provisions a **`--user` service**, so the\nserver survives logout and comes back on login without a terminal held open:\n\n```sh\nsystemctl --user status crucible-server     # provisioned by `crucible-axi install`\nsystemctl --user stop crucible-server       # clean stop — leaves Result=success\njournalctl --user -u crucible-server -f\n```\n\nThe unit is **`--user` only** — no root, no `sudo`, nothing in\n`/etc/systemd/system` — matching the user-scoped `bun add -g`. Its `ExecStart`\nis the same absolute argv `serve` uses, it carries `Restart=on-failure`, and it\nputs the resolved Bun's directory on `PATH`: the published `crucible-server` bin\nis a shim that spawns `bun` itself, and a unit inherits no shell `PATH`. Only\nthe `CRUCIBLE_*` variables you actually set are forwarded.\n\nDon't want a daemon? `crucible-axi install --no-service` (or\n`CRUCIBLE_NO_SERVICE=1`) skips that stage. On a machine with no systemd — or no\nuser D-Bus session — the stage reports itself skipped with the reason and the\ninstall still succeeds.\n\nUninstalling inverts the install along the same path — the verb reverses the\nstages it owns, then uv removes the tool that ran it:\n\n```sh\ncrucible-axi uninstall          # program only: store and config survive\nuv tool uninstall crucible-axi  # LAST — a running tool cannot remove itself\n```\n\nA plain `crucible-axi uninstall` removes **program artifacts only**: the\nuser-scoped server package and its `crucible-server` symlink, via\n`bun remove -g` with the same absolute Bun the install resolved. It reports each\nstage in the usual TOON-AXI envelope and names the two things it deliberately\nkept — the **store** (`$XDG_DATA_HOME/crucible`, else `~/.local/share/crucible`)\nand the **config** (`<target-dir>/crucible-clients.json`) — with their paths,\nmarked `retained`. Stage order is `server`, `config`, `store`: destructive last,\nso a failing step can never leave your data gone and the program still installed.\n\nDestroying data is opt-in and explicit:\n\n```sh\ncrucible-axi uninstall --purge  # also removes the store AND the config\n```\n\nWithout `--purge` nothing is deleted: a non-interactive run always retains (so\nautomation cannot silently lose a database), and an interactive one asks once,\nnaming both paths and the store's size, keeping them on empty input, EOF, or\nCtrl-C. **Bun is never removed** — the install only guarantees it, it does not\nown it. Absent artifacts converge with no subprocess, so re-running is\nindistinguishable from running once.\n\n## Development\n\nWorking on the Python client? Install the dev extras into your `.venv` so the\nPython coverage gate (`python-crucible.py regression --coverage`) has\n`coverage.py` available:\n\n```sh\npip install -e '.[dev]'\n```\n\n## Documentation\n\n- [docs/RUNBOOK.md](docs/RUNBOOK.md) — operating the server (start/stop, db\n  path, health, port/bind config).\n- `clients/` — the per-stack reporting clients\n  (`{bun,python,rust,mvn,arduino}-crucible.py`) plus the shared TOON-AXI\n  envelope module every one of them emits through.\n- `clients/STATUS-CONTRACT.md` — the status/dashboard payload contract the\n  orchestrators read.\n\n## Telling Crucible a release shipped\n\nCrucible does not observe your release process, so a release only appears on the\nboard if something reports it. This is worth stating explicitly because **not\nevery stack has a release script** — the pattern below is the strategy, and the\nscript is only one way to run it.\n\nThe unit is a `release` **milestone**, posted through any stack's client:\n\n```sh\n<stack>-crucible.py milestone --type release \\\n  --label 1.4.0 --commit \"$(git rev-list -n1 1.4.0)\" --agent <agentId>\n```\n\n`--agent` is **required** and has no fallback: an agent identity is a real\nregistration, and a derived default would plant a phantom row on the agent rail.\n`$WORKFLOW_ROLE` is a track lane (`mainline` | `track-n`), not an identity.\n\n**What depends on it.** Skip this and the loss is silent but wide: the roadmap\ndraws no release-boundary rows (nothing distinguishes work *in* a release from\nwork deferred past it), gate retirement has no completion event to fire on, and\ndelivery forecasting has no release to anchor to. Three releases of this project\nshipped with no record at all before the gap was noticed.\n\n**Adoption strategies**, in the order most projects should consider them:\n\n1. **Release script / ceremony hook** — if the stack has one (`release.sh`, a\n   Maven release plugin, `cargo release`), post the milestone *after the push\n   succeeds*, so a recorded release always corresponds to a real remote tag.\n2. **CI on tag push** — no release script needed: a tag-triggered job posts the\n   milestone. Best fit for stacks whose release *is* \"push a tag\".\n3. **By hand, once per release** — a single command, entirely acceptable for\n   small projects. Better a manual report than an unrecorded release.\n4. **Backfill** — already shipped releases can be replayed from their tags at\n   any time; reporting is idempotent per tag/commit.\n\n**Two rules learned the hard way.** Make reporting **non-fatal** — never roll\nback or fail a published release because a tracking call failed; the artifact is\nalready public and the record can be backfilled. But check the **identity at\npreflight**, before the tag exists, because a non-fatal report that fails at the\nend is a warning nobody reads: this project's ceremony exited clean while\nrecording nothing, three times. Fail early, warn late.\n\n## Version\n\n`0.2.1` — published on [PyPI](https://pypi.org/project/crucible-axi/) (`crucible-axi`) and\n[npm](https://www.npmjs.com/package/@anthill-tec/crucible-server) (`@anthill-tec/crucible-server`).\n\nThe authoritative value is the **git tag** and what those two registries serve; `package.json`\nis aligned to it by the release ceremony. Read it from there rather than trusting this line —\nit went stale at 0.1.3 because a hotfix merge-back bumped the manifest and not this file.\n","readmeFilename":"README.md","license":"GPL-3.0-only"}