CAP is a verification protocol: nearly every contribution is a contract change, and the bar reflects that. This document tells you what that bar is and how to meet it.

Development

$ mix deps.get
$ mix quality

mix quality is the complete gate battery, identical locally and in CI: dependency audits, format check, warnings-as-errors compile, strict credo, the full test suite with its coverage threshold, the certified conformance corpus (with regeneration byte-identity), all 22 named source mutations, Elixir/TypeScript verifier agreement over repository and unpacked-package corpora, dialyzer, docs with warnings-as-errors, and the release-candidate gate (reproducible archive, exact package boundary). See Conformance.

The independent Node verifier needs Node 24+.

The bar for a change

  • Red before green. Every behavior change and every new gate arrives with a test that was seen failing for exactly the defect it guards. A green gate without a red-capable proof is incomplete.
  • Mutation receipts. New verification behavior extends the named mutation battery — prove the exact protected defect goes red in an isolated scratch copy. Never tamper the live tree to demo a failure.
  • Corpus and spec changes are certification events. A deliberate corpus or registry change re-runs scripts/record_conformance_index.exs; a deliberate spec-byte change re-runs scripts/record_release_metadata.exs. Either invalidates the four certified identities (corpus digest, raw index SHA-256, registry digest, specification digest) in priv/release-metadata.json, the Elixir CLI pin, and the TypeScript verifier pin. Conformance, mutations, verifier agreement, release-candidate, review, and CI must all re-run.
  • Docs land with the change. New public behavior ships with its guide section, changelog entry, and API documentation in the same landing. Doc claims are held to the same standard as code: every technical statement traces to the implementation, the certified corpus, or a cited primary source — no aspiration-as-fact.
  • Notebooks must run. If you change an API a notebook touches, re-run the notebook's code sequence top to bottom before landing.

Invariants (the short list)

  • CAP never authorizes. No authorization-decision or term-evaluation vocabulary enters production source; every explicit module states its non-authorizing boundary.
  • Production runtime uses only OTP :crypto — no filesystem, clock, network, environment, process dictionary, or application callbacks in verification paths. Callers supply time, limits, trust, and keys.
  • Every public function, macro, and delegate carries a specification.
  • Every facts record is built through the single omission-floor constructor; the closed twelve-item not_verified floor cannot shrink.
  • All Mix dependencies stay development/test-only with runtime: false. No path: or git: dependencies in the committed manifest.
  • No version tokens in durable identifiers — no V2Decoder, priv/v1/, decode_v2, or phase/task tokens in any path, module, function, atom, struct key, or test name. The Hex package semver and its exact source_ref tag are the only version-bearing identities (see the versioning ADR).
  • Errors stay value-free: closed code vocabulary, protocol-owned subjects, no rejected input in any error.

Package boundary

The shipped archive is an explicit allowlist in mix.exs (code, certified corpus, release metadata, and named public documents). Tests, scripts, the independent verifier, and environment files never ship. If you add a public document, add it to the allowlist and to the docs extras; the release-candidate gate verifies exact unpacked membership either way.

Commits

Stay on main; stage explicit pathspecs (never git add ./-A); write the what and the why in the commit body. CI must be green at the exact pushed SHA.

Reporting a security issue

See SECURITY.md — do not open a public issue for security content.