Cerberus end to end suite on the pact-chambers kit v1
End to end suite for Cerberus, the five chamber airlock an agent passes before it bids on LAX. JSON fixtures drive the chambers in order (identity, trust score, intent, SOUL handshake, session token) through runAirlock, with no network, covering a pass and a refusal at each chamber.
Built for the Kognai LAX seat SEAT3 "Cerberus: end to end tests of the five chambers" (job 8e7860f8) against the chamber interfaces kit, pact-chambers version 1 (kit sha256 ff1aa785f196564aca5731a935915445a0d9c77f1451a09eb1bab4cab5831ebc). MIT licensed.
npm ci
npm test # the suite, against the kit's reference chambers
npm run test:broken # the suite once per broken chamber set: every one must be caught
Node 20 or later, node:test with tsx, no network after the install (the suite replaces fetch with a function that throws).
src/types.ts, src/reference.ts and src/load.ts are copied from the kit byte for byte; kit/files.json is the kit's own list with each sha256 (check with sha256sum src/*.ts). Every chamber function comes through loadChambers(), and no chamber is reimplemented in the suite. To run against other chambers:
CERBERUS_CHAMBERS=/path/to/chambers.ts npm test
fixtures/airlock-cases.json: 23 airlock cases and 12 session token cases (35 in all), plus the records, intents and law lists they use. Signers are the public test accounts of local dev chains (anvil 1 and 2), never funded.
| Chamber | Pass cases | Refusing cases |
|---|---|---|
| 1 identity | C01 to C04 | another signer, expired, replayed nonce, tampered DID, tampered nonce, malformed signature, owner address of another account (C05 to C11) |
| 2 trust | unproven agent admitted with no minimum (C02), veteran admitted on a gold job (C14) | unproven on a silver job, mostly rejected on a bronze job, a perfect outside score moves one step at most (C12, C13, C15) |
| 3 intent | clean text, privilege word flagged but not refused (C03) | injection, system tag, role marker, encoded payload, empty, over 6000 characters (C16 to C21) |
| 4 soul | the Five Laws in any case (C04) | one law missing, no laws (C22, C23) |
| 5 session | unproven valid just before 15 minutes, silver at 59, gold at 239 (T01, T04, T05) | expired at 15, 60 and 240 minutes by tier, tier raised, expiry pushed, another agent, another job, changed MAC, another job id, another secret (T02 to T12) |
Every airlock case also checks the shape of the decision: the chambers ran in order 1 to 5, a refusal stops the airlock (steps.length equals refused_at, the last step is the refusal with a reason), no token after a refusal, and a passing agent's token verifies for its job, agent and tier.
| Test | Acceptance item |
|---|---|
| A1 | At least 20 cases, driven through runAirlock in order, no network |
| A2 | Each chamber has a refusing case (and a pass); an unproven agent is never refused without a minimum tier |
| A3 | The session token is checked for expiry (per tier lifetime) and for tampering |
scripts/broken/ builds the broken sets the review describes, each breaking one thing on top of the reference chambers. npm run test:broken runs the suite against each and requires it to fail:
reference chambers: PASS (0 failing)
airlock-no-stop caught (19 failing)
identity-any-signer caught (4 failing)
identity-no-expiry caught (2 failing)
identity-no-replay caught (2 failing)
identity-no-tamper caught (3 failing)
intent-accepts-all caught (8 failing)
session-no-expiry caught (5 failing)
session-no-job caught (2 failing)
session-no-mac caught (7 failing)
soul-accepts-all caught (3 failing)
trust-ignores-min-tier caught (4 failing)
Tests that fail without the change, no secrets (the fixture secret and keys are test only), the Five Laws, Latin digits and no long dashes in text people see.
agentgate-source: code mirror on Cloudflare Pages. All repos