Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Wild v1 formats and decision rules

This reference defines the interoperable design contracts used by all nine wild specifications. These formats are intended behavior; the Python simulations are smaller models and do not implement this wire protocol.

The machine-readable structural schema is wild-v1.schema.json, using JSON Schema draft 2020-12. This document defines additional semantic validation that JSON Schema cannot express. A conforming reader validates both. Structural examples cover every wire kind; their placeholder digests and signatures are intentionally not valid certified assemblies. Their gate checks structure only. Unknown versions, kinds, fields, duplicate names, dangling references, or failed semantic checks are refused with a JSON diagnostic; no partial input receives a complete assurance claim.

Encoding, identities, and canonical bytes

All wire documents are UTF-8 JSON objects with schema_version: "1" and the kind specified by their schema definition. Duplicate JSON object keys, invalid UTF-8, unpaired surrogates, floating-point numbers, and integers outside [-9007199254740991, 9007199254740991] are invalid. Strings preserve their exact Unicode code points; no host-dependent normalization is applied. Identifier strings are restricted to the ASCII grammar in the schema.

Canonical JSON recursively sorts object keys by Unicode scalar value, omits whitespace and a byte-order mark, and writes integers in base ten without leading zeros or negative zero. It escapes quote and backslash as \" and \\, and control code points U+0000 through U+001F as lowercase \u00xx; all other scalar values are literal UTF-8. Solidus is not escaped. Input whitespace, escape spelling, and object-key order have no effect on canonical bytes.

Array ordering is explicit. These arrays are sets and must be sorted by the indicated unique key before canonicalization: contract slots and tombstones by slot name; contract laws by law id; contract relations by relation id; contract sunsets by date and then slot name; manifest providers by instance id; manifest demand lists and law-id lists lexically; assembly roots lexically, components by instance id, and bindings by binding id; certificate proofs by digest; policy required-law and allowed-method lists lexically; all slot-scope, parent-hash, adapter-hash, trusted-signer, lease-scope, and certificate proof lists lexically; bundle documents and blobs by digest; lockfile entries by entry id. Type record fields and sum variants are objects, whose keys are sorted by canonical JSON. Other arrays, including function arguments, observed samples, and arbitrary default values, preserve order. Repeated set keys are rejected, rather than silently deduplicated.

A content digest is sha256: followed by exactly 64 lowercase hexadecimal digits over canonical document bytes. Raw artifacts use the same syntax but hash their exact raw bytes. Artifact bytes and document bytes are never substituted for each other. v1 accepts SHA-256 only; introducing an algorithm requires a new supported format version. A contract hash excludes lineage ownership, timestamps, evidence, and artifact metadata, which reside in separate documents. Equal contract hashes establish structural identity, never implementation identity.

Canonical examples (byte strings shown as JSON without a trailing newline):

InputCanonical bytes
{"b":2,"a":1}{"a":1,"b":2}
{ "text": "\u0061" }{"text":"a"}
{"text":"\n"}{"text":"\u000a"}
Contract with slots z, aSame canonical bytes as that contract with slots a, z
{"a":1,"a":2} or {"a":1.0}Refused, no identity assigned

Contract IR and subtyping

A contract contains slots, tombstones, laws, relations, and sunsets. Slot names are unique across slots and tombstones. Each slot has a stable meaning identifier, polarity out or in, one declared facet, a recursive type, required, and default. default is {present:false} or {present:true,value:...} so an explicit null is distinguishable from absence. Outputs must have required:true. Tombstones are former input slots and must retain their last accepted meaning and type. An opaque type carries an artifact or source-range fingerprint; any fingerprint change is a break.

The scalar domains are unit, boolean, integer, string, and bytes; integer types specify inclusive min and max, with min ≤ max. Byte values are objects containing canonical padded base64; decoded bytes define equality. No implicit conversion, rounding, coercion, or numeric widening across scalar kinds occurs. Defaults must inhabit their declared type. General cardinality and timeout constraints are represented as integer slots in the relevant facet, with immutable meaning describing units and whether they are guarantees or requirements; they are not untyped annotations.

subtype(A,B) means every value allowed by A is accepted by B. The v1 checker uses these conservative structural rules; when it cannot establish inclusion it returns Unknown rather than guessing:

ShapeRule for subtype(A,B)
ScalarSame scalar kind; for integers, A’s interval is contained in B’s interval.
RecordEvery required B field is required in A with a subtype; each field that A can emit is accepted by B with a subtype. Extra A fields require B to be open. An open A requires an open B. Optional fields may be absent, never substituted with an implicit default.
SumEvery named A variant exists in B with a subtype payload unless B is open. Open A requires open B; unknown variants are retained as opaque payloads.
SequenceA’s item type is a subtype of B’s; A’s inclusive length interval is contained in B’s.
MapKey types are identical; value types are covariant; A’s cardinality interval is contained in B’s.
FunctionSame argument arity; B’s argument types are subtypes of A’s corresponding arguments; A’s result is a subtype of B’s.
OpaqueIdentical fingerprint only.

For a missing B record field, an open B accepts the unknown field without interpreting its payload. For fields shared by A and B their declared type still applies. An open A cannot subtype B when B has an optional typed field absent from A: A could emit that field with an incompatible unknown value. Named variants use the same rule. Unknown record fields and variants are round-tripped byte-for-byte in the containing opaque payload. A bytes default is exactly { "base64": "..." }; unit defaults are null. Open sums use an opaque payload for labels absent from the named variants. Recursive cyclic type references are not supported in v1: types are finite trees. Supporting such references requires a new schema version and termination rules.

accretes(old,new) requires all of the following:

  • Every old output remains under the same name, facet, polarity, and meaning, with a subtype output. New outputs are permitted. Retained inputs have supertype input domains; required may become optional, but optional may not become required. A new required input is forbidden; a new optional input is permitted.
  • Removed inputs leave tombstones. Existing tombstones remain or reactivate as non-required inputs whose type accepts the tombstoned domain; a reintroduced required input is a new requirement and breaks accretion. Tombstones cannot be fabricated without history. Removed outputs always break.
  • Provided defaults are identical. Changed input defaults are also conservatively a break in v1 because omission can change behavior. Limits expressed as slots obey the same polarity rules with no separate contradictory limit algorithm.
  • Every old law id remains with the same suite digest and scope. New laws may be added. New required relations are a break; an existing relation may not change or disappear within a lineage. A schema revision is needed to add a facet or shape kind.

Binding checks additionally verify every required input of every selected component, facet match, and all declared relations. Demand restriction selects externally used outputs; it never removes a selected implementation’s own required dependencies. Dynamic usage that cannot be resolved marks the demand manifest incomplete and prevents scoped substitution or removal claims. A law counterexample blocks the relevant policy even when structure passes.

Consumer manifest, assembly, and lockfile

A manifest names its component contract hash, raw implementation artifact digest, demand_complete, and a unique set of provider instance requirements. Each provider record names authority, versionless lineage, required slots, and an explicit floor contract hash. Uncertain dynamic usage is listed in unresolved_usage and requires demand_complete:false. A lineage is an ASCII dot-separated semantic name; version suffixes matching v[0-9]+ or a numeric final segment are forbidden. Names do not decide compatibility.

An assembly contains explicit root instance ids, component instances with contract, artifact, and manifest hashes, and bindings whose endpoints are instance ids and slot names. All ids and endpoints must resolve. Every required input has exactly one binding. The set of provider output slots referenced by bindings for each manifest provider exactly matches its demand_slots; undeclared provider dependencies are refused. Duplicate competing providers for one input are refused. Components are exactly the transitive closure reachable from roots; unrelated or missing instances are refused. Components sharing a singleton lineage declaration must use one lineage and one artifact instance; a second singleton instance is refused. Disconnected unneeded instances cannot alter the verdict.

For no roots, no components and no bindings are allowed. This empty assembly has structural assurance PassDeclared, coverage numerator and denominator zero, and coverage ratio null (vacuous satisfaction). Cyclic dependencies are allowed for composition: deterministic closure visits each instance once, then validates all edges. Deploy ordering considers only prerequisites not already satisfied. Assembly composition uses disjoint union after an explicit injective renaming of instance ids; exposed interfaces are joined by declared bindings. Name collisions, singleton conflicts, or invalid relations make composition undefined, with diagnostics. The category laws apply to jointly composable interfaces. Equality is structural equality modulo the explicit injective renaming of instance ids, so incidental instance names cannot break associativity.

A v1 lock preserves every host entry using a stable entry_id, ecosystem, locator, raw artifact digest when available, and status. A contracted entry also pins authority, lineage, and contract hash; an unresolved entry has status Unknown and a reason. Unresolved entries are retained and never silently removed or treated as compatible. A host alias may remain in the locator as provenance, but it cannot replace an identity. A sidecar is signed over its canonical document and binds authority, lineage, ecosystem, locator, artifact digest, contract hash, extractor digest, and registry sequence. Signature payload excludes only the signature member; the remaining members, including signer and algorithm, are covered. Runtime loading verifies raw artifact bytes against the sidecar and lock, not merely the contract hash.

For each registry snapshot and authority/lineage, publication records an accepted tip and its ancestry. Publishing competing children marks that lineage forked; no automatic newest exists until an explicit merge accretes all ancestors and becomes its unique tip. “Newest” means accepted tip at snapshot sequence, not clock or lexical hash order. The resolver takes a finite snapshot, roots, manifests, and policy, traverses dependency closure, and selects unique tips. It refuses missing or retracted tips, singleton conflicts, and failed relations; it never backtracks to an older revision. Stable pinned hashes remain readable with advisories. A floor can be derived only on totally ordered accepted ancestry; incomparable covering revisions require an explicit pinned covering revision and a coverage check. Registry snapshot and evaluation inputs are recorded in the certificate. Registry newest-tip selection is unchanged by the local update mode: local update validation accepts a host-selected pinned assembly and makes no newest-tip or publication claim.

Relations are finite equal or less_equal predicates over two qualified integer or scalar slot values, provided explicitly by defaults with matching meaning/units. Each endpoint is an object with instance_id and slot; in a contract, self names the declaring component and other instance ids name its manifest providers. Resolution maps these local references to assembly instance ids. Missing values or incompatible types yield Unknown and refuse any policy requiring the relation. Selection happens before relation checks. Adapters and explicit lineage migration are proposals; they do not introduce automatic search paths or silently change host resolver choices.

Law results, observations, attestations, and policy

A law_result binds a law suite, contract, implementation artifact, harness artifact, ordered fixture digests, seed, resource budgets, method, status, and an optional witness digest. The method is proof, exhaustive, or sampled. A proof requires a witness accepted by an independently specified and digest-bound proof checker. Exhaustive means every value of an explicitly finite domain was enumerated; its domain descriptor and count are in the witness. Sampled includes the exact recorded cases and proves only their outcomes. Proof and exhaustive results require a non-null witness; proof results also require a proof checker digest. Counterexamples require a witness naming the failing input. Inconclusive results require a non-empty diagnostic reason. A signature on a result proves who claimed it, not whether the law holds.

Status is pass, counterexample, or inconclusive. Timeout, crash, missing fixtures, external access, or nondeterminism yields inconclusive, not pass. Harnesses receive fixed time, seed, fixtures, and resource budgets; network access, ambient files, process creation outside the sandbox, and uncontrolled clocks are forbidden. A harness sandbox unable to enforce those restrictions produces inconclusive. Seed alone is insufficient for reproducibility. An artifact with the same contract but different bytes must receive new law evaluation.

An observation binds artifact and contract digests, demanded slot scope, sample digest, independent observation count, confidence in integer parts per million, observation time, and expiry. Confidence aggregation takes the minimum over contributors to a particular claim; it does not claim a joint probabilistic guarantee for unrelated events. Contradictory observations create a repair draft and block promotion in that observed scope without rewriting the contract. Missing or expired observations satisfy no evidence requirement.

An attestation binds contract and artifact digests, authority/lineage, slot scope, claim, issue time, expiry, signer, and Ed25519 signature. The signature is over the canonical document without its signature member. Observation records use the same signing rule; unsigned traffic metadata cannot satisfy a trusted evidence policy. Issue and expiry times are UTC RFC3339 strings with exactly second precision and Z; expiry must exceed issue time. Verification receives evaluation time explicitly; at equality with expiry a claim is expired, and future-issued claims are invalid. Trust is determined from caller-supplied roots and authenticated key-history/revocation proofs included in the bundle. A legacy semver string is metadata until a trusted publisher signs such a claim.

The structural lattice is Reject < Unknown < PassDeclared, with meet as minimum and join as maximum. Identity success alone does not establish a binding; a binding reaches PassDeclared only when all declared structural checks pass. Law checks, observations, and attestations do not form a higher assurance ladder. A verdict includes assurance, law methods and statuses, evidence scope, attestation status, coverage, and a policy decision (accept or refuse). A known structural counterexample is Reject; a missing contract or incomplete required structural analysis is Unknown.

A policy declares structural minimum, required law ids, allowed law methods, minimum fresh observation count/confidence, whether scoped attestations are required, trusted signer ids, and law resource budgets. Each binding must satisfy policy for all demanded slots. Overlays can establish declared structure only for explicitly modelled, digest-bound demands. Traffic-derived partial overlays disclose Unknown outside their observed domain. Passing integration tests attach sampled law evidence; they cannot alone turn Unknown structure into PassDeclared. Expired attestation changes the attestation status and may refuse a requiring policy while preserving independent structural and law results. No policy can accept structural Reject or a relevant law counterexample.

Cache entries are immutable check records. Structural keys are (old_contract, new_contract, checker). Law keys additionally include implementation, harness, suite, fixtures, seed, method, and budgets. Current decisions also depend on assembly/demand, policy digest, evidence digest set, trust-root digest, revocation history, and explicit evaluation time. v1 does not cache final policy decisions: it recomputes them from cached checks and current input validity. Same-contract artifacts, new evidence, expired claims, or revoked keys therefore cannot reuse a stale policy acceptance.

Certificate bundle and independent verification

A certificate contains the assembly hash, policy hash, checker artifact hash, registry snapshot head, evaluation time, and proof record digests. Its content-addressed bundle contains the assembly, all manifests and contracts, policy, law results, observations, attestations, sidecars, registry inclusion/consistency/key-history proofs, and witnesses referenced by those records. Artifacts and harnesses needed to replay executable laws are supplied as raw digest-addressed blobs. Unsupported proof formats yield inconclusive; v1 does not invent a generic proof language or treat an opaque witness as valid. A policy requiring such a proof cannot pass until a supported independently specified checker verifies it.

The caller separately supplies the expected assembly commitment, policy commitment, trust roots, evaluation time, and allowed checker digest(s). These are verifier inputs; values taken solely from the untrusted certificate cannot replace them. Historic verification evaluates claims at the recorded time only when the caller explicitly supplies that time; current verification evaluates at the caller’s current evaluation time. A historical pass does not authorize current deployment.

Verification proceeds as follows:

  1. Validate wire structure and canonical digests of every document; compare the assembly and policy hashes with the caller’s commitments and enforce the caller’s checker allowlist.
  2. Reconstruct exact dependency closure from root instances and manifests; reject missing or extraneous components, demands, bindings, or artifacts. A missing root with its subtree is detected by the external assembly commitment. Reject duplicate ids and competing bindings.
  3. Independently check every binding, singleton, relation, and artifact/sidecar match. Do not call the resolver and do not claim that the chosen provider is currently the newest.
  4. Verify referenced law results by replay or an accepted independently checkable witness. Verify signatures, inclusion and key-history proofs against the caller’s trust roots and snapshot. Reevaluate claim validity at the caller’s evaluation time.
  5. Compute per-binding assurance, method-labelled coverage, and policy decisions. Aggregate structural assurance with meet; accept only if every required binding and global constraint passes policy.

A negative composition result also has a certificate containing the committed attempted assembly and an independently checkable failure or missing-reference diagnostic. A missing blob produces Unknown/refusal rather than a fabricated structural counterexample. Corrupted blobs, malformed certificates, or mismatched caller commitments are verification errors, not compatibility evidence. A local update report is not a registry certificate: it carries no registry snapshot head, no inclusion or key-history proofs, and no publication or ancestry claim, and it never replaces v1 native certificate rules or wire grammar.

Structural verification performs indexed visits proportional to bindings B plus reachable schema nodes S plus proof bytes P. Replay costs are reported separately with policy resource bounds; repeated shared documents are hashed once per bundle. Benchmarks report B, S, P, replay work, checker version, and hardware instead of claiming a wall-clock ratio with an unspecified tolerance.

Registry and deployment coordination

Namespace bootstrap is an append-only entry signed by a trust-root-authorized namespace authority. It names the initial owner and a distinct recovery key. A qualified identity is (authority, lineage), preventing a public name from shadowing a configured private authority. Ordinary rotation requires old and new signatures. Recovery uses the predesignated recovery key, explicitly revokes the compromised key from a log sequence, and flags affected submissions; past bytes are immutable. Loss of both owner and recovery keys cannot be bypassed: publication remains refused until a separately governed new namespace is established. Mirrors are equivalent only for the same authenticated snapshot and caller inputs; consistency proofs cannot detect split views without comparison to a trusted checkpoint.

A deployment live snapshot enumerates every revision reachable under the consumer’s routing, its artifact, observation time, TTL, and coordination generation. Each physical live instance has instance_id and the logical assembly component_instance_id. A routes entry names logical consumer/provider ids and the physical revision ids it can reach; every route id must resolve to a reported revision of that provider. An empty required route or an omitted manifest provider route blocks the gate. In-flight consumer manifests and signed write_barrier records are referenced by digest; barriers name the writer, minimum readable revision, monotone sequence, and committed or Unknown state. All reachable providers must cover the floor, not just the highest revision. Missing reports, reports from the future, or evaluation_time ≥ observed_at + ttl yield Unknown; default TTL is 60 seconds. A consumer can use a new floor during a provider roll only after old routes are drained or routing pins it exclusively to covering instances.

A deployment coordinator provides serializable leases spanning both live and planned consumers, provider routing, floors, and irreversible-write barriers. A gate verdict records snapshot generation, lease id, and validity deadline. Before every route change, promotion, rollback, and retirement the coordinator atomically checks the generation and lease, revalidates floors against all live/in-flight consumers, and commits the state transition. Lease expiry, generation conflict, or unreachable coordinator aborts; rerun the gate on a fresh snapshot. Reports alone without this coordination cannot authorize deployment. The pure gate receives explicit time and snapshot; collection and coordination are external effects.

Unsatisfied prerequisites alone contribute floor-order edges. A cycle of already satisfied service dependencies is allowed; a cycle of unsatisfied new floors is refused. Irreversible writers persist a monotone first-write barrier before acknowledging the first incompatible write. Unknown barrier status fails closed, and canary aborts follow the same rollback restrictions as full deployments. Default retirement grace is seven continuous days of empty fresh known demand and zero traffic; renewed demand or a missing report restarts the interval. Authorized emergency overrides can waive only enumerated policy findings, never structural Reject, incomplete reachability, coordination failures, or irreversible barriers.

Adoption, extractor diagnostics, and command results

Observe is read-only and shadow preserves host exit status. First activation of gate atomically persists an immutable baseline digest and scoped findings with owner and acknowledgements expiring in 30 days. If persistence fails, gate activation is refused. init, reruns, branch checkout, and level changes do not reset the baseline. A deliberate baseline replacement requires an authorized signer, reason, old and new digests, expiry, and an appended audit event. Acknowledgement renewal also appends an event; expired acknowledgements refuse enforcement even for old findings. Unsupported ecosystems remain Unknown: observe/shadow report diagnostics successfully; gate/native must satisfy their policy.

Historical releases with unavailable source or failed extraction remain Unknown nodes. Unknown nodes do not establish accretion edges. Source bundles include every imported schema, build option, and generated input an extractor needs; all are hashed. An extractor inventories exported declarations using stable source ranges. Known unsupported constructs become opaque slots; parser failure or incomplete declaration inventory prevents a complete extraction claim. False-break rate reports use independently adjudicated candidate breaks as the denominator, include the adjudication source and sample count, and report false_break_rate_ppm:null (Unknown) when that count is zero; otherwise the value is floor(1000000 * false_breaks / adjudicated_breaks).

All commands emit an envelope before human rendering. It contains schema version, command, structural assurance, policy decision, tier_reports, slots, coverage, checker digest, known consumer ids, an explicit false undeclared-consumer coverage flag, and diagnostics. Deploy commands additionally populate the typed deployment member with stage, revision hashes, gate decision, and lease digest; other commands use null. Coverage uses numerator and denominator with null ratio for an empty domain. Diagnostics have stable code, severity, source path when known, slot ids, and a reason. Exit 0 means the operation completed and policy accepted (or observe/shadow intentionally report only); exit 1 means a computed policy refusal; exit 2 means malformed input, missing required local files, or execution failure. An inconclusive check is a policy refusal when required, not a passing test.

Registry proof encoding and publication records

v1 deliberately uses a full hash-chain proof rather than an underspecified compact Merkle proof. Each log_entry has zero-based sequence, the previous entry’s canonical digest, a typed event payload, signer id, signature algorithm, and signature. The first entry’s previous is the sentinel sha256: followed by 64 zero digits; this sentinel does not identify a contract. The head is the last entry’s canonical digest, or the sentinel for an empty log. A registry_proof contains entries in increasing sequence with no gaps. Verification rehashes every entry, validates each predecessor link and signature, and verifies any caller checkpoint as an exact prefix. Two supplied heads are consistent only if the shorter authenticated chain is an exact prefix of the longer. Compact proofs require a separately versioned format; no logarithmic proof-size claim is made for v1.

All Ed25519 public keys decode to 32 bytes and signatures to 64 bytes. Bootstrap entries are verified with caller-authorized namespace authority keys. Each later entry is verified with the active owner at that sequence, except recovery entries, which require the predesignated recovery key. Ordinary rotation’s incoming-key new_signature signs the canonical entry with outer signature and nested new_signature removed; the outgoing key signs the entry with only outer signature removed, including that incoming signature. Ownership updates apply after the entry. Recovery names the old key and the first compromised sequence, not later than the recovery entry; submissions from that key at or after that sequence are flagged and cannot satisfy current policy. Historical validation discloses that later recovery was not known at its recorded snapshot. Losing both keys does not permit an unsigned bypass.

A publication names authority, lineage, contract and artifact digests, parent contract hashes, stability, bridge status, and adapter hashes. Parent hashes must belong to that authority/lineage except an explicitly declared predecessor lineage recorded as an unbridged or adapted boundary. The first lineage publication has no same-lineage parents. Subsequent candidates accrete all same-lineage parents and ancestors. Competing children mark the accepted ancestry forked until an explicit all-parent merge. Experimental retractions and advisories are authenticated log events referencing the affected publication; a pinned artifact remains available. Registry availability is a prerequisite: missing raw artifacts remain a reported failure, rather than being implied available by an append-only metadata log.

Contract sunsets list dates and output slot names projected to disappear. They are immutable within a lineage, and introducing an earlier disappearance is a break. earliest_break returns the least listed date or null. A schedule is a disclosed future service-retirement risk, not permission to mutate a content-addressed contract or remove stable-lineage slots. Current structural checks stay clock-free; deploy policy evaluates the schedule with explicit time and uses a new lineage or retirement rules for actual removal.

Semantic checks additionally enforce interval ordering, default type membership, uniquely named slots/laws/relations, sorted set fields, manifest completeness matching unresolved usage, and publication/sidecar authority consistency. Coverage has numerator ≤ denominator; ratio_ppm is floor(1000000 * numerator / denominator), or null when denominator is zero. Lossless adapters have empty lost_slots and a non-null reverse; lossy adapters list every accepted loss. Source/target adapter digests must match a binding’s actual endpoint contracts. Attestations and observations must cover every demanded slot for which their policy is required. Public keys, timestamps, and decoded base64 lengths are checked semantically; JSON Schema alone does not establish signatures or canonical identity.