packs

The suite polices itself, on every push.

A pack is a self-contained bundle that loads into a host's runner, uses the host's real surface as its vocabulary, and proves the contract it claims to enforce. Nothing inside a pack imports the target. govstruct ships ten check-profile packs and one crashtest lane - the same SPEC v1 grammar the whole family loads.

The packs, live

Ten SPEC v1 check-profile packs under packs/public/, each a pure-reading verifier over files on disk, plus the crashtest dogfood lane that attacks govstruct lint with a hostile member-block corpus. A NEW exploited case or any verdict regression fails CI.

packwhat it verifiesverdict
comment-shapescomment hygiene across the tree
pure-reading checks; a violation is named at file:line
PASS
env-shapesenvironment-key declarations
every env key a member claims is declared once, in the shared block
PASS
floor-shapesengine floors
a floor bump propagates through the dependency graph, never drifts silently
PASS
hygiene-shapestree hygiene
no stray build product, lockfile, or repo-bound internal in a shipped surface
PASS
naming-shapesthe naming contract
ids, aliases, and file names agree with the roster grammar
PASS
pin-shapespin style
pins, never floats: every dependency and workflow uses: carries an exact rev
PASS
style-shapessource style
the shared source-consistency rules, enforced as a pack, not a fifth app
PASS
test-shapesthe test floor
every member carries a real test suite, not a green stub
PASS
version-shapesversion truth
package.json is the single version source; a living surface cannot hand-copy it
PASS
a11y-shapesthe emitted pane's floor
a named landmark, a real anchor per row, a visible focus ring, keyed strings + a locale fallback
PASS
govstruct-manifest-shapeshostile member blocks
nine attacks over govstruct lint: malformed blocks refuse (never crash), every refusal carries a registered code, spec-allowed shapes are never over-strictly flagged
REFUSED

The counts above are current-tree receipts, not marketing: the committed crashtest ledger sits at labs/crashledger.json(63 REFUSED verdicts), the packs live under packs/public/, and the full grammar is at the docs packs page.

The verdict taxonomy

Every scenario lands in exactly one of four buckets. Adoption is explicit - a new verdict only enters the ledger through a reviewed commit, never a silent rebuild.

REFUSED

The surface said no, cleanly, with its named code. A regression here is loud, not quiet.

BOUNDED

The damage was contained to a documented limit - a byte cap, a fixture lifespan. Bounds live in the ledger, not in prose.

PASSED

The safe path works end to end: checks, gates, roundtrips.

EXPLOITED

The attack landed. A new EXPLOITED or the regression of any previously recorded row fails CI.

Running the lane

The check host reads each pack's declared checks over the tree; the crashtest lane drives govstruct lint in-process over a hostile corpus. Exit 0 on green, 1 on findings.

# run every check pack
npm run check

# manifest + entry grammar (packstruct)
npm run lint:packs

# the dogfood: hostile member blocks over the CLI
npx crashtest run