Skip to main content

Conformance

Covenant freezes its public wire and record contracts as committed, byte-exact golden vectors. A golden vector is the canonical serialized form of one message or record, checked into the repository, that an external implementation can encode and decode against without reading the Rust source. If your implementation reproduces every committed vector byte-for-byte and recomputes every committed hash, it speaks the same protocol Covenant does.

The suites

  • IPC requests and responses. One canonical frame per daemon Request and Response variant, plus the protocol-info and v2 streaming envelopes.
  • Capability grammar. One Capability grant per scope namespace — the dotted namespace.method[.sub] action grammar.
  • Audit record kinds.Every audit record variant's wire form and its SHA-256 event hash.
  • Audit provenance chain. The capability-family provenance records and the genesis-seeded chain root fold.

The wire form is what the bytes mean, not how they are pretty-printed. The audit suites pin the compact JSON string because that is the exact byte sequence hashed into the tamper-evident chain; the IPC and capability suites pin the pretty-printed form because those vectors exist to be read and diffed, and JSON object key order — not whitespace — is the contract.

Running the suite

One command runs every suite:

node agent-os/scripts/conformance.mjs

It executes each golden runner and requires every suite to run at least one test and report zero failures, so a renamed or deleted suite surfaces as a hard error rather than a silently shrinking run. Two read-only modes need no Rust toolchain:

node agent-os/scripts/conformance.mjs --list    # print the registered suites
node agent-os/scripts/conformance.mjs --check   # static integrity, no cargo

--check discovers the golden runners on disk and fails if any one is not registered in the runner, so a new conformance suite can never be added without the runner learning about it.

Proving conformance from another implementation

You do not need the runner — or Rust — to verify conformance. The committed vectors are plain JSON. For a wire suite, construct the message, serialize it, compare against the committed vector (object key order and field presence are part of the contract; insignificant whitespace is not), and confirm it round-trips back to the same value.

For the audit record suites, the hash is the contract:

canonical_json   = compact JSON of the AuditEvent
event_hash_hex   = sha256(canonical_json)
chain_hash       = sha256(previous_hash + "\n" + event_hash)   // per record, in order
                   previous_hash seeds with 64 hex zeros
chain_root       = the final chain_hash

Changing a frozen contract

Golden vectors are never regenerated blindly to make a failing test pass — a silent regenerate is exactly how a downstream verifier breaks. Each suite detects drift by re-serializing the in-code value and asserting byte-for-byte equality, and keeps the corpus exhaustive with a compile-time match over the underlying enum, so a new variant fails the build until a vector is added. When a wire shape genuinely changes, regenerate deliberately and review the resulting diff as the record of the change; bump the .v<n> suffix on a fixture for an incompatible record shape so existing verifiers can pin the version they support.

Related