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)