law/invariants.md
The constitutional invariants of every zmail-hosted project. Every PR through the §F airlock is judged against this list. A diff that violates an invariant is rejected regardless of context.
This file is the authoritative source. The hardcoded TS array in src/lib/ci_pr_review.ts DEFAULT_CONFIG mirrors this for in-process speed; a future invariant-loader keeps them in sync (read from this repo's HEAD at airlock startup).
Owner-only edit. Amendments require an owner-signed envelope to zero@zmail.bot with subject [airlock] amend invariant, followed by an airlock PR.
I-1 · trace LMAX is append-only
The trace ledger never updates, never deletes, never drops. Past verdicts (case law) accumulate forever; the sequence number underwrites the audit chain.
I-2 · agent_id is the Ed25519 pubkey hex
An agent's identity is its public key. The hex never changes mid-thread. Renaming or rotating an agent_id mid-thread breaks the trust chain. Key rotation requires a new agent_id plus a signed lineage envelope.
I-3 · no hand-rolled crypto / parsers / protocol implementations
Cryptographic and protocol primitives must use audited libraries: postal-mime, mimetext, @noble/ed25519. Hand-rolling crypto is a hard-stop violation.
I-4 · no Microsoft trademark in user-facing copy
The trademark of the largest centralized code host is not used in zmail-facing copy. Internal references for git operations (clone, pull) are fine.
I-5 · no version tags
Zero 没有版本. Sprint-style ordinal labels in user-facing copy or commit messages are violations. Components ship when ready; dependents adopt when convenient.
I-6 · no compat shims
Suffix-versioned filenames, "FLAG_NEW" gates, "during the grace window", "old path stays for compat" — all violations. Replace cleanly; if the new path breaks, revert. One commit = one surface change + every caller updated + old code deleted.
I-7 · routes go through the Hono SSOT
All HTTP routes register in src/router.ts (Hono). No new routes in runtime.ts native if-chain. The native chain is the legacy fallback under active migration; new code must not extend it.
I-8 · library-first
Hand-rolling beyond ~30 lines for a problem with an audited library solution requires explicit library-not-viable justification in the PR rationale. The justification must name the library and the specific defect.
Amendments
(none yet · this is the constitutional baseline)