crashtest docs

Family Status

Crashtest serves a machine-readable status file at the fixed path /status.json, on the family-status@1 dialect the struct family agreed on (worked example: eyestruct - served there first, adoption receipts chronicled in the pack reference’s family lanes).

Where the numbers come from

Nobody hand-types it. The emitter regenerates the file from the repo’s own committed ledgers on every web build: the CI web lane runs the emitter before the site package, so the served dialect can never lag the ledgers it reports, and web/public/status.json is gitignored - a committed copy would be exactly the stale-snapshot drift the family kills elsewhere. Run it by hand with:

node web/scripts/build-status.mjs

The shape

{ "schema": 1, "contract": "family-status@1", "repo": "dhaupin/crashtest",
  "site": "...", "docs": "...", "asOf": "<short HEAD sha or worktree>",
  "legs":  [{ "leg": "crashtest", "verdict": "PASS|RED", "cases": N,
              "counts": {"REFUSED": n}, "ledger": "labs/crashledger.json" }],
  "packs": [{ "name": "<slug>", "spec": "packstruct@1",
              "manifest": "packs/public/<slug>/pack.json", "cases": N }] }

Crashtest ships ONE committed ledger with the dogfood campaign, so the legs array carries the crashtest leg only - no leg is claimed for a ledger the repo does not carry. The packs rows carry each pack’s declared attack count, derived from the pack bank itself; the battery cross-checks that derivation against the CLI’s machine inventory (crashtest packs --json), so the two sources can never disagree silently. The ledgers themselves are documented in the hardening ledger - regeneration IS the freshness there too, by law.

The verdict rule

Additive-first, never a fake pass:

The reader rule

The dashboard’s family island fetches every sibling’s /status.json and refuses on missing or renamed schema/contract - a member not serving the dialect yet renders its own empty “not serving” row, never a guessed number. One bad sibling degrades only its own row.

Verify an install

Two pins, every time - schema === 1 and contract === "family-status@1", plus asOf naming the real HEAD (or honestly saying worktree). Anything else is not the dialect this page describes.