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

“Oh baby baby, it’s a wild world It’s hard to get by just upon a smile Oh baby baby, it’s a wild world I’ll always remember you like a child, girl” — Cat Stevens

wild

wild is a language-agnostic test selection engine… no — that’s its sibling. wild does machine-checked compatibility and composition of software components, modelled as a category of contracts: contracts declare what a component provides and requires, tiers order ecosystem authority, and a checker verifies structural compatibility — first-party or third-party — before an update ships.

Part of the charly-vibes toolshed.

Status

A design with a prototype and a Rust implementation. The wild extract and wild check subcommands are implemented and runtime-tested; the manual describes the intended interface and marks what is implemented.

Crates.io. The publishable package is wild-vibes — the wild crate name on crates.io belongs to an unrelated glob-expansion crate. The repository, binary, and wire-format identities remain wild.

Quick Start

git clone https://github.com/charly-vibes/wild
cd wild
cargo build

# Extract design contracts from a Rust crate (beads wild-mh5.x)
./target/debug/wild extract --request request.json --output out/

# Run a scoped structural check against the extracted artifact
./target/debug/wild check --request request.json --format json --report report.json

Key Concepts

  • Contracts: structural manifests of what a component provides and requires
  • Tiers: ecosystem ordering — language standard library above frameworks, frameworks above first-party code
  • Compatibility checking: machine-checked structural conformance of candidate updates against declared contracts
  • Semantic composition: how compatibility composes (and where it doesn’t) — see the Specodelic specs

Continue

Release Status

Generated artifact (docs.yml, from Cargo.toml + git ref). Do not hand-edit — the repo source files remain authoritative.

  • Version: v0.2.0
  • Built from: main @ 0c8f9dc

wild: manual

Machine-checked compatibility for software components, first-party or third-party.

Status, read first. wild is a design with a prototype, not a finished tool. What exists today: a nine-file specification suite (specs/, lint-clean), a toy checker (wild_sim.py), prototype extractors for Rust, Python, and command-line tools (wild_proto.py, experiments/cli_extract.py), and experiments on real projects. The wild command described below is the intended interface. Sections are marked [prototype] where code exists and [designed] where only the spec exists. The normative v1 formats and JSON Schema are specified; the older TOML sketch below is illustrative and is not the wire protocol.


1. What it does

Version numbers are claims. wild replaces them with checks.

For every release of a component it extracts a contract (what the component provides and what it requires), compares it with earlier releases, and decides mechanically whether the new release can replace the old one. For a set of components that must work together it decides whether they compose, picks the revisions, and produces a certificate that anyone can re-check offline.

You get three things:

  1. A compatibility verdict per change, computed from contracts, not from a version label.
  2. A composition verdict per assembly, with a certificate.
  3. A deploy order and rollback rules derived from those contracts, so continuous deployment needs no manual ordering.

2. The idea in one page

  • A component’s contract is a set of named slots. A slot is something it provides (an output, a function, a command, a field) or requires (an input a caller must supply).
  • Revision B is an accretion of revision A when it provides at least what A provided and requires no more than A required. Old users keep working.
  • Accretions compose and have identities, so they form a category (a preorder). This is what lets verdicts chain: if B accretes A and C accretes B, then C accretes A, with no re-check needed.
  • A change that is not an accretion is a break. A break must start a new lineage (a new name), with explicitly directed adapters or a disclosed unbridged boundary. Nobody is silently moved across a break.
  • A consumer states its demand: the slots it actually uses. Scoped replacement checks demanded outputs and every required dependency of the replacement. Incomplete dynamic demand prevents a scoped safety claim.
  • Checks run in tiers ordered by cost. Identity and shape check declared structure. Law results disclose proof, exhaustive, or sampled methods; evidence and signed attestations add separate scoped claims.

3. Concepts

TermMeaning
ContractThe set of slots, laws, limits, and defaults of one component revision.
SlotA named provided or required item with a type. Outputs have out polarity, inputs in.
OpennessEach record or sum is open (consumers must tolerate additions) or closed (default). Growing a closed output sum is a break.
RevisionA contract identified by the hash of its canonical form. Never edited.
LineageAn authority-qualified ancestry of accretive revisions with one accepted tip; unmerged forks refuse automatic selection.
AccretionThe relation “this revision can replace that one”. Reflexive and transitive.
BreakAny change that is not an accretion. Starts a new lineage.
AdapterA checked bridge from one lineage to another (facade library, wire proxy, data upcaster, or component wrapper).
DemandThe slots a consumer uses, derived from its code and tests.
FloorThe least covering revision on ordered ancestry; incomparable covering minima require an explicit pin.
LawA recorded property that must keep holding (for example idempotency). Laws accumulate across revisions.
TombstoneA record that a required slot was dropped, so its name can never return with a different meaning.
CertificateA committed assembly, policy, and proof bundle checked offline against caller-supplied commitments, trust roots, checker allowlist, and evaluation time.

Tiers and verdicts

TierWhat it checksNature
0 identityHashes and lineage namesexact, instant
1 shapeProvides, requires, polarity, openness, limits, defaultsexact, deterministic
2 lawsAccumulated laws against a digest-bound implementation and harnessproof, exhaustive, or sampled
3 evidenceReplayed traffic, consumer tests, canarystatistical
4 attestationA signed human claim with scope and expiryhuman

Structural assurance forms the lattice Reject < Unknown < PassDeclared. Reports separately name law methods/results, observation scope, attestation status, and the policy decision. Passing samples or version claims cannot establish structural assurance. Expired claims stop satisfying their policy requirement while independent checks remain valid. The word “compatible” alone is never printed.

4. How a change flows

source ──extract──▶ contract ──identify──▶ revision hash
                                   │
        tier 1 shape ◀─────────────┤   (checked against every ancestor)
        tier 2 laws  ◀─────────────┤
                                   ▼
             accretion?  ──yes──▶ publish to lineage
                  │
                  no ──▶ new lineage + bridge status ──▶ publish
                                   │
consumers: demand ─▶ resolve ─▶ certificate ─▶ verify (offline)
                                   │
deploy: floors ─▶ gate ─▶ canary ─▶ roll ─▶ live ─▶ retire old lineage when demand is zero

5. Using it

5.1 First week in an existing project [designed]

wild adopts a project in four levels. Each adds enforcement; none changes your package manager, registry, or release process.

wild init                # writes extractor config, a baseline, and a CI hook; no edits needed
wild adopt observe       # read-only: rebuilds your release history from contracts
wild adopt shadow        # CI reports verdicts but never fails a build
wild adopt gate          # rejects new breaks and expired baseline acknowledgements
wild adopt native        # publishes sidecar records next to your existing artifacts
  • observe extracts available historical releases, retains unavailable ones as Unknown, and lists disagreements between version labels and computed changes.
  • baseline: first enforcement atomically records existing findings with an owner and acknowledgements expiring in 30 days. Rerunning init or changing levels never resets it; replacement and renewal require signed audit events. Expired acknowledgements reject.
  • native adds a sidecar record that binds your host artifact’s digest to a revision hash. Your package, tag, and version are never modified.

5.2 Publishing a release (provider) [designed]

wild extract .           # source → contract (draft)
wild check               # tiers 0-2 against every earlier revision, locally
wild publish             # signs and appends the revision to the registry log

check tells you which tier rejected and why: the tier, the slot or law, and the rule. Typical outcomes:

You didVerdict
Added an output slot or an optional inputaccretion, publish
Removed an output or widened its value domainbreak: new lineage with adapter or unbridged status
Made an optional input requiredbreak
Added a variant to a closed output sumbreak
Changed a declared default or tightened a provided limitbreak
Reactivated a tombstoned input as required or with narrower acceptancerejected

5.3 Handling a break [designed]

wild adapt acme.billing acme.payments    # drafts an adapter, TODO on each slot it cannot map
wild check --adapter                      # round-trip laws on recorded samples
wild publish --lineage acme.payments
  • A draft adapter has an explicit TODO for every slot the tool cannot derive.
  • An adapter declares its source/target hashes and losses. A lossless claim needs a reverse mapping and round-trip checks whose proof, exhaustive, or sampled method is disclosed. An infeasible adapter leaves an explicit unbridged boundary.
  • Consumers whose demand does not touch the broken slot may move to the new lineage without an adapter. Moving is always opt-in.

5.4 Consuming a component [designed]

wild demand              # derive the slots you use from code and tests (editable)
wild lock import         # read your existing lockfile; unresolvable entries become Unknown
wild update              # advice only: per candidate version, are your slots still compatible?
  • update reports compatibility advice without changing the host resolver choice. Scoped replacement also checks new required dependencies; unresolved dynamic calls prevent a complete-demand claim.
  • Contracted lock entries pin authority, lineage, contract hash, and artifact digest. Unresolved entries retain their host locator and Unknown status; aliases are provenance, never identities.

5.5 Composing components [designed]

wild resolve             # unique accepted tip per lineage; refuse unresolved forks or constraints
wild certify             # write the certificate
wild verify bundle.json  # offline; expected assembly/policy, trust roots and time are explicit inputs
  • Resolution traverses finite dependency closure and selects each lineage’s unique accepted tip. Forks, singleton conflicts, and failed relations refuse selection without backtracking. Different required lineages remain separate copies.
  • A component declared singleton has exactly one instance and one lineage per assembly.
  • Values that cross between lineages need an adapter; otherwise the boundary is reported as unbridged.
  • Assembly structural assurance is the meet of binding assurance; each binding must also satisfy law, evidence, and attestation policy. The report discloses coverage and method.

5.6 Deploying [designed]

wild deploy plan         # derive the order from floors; manual ordering is not accepted
wild deploy gate         # a consumer deploys only if its providers are live at or above its floor
wild deploy rollback     # refuses to roll a provider below any live consumer's floor
wild deploy retire       # retires an old lineage when no known consumer demands it
  • Only unsatisfied floor prerequisites contribute ordering edges. A cycle of satisfied dependencies is allowed; an unsatisfied prerequisite cycle is refused with its members listed.
  • A revision that writes data older revisions cannot read must declare itself irreversible; rollback past it is rejected after its first write.
  • Every traffic-reachable provider revision must cover the floor. Reports expire at their TTL boundary (default 60 seconds); missing or future-dated reports block. A coordinator lease and snapshot generation are revalidated atomically at each route change, promotion, or rollback.
  • An emergency override records scope, signer, reason, and expiry. It cannot bypass structural Reject, Unknown reachability, coordination failure, or irreversible-write barriers. Retirement needs seven continuous days of fresh empty known demand and zero traffic by default.

5.7 Third-party software without contracts [designed; extractors partly prototyped]

  • Overlay: you may publish an overlay contract for an upstream package, bound to its artifact digest and labelled inferred.
  • Tests as laws: your passing integration tests against an uncontracted upstream are recorded as laws of your own component.
  • Version claims remain metadata until a trusted publisher signs a scoped, expiring attestation; they never substitute for structural or law checks.
  • An uncontracted edge has Unknown structural assurance. An explicit digest-bound overlay can declare covered structure; integration tests provide sampled law evidence for their exercised domain.

6. Reading a report

Every command emits a JSON envelope by default when not attached to a terminal, and a human rendering on request. The envelope carries the tier, the verdict, and the slot ids. A report also states the checker version and lists which consumers are known and which cannot be known.

Example (illustrative):

check acme.billing  (rev 4f2a… → 91c0…)   checker 0.1
  tier 0 identity   pass
  tier 1 shape      REJECT   invoice.total: output type int32 → str
  stopped at tier 1 (first reject)
  known consumers: 3 declared. Undeclared consumers are not covered.

7. Writing a contract (illustrative TOML sketch)

The wire format is versioned JSON in wild v1 formats, with structural examples. The TOML sketch below explains the concepts and is not accepted as v1 wire input. Extractors produce draft contracts; manual declarations fill semantic meaning, laws, limits, defaults, and unsupported constructs.

lineage   = "acme.billing"
stability = "stable"            # stable | experimental | deprecated

[[slot]]
name = "invoice.total"
polarity = "out"
type = "decimal(2)"

[[slot]]
name = "invoice.status"
polarity = "out"
type = "sum"
variants = ["draft", "paid"]
openness = "open"               # consumers must tolerate new variants

[[slot]]
name = "charge.amount"
polarity = "in"
type = "decimal(2)"

[limit]
"batch.size" = { max = 500 }

[[law]]
name = "charge.idempotent"

8. What it does not do

  • Undeclared behavior. A change in behavior behind an unchanged signature is caught only by a law or by evidence (tier 2 or 3). In experiments it was the main residual.
  • Consumers it cannot see. Retirement and “safe to remove” are safe only against known consumers.
  • Governance. Namespace disputes, typosquatting, business decisions to shut a service, and hardware retirements are out of scope; they can be recorded as attestations.
  • Lossy extraction. The contract is a common denominator. What an extractor cannot express becomes an opaque slot, which is frozen, so it can cause false breaks. Extractors report their opaque share and false-break rate.
  • Emergent behavior. Properties of a whole system, such as retry amplification, are outside per-contract checking.

9. Evidence so far

All from toy models or small real experiments; none from a production deployment.

  • The accretion relation passed exhaustive reflexivity and transitivity checks over 76 single-slot states (438,976 triples) after four rule fixes found by the same tests.
  • In a synthetic ecosystem, lineage resolution broke zero dependencies and needed no search; with truthful labels it coincides with semver-with-duplicates, so the gain is machine-checked labels.
  • genesis-vibes and specodelic (Rust): across 15 consecutive genesis-vibes releases, Cargo’s 0.x caret rule and the contract check disagreed on 6, including one patch release that added a public struct field. specodelic’s actual usage tolerated 1 to 6 more genesis versions than its Cargo range allowed. No compile test was possible.
  • Flask/Werkzeug and requests/urllib3 (Python): on 28 real version combinations, accuracy against an execution oracle was 0.89 for the contract check with call-site arguments and 0.75 for declared version ranges. Small sample, and two extractor fixes were made after seeing failures.
  • specodelic’s own CLI: shapes were identical across v0.2.0 to v0.4.0, while lint behavior changed in two rules. A replayed corpus caught it; the shape tier could not.

10. Troubleshooting

SymptomLikely cause and fix
A change is rejected at tier 1 but you never touch that slotThe full check applies to the whole lineage. Publish as a new lineage; consumers whose demand is unaffected can adopt it unaided.
Many breaks on the first runUse the baseline; breaks present at baseline are recorded, not rejected.
False breaks on an opaque slotReplace opaque with a typed slot in the extractor config, or accept the reported opaque share.
A dependency shows UnknownIt has no contract. Add an overlay, rely on tests-as-laws, or accept the weaker tier.
Deploy gate blocksA provider is not live at your floor, or its live-revision report is stale.
Rollback refusedA live consumer’s floor is above the revision you chose; roll those consumers back first.
Verification fails offlineThe certificate is incomplete or a hash was altered; regenerate it from the registry.

11. Reference

Commands [designed]

CommandPurpose
initWrite extractor config, baseline, and CI hook
extract <source>Source to contract draft
checkRun tiers 0 to 2 against every earlier revision
publishSign and append a revision
adapt <old> <new>Draft an adapter across lineages
demandDerive consumer demand
lock importImport an existing lockfile
updatePer-candidate compatibility advice
resolve / certify / verifyComposition, certificate, offline check
deploy plan / gate / rollback / retireRollout rules
adopt observe / shadow / gate / nativeAdoption levels
statusLevel, per-tier share of dependencies, open acknowledgements
explainWhy a verdict was reached

Specification map

SpecCovers
wildUmbrella: computed, verifiable, honest verdicts
wild.coreContract IR and the accretion category
wild.tiersTier pipeline and verdict lattice
wild.composeAssemblies, resolution, certificates
wild.registryAppend-only log, ownership, lockfile, sidecar
wild.bridgeAdapters, overlays, third-party software
wild.adoptStaged adoption
wild.deployGate, canary, rollback, retirement
wild.extractExtractors and law harness

Format reference

Wild v1 formats defines canonical bytes, IR, manifests, locks, sidecars, policies, evidence, certificate bundles, registry proofs, and deployment coordination. The schema and examples are structurally validated. Runtime conformance remains future work; current simulations exercise smaller models.

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.

JSON Schema

The v1 protocol schema, mirrored from schemas/wild-v1.schema.json. Structural examples live in schemas/examples-v1.json.

Wild design

Mirrored from docs/wild-design.md — the design document backing the specodelic specs.

Design standard

Mirrored from docs/design-standard.md — how designs are proposed, reviewed, and ratified in this repo.

wild


id: wild kind: intent statement: THE wild SHALL let software components, first-party or third-party, be composed on machine-checked contracts, so that compatibility is determined autonomously and verifiably instead of asserted by version numbers.

Wild

Purpose

This is a normative design specification; only the prototype and corpus gate scenarios explicitly identified below are implemented. Shared wire formats and decision rules are defined in wild v1 formats and the v1 schema.

Umbrella spec. Contracts form a category: objects are contract revisions, morphisms are accretions (provides grow, requires shrink), and breaks cross lineages through adapters. Assemblies of components compose on top of that category and yield a certificate any independent verifier can re-check. The other specs refine one concern each: wild.core (contracts and accretion), wild.tiers (verdict pipeline), wild.compose (assemblies, resolution, certificates), wild.registry (log, ownership, lock), wild.bridge (adapters, overlays, third parties), wild.adopt (brownfield adoption), wild.deploy (rollout), wild.extract (extractors and law harness).

Constraints

idkindexprtraces_to
compatibility_computedinvariantno compatibility verdict is derived from a version string; version strings are metadata and attestation input only[[wild]]
decision_autonomousinvariantgiven contracts and demand, the composition verdict is computed without human input; human judgment enters only as attestation[[wild]]
decision_verifiableinvariantevery composition verdict ships a certificate that an independent verifier can re-check[[wild]]
offline_verifiableinvariantverification uses the v1 certificate bundle and caller-supplied assembly commitment, policy, trust roots, and evaluation time defined in docs/wild-formats-v1.md; no network or registry write access[[wild]]
language_blindinvariantthe core operates on the Contract IR only; ecosystem knowledge lives in extractors[[wild]]
category_structureinvariantcontract accretion is reflexive and transitive; assembly composition is a partial operation on compatible, explicitly identified interfaces and obeys identity and associativity wherever defined[[wild]]
honest_scopeinvarianta verdict states its tier and its coverage and never claims more than was checked[[wild]]
no_silent_downgradeinvariantlost coverage cannot increase assurance; expired attestations cease satisfying attestation policy without erasing independently valid structural or law results[[wild]]
checker_versionedinvariantevery recorded verdict names the checker version; changing the checker never rewrites an existing verdict[[wild]]
output_envelopeinvariantevery command emits the v1 JSON envelope with assurance, decision, tier_reports, slots, coverage, checker, and disclosed consumers; the human rendering is derived from it[[wild]]
honest_verdict_labelsinvarianta verdict names structural assurance, law method, evidence scope, and attestation policy result; the bare word compatible is never emitted[[wild]]
open_world_disclosedadvisoryevery report lists known consumers and states that undeclared consumers are not covered[[wild]]

Model

States

  • requested
  • resolved
  • certified
  • verified
  • refused

Transitions

idfromtoguard
resolverequestedresolved[[wild.decision_autonomous]] ∧ [[wild.compatibility_computed]]
certifyresolvedcertified[[wild.decision_verifiable]]
verifycertifiedverified[[wild.offline_verifiable]] ∧ [[wild.checker_versioned]]
refuse_unresolvedrequestedrefused[[wild.honest_scope]]
refuse_staleresolvedrefused[[wild.no_silent_downgrade]]
refuse_invalidcertifiedrefused[[wild.honest_scope]]

Properties

idkindderives_fromgeneratorpredicate
version_string_never_decidesunit[[wild.compatibility_computed]]release_labelled_patch_that_removes_a_slot()verdict == Reject regardless of label
verdict_needs_no_humanunit[[wild.decision_autonomous]]contracts_and_demand()compute(c, d) completes with no interactive input
verdict_has_certificateunit[[wild.decision_verifiable]]arbitrary_composition_verdict()certificate present ∧ verify(certificate) == verdict
verification_is_offlineunit[[wild.offline_verifiable]]verify_with_network_and_registry_disabled()verify(certificate) completes
core_has_no_ecosystem_importsunit[[wild.language_blind]]core_module_dependency_graph()no dependency edge to any extractor
category_laws_holdlaw[[wild.category_structure]]arbitrary_contract_chain(length: 3)identity: compose(id, f) == f associativity: compose(compose(f, g), h) == compose(f, compose(g, h))
verdict_states_its_scopeunit[[wild.honest_scope]]arbitrary_verdict()verdict has structural assurance, law methods, evidence scope, attestation status, and coverage
lost_coverage_lowers_verdictunit[[wild.no_silent_downgrade]]assembly_gaining_an_uncontracted_dependency()coverage(after) < coverage(before) ∧ assurance(after) ≤ assurance(before)
verdict_names_checkerunit[[wild.checker_versioned]]verdict_recorded_then_checker_upgraded()recorded.checker == old ∧ recorded unchanged
envelope_matches_humanunit[[wild.output_envelope]]arbitrary_check_result()parse(render_human(r)) agrees with envelope(r)
bare_compatible_never_emittedunit[[wild.honest_verdict_labels]]arbitrary_passing_result()output names structural assurance, law method, and evidence scope ∧ not equals "compatible"
unknown_consumers_disclosedunit[[wild.open_world_disclosed]]report_with_known_consumers([a, b])report states undeclared consumers are not covered

Notes

Value proposition: determine composition across modules, components, and packages, first or third party, autonomously and verifiably. Autonomy comes from computing verdicts over contracts; verifiability from certificates re-checked offline by a separate verifier; the category structure is what lets verdicts compose (transitivity of accretion, associativity of assembly composition).

What the evidence says (toy simulations with assumed parameters, not data about real registries): the accretion relation needed four rule fixes before it passed exhaustive reflexivity and transitivity checks; with truthful labels, lineage resolution and semver-with-duplicates coincide, so the gain is machine-checked labels; undeclared behavior stays the weak spot and is only reached through laws and evidence. These limits are why honest_scope and open_world_disclosed exist.

Design acceptance cases

These cases define future runtime behavior. They are not claims that the current prototypes implement the v1 protocol. Executable document and prototype gates are under Requirements.

Rule: Compatibility computed

The system SHALL satisfy compatibility_computed as defined in the Constraints table and the v1 format reference.

Acceptance case: Version string never decides

  • GIVEN the fixture domain release_labelled_patch_that_removes_a_slot()
  • WHEN the compatibility_computed check runs
  • THEN verdict == Reject regardless of label

Rule: Decision autonomous

The system SHALL satisfy decision_autonomous as defined in the Constraints table and the v1 format reference.

Acceptance case: Verdict needs no human

  • GIVEN the fixture domain contracts_and_demand()
  • WHEN the decision_autonomous check runs
  • THEN compute(c, d) completes with no interactive input

Rule: Decision verifiable

The system SHALL satisfy decision_verifiable as defined in the Constraints table and the v1 format reference.

Acceptance case: Verdict has certificate

  • GIVEN the fixture domain arbitrary_composition_verdict()
  • WHEN the decision_verifiable check runs
  • THEN certificate present ∧ verify(certificate) == verdict

Rule: Offline verifiable

The system SHALL satisfy offline_verifiable as defined in the Constraints table and the v1 format reference.

Acceptance case: Verification is offline

  • GIVEN the fixture domain verify_with_network_and_registry_disabled()
  • WHEN the offline_verifiable check runs
  • THEN verify(certificate) completes

Rule: Language blind

The system SHALL satisfy language_blind as defined in the Constraints table and the v1 format reference.

Acceptance case: Core has no ecosystem imports

  • GIVEN the fixture domain core_module_dependency_graph()
  • WHEN the language_blind check runs
  • THEN no dependency edge to any extractor

Rule: Category structure

The system SHALL satisfy category_structure as defined in the Constraints table and the v1 format reference.

Acceptance case: Category laws hold

  • GIVEN the fixture domain arbitrary_contract_chain(length: 3)
  • WHEN the category_structure check runs
  • THEN identity: compose(id, f) == f associativity: compose(compose(f, g), h) == compose(f, compose(g, h))

Rule: Honest scope

The system SHALL satisfy honest_scope as defined in the Constraints table and the v1 format reference.

Acceptance case: Verdict states its scope

  • GIVEN the fixture domain arbitrary_verdict()
  • WHEN the honest_scope check runs
  • THEN verdict has structural assurance, law methods, evidence scope, attestation status, and coverage

Rule: No silent downgrade

The system SHALL satisfy no_silent_downgrade as defined in the Constraints table and the v1 format reference.

Acceptance case: Lost coverage lowers verdict

  • GIVEN the fixture domain assembly_gaining_an_uncontracted_dependency()
  • WHEN the no_silent_downgrade check runs
  • THEN coverage(after) < coverage(before) ∧ assurance(after) ≤ assurance(before)

Rule: Checker versioned

The system SHALL satisfy checker_versioned as defined in the Constraints table and the v1 format reference.

Acceptance case: Verdict names checker

  • GIVEN the fixture domain verdict_recorded_then_checker_upgraded()
  • WHEN the checker_versioned check runs
  • THEN recorded.checker == old ∧ recorded unchanged

Rule: Output envelope

The system SHALL satisfy output_envelope as defined in the Constraints table and the v1 format reference.

Acceptance case: Envelope matches human

  • GIVEN the fixture domain arbitrary_check_result()
  • WHEN the output_envelope check runs
  • THEN parse(render_human(r)) agrees with envelope(r)

Rule: Honest verdict labels

The system SHALL satisfy honest_verdict_labels as defined in the Constraints table and the v1 format reference.

Acceptance case: Bare compatible never emitted

  • GIVEN the fixture domain arbitrary_passing_result()
  • WHEN the honest_verdict_labels check runs
  • THEN output names structural assurance, law method, and evidence scope ∧ not equals "compatible"

Rule: Open world disclosed

The system SHALL satisfy open_world_disclosed as defined in the Constraints table and the v1 format reference.

Acceptance case: Unknown consumers disclosed

  • GIVEN the fixture domain report_with_known_consumers([a, b])
  • WHEN the open_world_disclosed check runs
  • THEN report states undeclared consumers are not covered

Acceptance case: Historical certificate does not authorize current use

  • GIVEN an attestation was valid at certificate creation but is now expired
  • WHEN the caller requests current verification with the later evaluation time
  • THEN historic checks remain immutable and current attestation policy refuses

Requirements

Requirement: Spec corpus integrity

The spec corpus SHALL stay lint-clean and reference-closed, so every constraint, property, and model row in the corpus remains checkable by the specodelic toolchain.

Scenario: Spec corpus stays lint-clean and reference-closed

  • GIVEN the dual-format corpus under openspec/specs
  • WHEN spk lint openspec and specodelic graph openspec run
  • THEN lint reports no issues and no warnings across all nine files
  • AND the reference graph reports no dangling references
  • AND the gate executes this behavior as a declared contract test

Requirement: Ecosystem gate wiring

The three ecosystem gates (ah, pretender, testaruda) SHALL be wired as hard gates, so quality checks are machine-enforced rather than advisory.

Scenario: Gates wired and standard true

  • GIVEN the wired gate configs (.espectacular/config.toml, justfile, lefthook.yml, pretender.toml, testaruda.toml)
  • WHEN the wiring gate runs ah check, pretender check, spk lint openspec, and testaruda select --safe
  • THEN the three gate configs exist on disk and parse clean
  • AND they carry the standard sections and follow the hardcoded-gate pattern
  • AND the openspec spec corpus is lint-clean and reference-closed
  • AND the gated tests run clean
  • AND the gate executes this behavior as a declared contract test

Requirement: Wild design contract

The design corpus SHALL expose this capability’s constraints as normative, self-contained rules with acceptance cases, and SHALL link to a structurally valid shared v1 schema without claiming future runtime behavior is implemented.

Scenario: Wild design is self-contained

  • GIVEN this spec, docs/wild-formats-v1.md, and schemas/wild-v1.schema.json
  • WHEN the design contract gate checks normative rule coverage, local references, and the shared schema
  • THEN every constraint has a corresponding rule and acceptance case
  • AND both referenced files exist and the schema is valid JSON Schema draft 2020-12
  • AND this capability is discoverable by strict OpenSpec validation

wild-core


id: wild.core kind: intent statement: THE wild core SHALL represent each software contract as a content-addressed set of typed slots and decide accretion between revisions as a category with checkable laws.

Wild core

Purpose

This is a normative design specification; only the prototype and corpus gate scenarios explicitly identified below are implemented. Shared wire formats and decision rules are defined in wild v1 formats and the v1 schema.

The Contract IR and the accretion relation. A contract has slots with polarity (out provides, in requires), openness, limits, defaults, laws, and facets. Revision v' accretes v when provides grow and requires shrink. Accretions form a thin category (a preorder); restricting to a consumer’s demand is a functor. A non-accretion must start a new lineage.

Constraints

idkindexprtraces_to
identity_content_addressedinvariantrevision.id == hash(canonical(contract)); equal ids imply identical contracts[[wild.core]]
canonical_form_stableinvariantcanonical(c) is independent of slot order, whitespace, extractor, host, and clock[[wild.core]]
hash_algorithm_in_identityinvariantan identity names its hash algorithm; identities under different algorithms are never equal[[wild.core]]
lineage_name_versionlessinvariantlineage.name is namespaced, non-empty, and has no version component[[wild.core]]
name_meaning_immutableinvariantwithin a lineage, slot name, facet, polarity, and semantic meaning are immutable; types may evolve only by the variance rules in docs/wild-formats-v1.md; law definitions are immutable and law sets only grow[[wild.core]]
slot_shapes_closedinvariantv1 slot shape ∈ {scalar, record, sum, sequence, map, function, opaque}; adding a shape requires a new IR schema version, not merely a new contract hash[[wild.core]]
accretion_monotoneinvariantaccretes(v, v') iff every old output remains with a subtype, each retained input accepts a supertype, no new required input appears, tombstones persist, and defaults, limits, laws, and facets satisfy docs/wild-formats-v1.md[[wild.core]]
polarity_openness_declaredinvariantevery record and sum declares open or closed (default closed); a closed output sum growing, opening, or becoming unrestricted is a break; an input sum growing is an accretion; an input sum losing tolerance is a break[[wild.core]]
limits_are_slotsinvariantdeclared limits (size, cardinality, timeout) are slots; tightening a provided limit or loosening a required limit is a break[[wild.core]]
defaults_are_slotsinvariantdefaults and environment assumptions are slots; a changed provided default is a break[[wild.core]]
opaque_is_frozeninvariantany change to an opaque slot is a break[[wild.core]]
facets_independentinvariantcompat(v, v') is the conjunction over facets of compat_facet(v, v'); facets ∈ {api, abi, layout, serialization, behavior, dialect, environment, license}; adding a facet kind requires a new IR schema version[[wild.core]]
data_artifacts_have_contractsinvariantcontent files, templates, and generated feature files consumed by code carry a contract checked like an API, including arity and size limits[[wild.core]]
tombstones_preserve_namesinvarianta dropped requires leaves a tombstone; re-adding the name must accrete the tombstoned slot[[wild.core]]
accretion_is_categoryinvariantaccretions have identities and compose; composing accretions yields an accretion; the relation is reflexive and transitive[[wild.core]]
check_against_ancestorsinvarianta candidate revision is checked against every ancestor in its lineage, not only its predecessor[[wild.core]]
demand_restriction_functorialinvariantrestricting a contract to a demand set preserves accretion and composes: restrict(restrict(c, D1), D2) == restrict(c, D1 ∩ D2)[[wild.core]]
break_requires_new_lineageinvarianta non-accretion may be published only under a new lineage name[[wild.core]]
stability_tiersinvariantlineage stability ∈ {stable, experimental, deprecated}; only experimental lineages may be retracted[[wild.core]]
sunset_computableinvarianta contract with a sunset schedule exposes the earliest date at which its provides shrink, queryable before that date[[wild.core]]
fork_merge_pushoutinvarianta merge is published only if its contract accretes every branch ancestor and has no conflicting meaning, default, limit, or law definition; unresolved conflicts list names and are refused; an unmerged fork has no implicit newest revision[[wild.core]]

Model

States

  • drafted
  • canonical
  • identified
  • accretive
  • lineage_break
  • rejected

Transitions

idfromtoguard
canonicalizedraftedcanonical[[wild.core.canonical_form_stable]]
identifycanonicalidentified[[wild.core.identity_content_addressed]] ∧ [[wild.core.hash_algorithm_in_identity]]
accreteidentifiedaccretive[[wild.core.accretion_monotone]] ∧ [[wild.core.check_against_ancestors]]
breakidentifiedlineage_break[[wild.core.break_requires_new_lineage]]
rejectidentifiedrejectedviolation of [[wild.core.name_meaning_immutable]] or invalid v1 IR

Properties

idkindderives_fromgeneratorpredicate
hash_matches_contentunit[[wild.core.identity_content_addressed]]arbitrary_contract()id(c) == hash(canonical(c))
canonical_is_order_independentunit[[wild.core.canonical_form_stable]]arbitrary_contract(), permutation_of_slots()canonical(c) == canonical(permute(c))
algorithms_never_collideunit[[wild.core.hash_algorithm_in_identity]]same_bytes_hashed_with_two_algorithms()id_a != id_b
versioned_lineage_name_rejectedunit[[wild.core.lineage_name_versionless]]lineage_name_with_version_suffix("acme.billing.v2")check(name) == failed
redefined_meaning_rejectedunit[[wild.core.name_meaning_immutable]](r, r') with a changed slot meaning or a narrowed input typecheck(r, r') == failed; variance-safe type refinement with unchanged meaning passes
unknown_shape_rejectedunit[[wild.core.slot_shapes_closed]]slot_with_shape("tensor")check(slot) == failed
removed_provide_is_breakunit[[wild.core.accretion_monotone]]contract_pair_with(provide_removed: true)accretes(v, v') == false
closed_output_growth_is_breakunit[[wild.core.polarity_openness_declared]]closed_output_sum_with_added_variant()accretes == false; the same addition in input position yields true
tightened_limit_is_breakunit[[wild.core.limits_are_slots]]provided_limit_lowered(500 → 200)accretes == false
changed_default_is_breakunit[[wild.core.defaults_are_slots]]provided_default_changed(30 → 5)accretes == false
opaque_change_is_breakunit[[wild.core.opaque_is_frozen]]opaque_slot_with_changed_content()accretes == false
facet_break_blocks_compatunit[[wild.core.facets_independent]]pair_with_break_in_exactly_one_facet()compat == failed
feature_file_arity_checkedunit[[wild.core.data_artifacts_have_contracts]]template_defining_21_fields_fed_20_inputs()check == failed
tombstone_blocks_name_reuseunit[[wild.core.tombstones_preserve_names]]drop_then_readd_input_with_narrower_type()check(readd) == failed
accretion_category_lawslaw[[wild.core.accretion_is_category]]arbitrary_contract_chain(length: 3)identity: accretes(v, v) and compose(id, f) == f associativity: compose(compose(f, g), h) == compose(f, compose(g, h))
skipped_ancestor_break_caughtunit[[wild.core.check_against_ancestors]]chain_v1_v2_v3_where_v3_breaks_v1_only()check(v3) == failed
restriction_functor_lawslaw[[wild.core.demand_restriction_functorial]]arbitrary_contract(), two_demand_sets()identity: restrict(c, all_slots) == c associativity: restrict(restrict(c, D1), D2) == restrict(c, D1 ∩ D2)
break_in_lineage_rejectedunit[[wild.core.break_requires_new_lineage]]breaking_revision_under_same_lineage()publish == rejected
retracting_stable_rejectedunit[[wild.core.stability_tiers]]retract_request_on_stable_lineage()retract == rejected
scheduled_shrink_reportedunit[[wild.core.sunset_computable]]contract_with_sunset(date: d)earliest_break(c) == d
colliding_merge_refusedunit[[wild.core.fork_merge_pushout]]two_forks_defining_same_name_differently()merge == refused ∧ colliding names listed

Notes

Exhaustive small-scope testing (76 single-slot states, 438,976 triples) found four rule gaps in an early checker: optional inputs becoming required, open/closed flips, unrestricted versus restricted sums, and dropped names returning with a new meaning. They are encoded above as polarity_openness_declared and tombstones_preserve_names. The relation is a conjunction over names, so the single-name result extends to many slots by construction; this was argued, not tested.

The category is thin (at most one morphism between two revisions), so associativity and identity hold structurally; the properties guard the implementation, not the mathematics.

Design acceptance cases

These cases define future runtime behavior. They are not claims that the current prototypes implement the v1 protocol. Executable document and prototype gates are under Requirements.

Rule: Identity content addressed

The system SHALL satisfy identity_content_addressed as defined in the Constraints table and the v1 format reference.

Acceptance case: Hash matches content

  • GIVEN the fixture domain arbitrary_contract()
  • WHEN the identity_content_addressed check runs
  • THEN id(c) == hash(canonical(c))

Rule: Canonical form stable

The system SHALL satisfy canonical_form_stable as defined in the Constraints table and the v1 format reference.

Acceptance case: Canonical is order independent

  • GIVEN the fixture domain arbitrary_contract(), permutation_of_slots()
  • WHEN the canonical_form_stable check runs
  • THEN canonical(c) == canonical(permute(c))

Rule: Hash algorithm in identity

The system SHALL satisfy hash_algorithm_in_identity as defined in the Constraints table and the v1 format reference.

Acceptance case: Algorithms never collide

  • GIVEN the fixture domain same_bytes_hashed_with_two_algorithms()
  • WHEN the hash_algorithm_in_identity check runs
  • THEN id_a != id_b

Rule: Lineage name versionless

The system SHALL satisfy lineage_name_versionless as defined in the Constraints table and the v1 format reference.

Acceptance case: Versioned lineage name rejected

  • GIVEN the fixture domain lineage_name_with_version_suffix("acme.billing.v2")
  • WHEN the lineage_name_versionless check runs
  • THEN check(name) == failed

Rule: Name meaning immutable

The system SHALL satisfy name_meaning_immutable as defined in the Constraints table and the v1 format reference.

Acceptance case: Redefined meaning rejected

  • GIVEN the fixture domain (r, r') with a changed slot meaning or a narrowed input type
  • WHEN the name_meaning_immutable check runs
  • THEN check(r, r') == failed; variance-safe type refinement with unchanged meaning passes

Rule: Slot shapes closed

The system SHALL satisfy slot_shapes_closed as defined in the Constraints table and the v1 format reference.

Acceptance case: Unknown shape rejected

  • GIVEN the fixture domain slot_with_shape("tensor")
  • WHEN the slot_shapes_closed check runs
  • THEN check(slot) == failed

Rule: Accretion monotone

The system SHALL satisfy accretion_monotone as defined in the Constraints table and the v1 format reference.

Acceptance case: Removed provide is break

  • GIVEN the fixture domain contract_pair_with(provide_removed: true)
  • WHEN the accretion_monotone check runs
  • THEN accretes(v, v') == false

Rule: Polarity openness declared

The system SHALL satisfy polarity_openness_declared as defined in the Constraints table and the v1 format reference.

Acceptance case: Closed output growth is break

  • GIVEN the fixture domain closed_output_sum_with_added_variant()
  • WHEN the polarity_openness_declared check runs
  • THEN accretes == false; the same addition in input position yields true

Rule: Limits are slots

The system SHALL satisfy limits_are_slots as defined in the Constraints table and the v1 format reference.

Acceptance case: Tightened limit is break

  • GIVEN the fixture domain provided_limit_lowered(500 → 200)
  • WHEN the limits_are_slots check runs
  • THEN accretes == false

Rule: Defaults are slots

The system SHALL satisfy defaults_are_slots as defined in the Constraints table and the v1 format reference.

Acceptance case: Changed default is break

  • GIVEN the fixture domain provided_default_changed(30 → 5)
  • WHEN the defaults_are_slots check runs
  • THEN accretes == false

Rule: Opaque is frozen

The system SHALL satisfy opaque_is_frozen as defined in the Constraints table and the v1 format reference.

Acceptance case: Opaque change is break

  • GIVEN the fixture domain opaque_slot_with_changed_content()
  • WHEN the opaque_is_frozen check runs
  • THEN accretes == false

Rule: Facets independent

The system SHALL satisfy facets_independent as defined in the Constraints table and the v1 format reference.

Acceptance case: Facet break blocks compat

  • GIVEN the fixture domain pair_with_break_in_exactly_one_facet()
  • WHEN the facets_independent check runs
  • THEN compat == failed

Rule: Data artifacts have contracts

The system SHALL satisfy data_artifacts_have_contracts as defined in the Constraints table and the v1 format reference.

Acceptance case: Feature file arity checked

  • GIVEN the fixture domain template_defining_21_fields_fed_20_inputs()
  • WHEN the data_artifacts_have_contracts check runs
  • THEN check == failed

Rule: Tombstones preserve names

The system SHALL satisfy tombstones_preserve_names as defined in the Constraints table and the v1 format reference.

Acceptance case: Tombstone blocks name reuse

  • GIVEN the fixture domain drop_then_readd_input_with_narrower_type()
  • WHEN the tombstones_preserve_names check runs
  • THEN check(readd) == failed

Rule: Accretion is category

The system SHALL satisfy accretion_is_category as defined in the Constraints table and the v1 format reference.

Acceptance case: Accretion category laws

  • GIVEN the fixture domain arbitrary_contract_chain(length: 3)
  • WHEN the accretion_is_category check runs
  • THEN identity: accretes(v, v) and compose(id, f) == f associativity: compose(compose(f, g), h) == compose(f, compose(g, h))

Rule: Check against ancestors

The system SHALL satisfy check_against_ancestors as defined in the Constraints table and the v1 format reference.

Acceptance case: Skipped ancestor break caught

  • GIVEN the fixture domain chain_v1_v2_v3_where_v3_breaks_v1_only()
  • WHEN the check_against_ancestors check runs
  • THEN check(v3) == failed

Rule: Demand restriction functorial

The system SHALL satisfy demand_restriction_functorial as defined in the Constraints table and the v1 format reference.

Acceptance case: Restriction functor laws

  • GIVEN the fixture domain arbitrary_contract(), two_demand_sets()
  • WHEN the demand_restriction_functorial check runs
  • THEN identity: restrict(c, all_slots) == c associativity: restrict(restrict(c, D1), D2) == restrict(c, D1 ∩ D2)

Rule: Break requires new lineage

The system SHALL satisfy break_requires_new_lineage as defined in the Constraints table and the v1 format reference.

Acceptance case: Break in lineage rejected

  • GIVEN the fixture domain breaking_revision_under_same_lineage()
  • WHEN the break_requires_new_lineage check runs
  • THEN publish == rejected

Rule: Stability tiers

The system SHALL satisfy stability_tiers as defined in the Constraints table and the v1 format reference.

Acceptance case: Retracting stable rejected

  • GIVEN the fixture domain retract_request_on_stable_lineage()
  • WHEN the stability_tiers check runs
  • THEN retract == rejected

Rule: Sunset computable

The system SHALL satisfy sunset_computable as defined in the Constraints table and the v1 format reference.

Acceptance case: Scheduled shrink reported

  • GIVEN the fixture domain contract_with_sunset(date: d)
  • WHEN the sunset_computable check runs
  • THEN earliest_break(c) == d

Rule: Fork merge pushout

The system SHALL satisfy fork_merge_pushout as defined in the Constraints table and the v1 format reference.

Acceptance case: Colliding merge refused

  • GIVEN the fixture domain two_forks_defining_same_name_differently()
  • WHEN the fork_merge_pushout check runs
  • THEN merge == refused ∧ colliding names listed

Acceptance case: Canonical identity rejects ambiguous JSON

  • GIVEN a contract JSON document with a duplicate object key or floating-point value
  • WHEN canonicalization runs
  • THEN the input is refused before hashing; permuted valid slot arrays yield identical bytes

Acceptance case: Variance preserves semantic identity

  • GIVEN an input integer slot changes from interval [0,10] to [0,20] with unchanged meaning
  • WHEN accretion is checked
  • THEN the refinement passes; changing meaning or narrowing to [0,5] rejects

Acceptance case: Tombstone reactivation cannot introduce a requirement

  • GIVEN a previously removed input is present only as a tombstone
  • WHEN the candidate reintroduces it as required
  • THEN accretion rejects even when its type accepts the old domain

Requirements

Requirement: Prototype accretion pipeline

The prototype tier pipeline SHALL run the round-1 accretion scenarios end to end and emit a machine-readable verdict record per scenario, so declared round-1 outcomes remain executable while wild itself is unbuilt; the prototype uses a smaller type model and does not establish full v1 conformance.

Scenario: Prototype accretion pipeline reports round-1 verdicts

  • GIVEN the round-1 scenario fixtures encoded in prototype/wild_sim.py
  • WHEN the prototype simulation runs
  • THEN it exits 0 and emits a JSON array of verdict records, each carrying an id and a decision trace matching the declared expected terminal state
  • AND known undeclared-behavior escapes remain reported rather than being silently converted to passing safety claims
  • AND the gate executes this behavior as a declared contract test

Requirement: Wild core design contract

The design corpus SHALL expose this capability’s constraints as normative, self-contained rules with acceptance cases, and SHALL link to a structurally valid shared v1 schema without claiming future runtime behavior is implemented.

Scenario: Wild core design is self-contained

  • GIVEN this spec, docs/wild-formats-v1.md, and schemas/wild-v1.schema.json
  • WHEN the design contract gate checks normative rule coverage, local references, and the shared schema
  • THEN every constraint has a corresponding rule and acceptance case
  • AND both referenced files exist and the schema is valid JSON Schema draft 2020-12
  • AND this capability is discoverable by strict OpenSpec validation

wild-tiers


id: wild.tiers kind: intent statement: THE wild tier pipeline SHALL decide each revision’s verdict through checks ordered by cost, where structural checks can reject, executable law checks disclose their method, and observations and attestations never override structural rejection.

Wild tiers

Purpose

This is a normative design specification; only the prototype and corpus gate scenarios explicitly identified below are implemented. Shared wire formats and decision rules are defined in wild v1 formats and the v1 schema.

Checks run in cost order: identity, shape, laws, evidence, attestation. Identity and shape decide declared structure. Law results distinguish proof, exhaustive finite enumeration, and sampling; a passing sample proves only that sample. Evidence and signed attestations are separate scoped claims. The verdict product and policy evaluation are defined in docs/wild-formats-v1.md.

Constraints

idkindexprtraces_to
fail_fast_orderinginvarianttiers run in order identity < shape < laws < evidence < attestation; a run stops at the first Reject[[wild.tiers]]
exact_tiers_pureinvariantidentity and shape are pure functions of canonical contracts and checker version; law evaluation is reproducible only with the implementation digest, harness digest, seed, fixture digests, and resource limits in the v1 bundle[[wild.tiers]]
verdict_latticeinvariantstructural assurance forms the lattice Reject < Unknown < PassDeclared; executable laws, observations, and attestations are separate scoped records; assembly assurance is the structural meet and policy checks every binding as defined in docs/wild-formats-v1.md[[wild.tiers]]
policy_names_min_tierinvarianteach context has a v1 policy naming structural floor, allowed law methods, required law ids, evidence thresholds, and any required attestations; missing or failed required checks refuse the operation[[wild.tiers]]
rejection_explainsinvarianta Reject names the tier, the slot or law, and the rule that failed[[wild.tiers]]
laws_cumulativeinvariantlaws(v') ⊇ ⋃ laws(ancestors); every ancestor law passes against the v' implementation[[wild.tiers]]
law_runs_deterministicinvariantthe same complete harness inputs yield the same law result; seed, implementation and harness digests, fixtures, budgets, and method are recorded; timeout, crash, or nondeterminism is inconclusive and cannot pass required policy[[wild.tiers]]
evidence_cannot_override_exactinvariantobservations may add scoped evidence to a structural Pass; they cannot override a structural Reject or a law counterexample[[wild.tiers]]
evidence_confidence_conservativeadvisoryreported confidence is the minimum over contributing observations, never a product[[wild.tiers]]
contradiction_triggers_repairinvariantobserved behavior contradicting the declared contract creates a repair draft; the contract is never edited silently[[wild.tiers]]
attestation_scopedinvariantan attestation names its signer, its scope (lineage and slots), and its claim[[wild.tiers]]
attestation_expiringinvariantan attestation carries issue time and expiry and is bound to artifact and contract digests; at evaluation_time ≥ expiry the attestation status is Unknown while independent checks remain unchanged[[wild.tiers]]
verdict_cache_keyedinvariantstructural cache keys include old and new contract hashes and checker version; law cache keys also include implementation, harness, fixtures, seed, method, and budgets; policy evaluation includes demand, policy digest, evidence digests, trust roots, and evaluation time and is never reused past claim expiry[[wild.tiers]]
verdict_recorded_immutableinvariantrecorded check results are immutable; new inputs append new records; current policy decisions are recomputed from those records and claim validity at evaluation time[[wild.tiers]]

Model

States

  • draft
  • identified
  • shape_checked
  • law_checked
  • published
  • observed
  • attested
  • rejected

Transitions

idfromtoguard
identifydraftidentified[[wild.tiers.exact_tiers_pure]]
shape_checkidentifiedshape_checked[[wild.tiers.fail_fast_ordering]] ∧ preserves wild-core accretion_monotone
law_checkshape_checkedlaw_checked[[wild.tiers.laws_cumulative]]
publishlaw_checkedpublished[[wild.tiers.policy_names_min_tier]] ∧ requires wild-registry registry_append_only
observepublishedobserved[[wild.tiers.evidence_cannot_override_exact]]
attestobservedattested[[wild.tiers.attestation_expiring]]
repairobserveddraft[[wild.tiers.contradiction_triggers_repair]]
reject_identityidentifiedrejected[[wild.tiers.rejection_explains]]
reject_shapeshape_checkedrejected[[wild.tiers.rejection_explains]]
reject_lawslaw_checkedrejected[[wild.tiers.rejection_explains]]
reviserejecteddraft[[wild.tiers.verdict_recorded_immutable]]

Properties

idkindderives_fromgeneratorpredicate
first_reject_stops_rununit[[wild.tiers.fail_fast_ordering]]revision_failing_identity_and_laws()tiers_run == [identity] ∧ verdict == Reject
exact_tiers_ignore_side_inputsunit[[wild.tiers.exact_tiers_pure]]same_inputs_with_varied_clock_and_network()verdict(a) == verdict(b)
verdict_lattice_lawslaw[[wild.tiers.verdict_lattice]]three_arbitrary_verdicts()identity: meet(v, PassDeclared) == v associativity: meet(meet(a, b), c) == meet(a, meet(b, c))
below_policy_refusedunit[[wild.tiers.policy_names_min_tier]]verdict_PassDeclared_under_policy_requiring_laws()decision == refused
reject_names_ruleunit[[wild.tiers.rejection_explains]]arbitrary_rejected_revision()report has tier ∧ slot_or_law ∧ rule
ancestor_law_failure_rejectedunit[[wild.tiers.laws_cumulative]]revision_violating_an_ancestor_law()law_check == failed
law_run_reproducibleunit[[wild.tiers.law_runs_deterministic]](contract, impl, seed) run twicerun(a) == run(b)
evidence_never_overrides_rejectunit[[wild.tiers.evidence_cannot_override_exact]]shape_Reject_plus_clean_traffic_replay()verdict == Reject
confidence_is_minimumunit[[wild.tiers.evidence_confidence_conservative]]observations_with_confidences([0.99, 0.90])confidence == 0.90
contradiction_creates_draftunit[[wild.tiers.contradiction_triggers_repair]]observed_behavior_outside_declared_contract()repair_draft_created ∧ contract_unchanged
attestation_without_scope_rejectedunit[[wild.tiers.attestation_scoped]]attestation_missing_scope()check(a) == failed
expired_attestation_is_unknownunit[[wild.tiers.attestation_expiring]]attestation_with_past_expiry()attestation_status(a) == Unknown ∧ independent_assurance unchanged
cache_key_includes_checkerunit[[wild.tiers.verdict_cache_keyed]]same_pair_under_two_checker_versions()keys differ ∧ no cross-hit
recorded_verdict_unchangedunit[[wild.tiers.verdict_recorded_immutable]]verdict_recorded_then_rerun_under_new_checker()old record unchanged ∧ new record appended

Notes

Evidence is graded because failures are correlated, so confidence is the minimum, never a product. Simulation round 1 (12 scenarios): six shape breaks were caught at tier 1, two behavior changes at tier 2 through laws, one at tier 3 through canary replay, one safe input widening was correctly passed, and two undeclared behavior changes escaped. Escapes of undeclared behavior are the known residual of this design.

Design acceptance cases

These cases define future runtime behavior. They are not claims that the current prototypes implement the v1 protocol. Executable document and prototype gates are under Requirements.

Rule: Fail fast ordering

The system SHALL satisfy fail_fast_ordering as defined in the Constraints table and the v1 format reference.

Acceptance case: First reject stops run

  • GIVEN the fixture domain revision_failing_identity_and_laws()
  • WHEN the fail_fast_ordering check runs
  • THEN tiers_run == [identity] ∧ verdict == Reject

Rule: Exact tiers pure

The system SHALL satisfy exact_tiers_pure as defined in the Constraints table and the v1 format reference.

Acceptance case: Exact tiers ignore side inputs

  • GIVEN the fixture domain same_inputs_with_varied_clock_and_network()
  • WHEN the exact_tiers_pure check runs
  • THEN verdict(a) == verdict(b)

Rule: Verdict lattice

The system SHALL satisfy verdict_lattice as defined in the Constraints table and the v1 format reference.

Acceptance case: Verdict lattice laws

  • GIVEN the fixture domain three_arbitrary_verdicts()
  • WHEN the verdict_lattice check runs
  • THEN identity: meet(v, PassDeclared) == v associativity: meet(meet(a, b), c) == meet(a, meet(b, c))

Rule: Policy names min tier

The system SHALL satisfy policy_names_min_tier as defined in the Constraints table and the v1 format reference.

Acceptance case: Below policy refused

  • GIVEN the fixture domain verdict_PassDeclared_under_policy_requiring_laws()
  • WHEN the policy_names_min_tier check runs
  • THEN decision == refused

Rule: Rejection explains

The system SHALL satisfy rejection_explains as defined in the Constraints table and the v1 format reference.

Acceptance case: Reject names rule

  • GIVEN the fixture domain arbitrary_rejected_revision()
  • WHEN the rejection_explains check runs
  • THEN report has tier ∧ slot_or_law ∧ rule

Rule: Laws cumulative

The system SHALL satisfy laws_cumulative as defined in the Constraints table and the v1 format reference.

Acceptance case: Ancestor law failure rejected

  • GIVEN the fixture domain revision_violating_an_ancestor_law()
  • WHEN the laws_cumulative check runs
  • THEN law_check == failed

Rule: Law runs deterministic

The system SHALL satisfy law_runs_deterministic as defined in the Constraints table and the v1 format reference.

Acceptance case: Law run reproducible

  • GIVEN the fixture domain (contract, impl, seed) run twice
  • WHEN the law_runs_deterministic check runs
  • THEN run(a) == run(b)

Rule: Evidence cannot override exact

The system SHALL satisfy evidence_cannot_override_exact as defined in the Constraints table and the v1 format reference.

Acceptance case: Evidence never overrides reject

  • GIVEN the fixture domain shape_Reject_plus_clean_traffic_replay()
  • WHEN the evidence_cannot_override_exact check runs
  • THEN verdict == Reject

Rule: Evidence confidence conservative

The system SHALL satisfy evidence_confidence_conservative as defined in the Constraints table and the v1 format reference.

Acceptance case: Confidence is minimum

  • GIVEN the fixture domain observations_with_confidences([0.99, 0.90])
  • WHEN the evidence_confidence_conservative check runs
  • THEN confidence == 0.90

Rule: Contradiction triggers repair

The system SHALL satisfy contradiction_triggers_repair as defined in the Constraints table and the v1 format reference.

Acceptance case: Contradiction creates draft

  • GIVEN the fixture domain observed_behavior_outside_declared_contract()
  • WHEN the contradiction_triggers_repair check runs
  • THEN repair_draft_created ∧ contract_unchanged

Rule: Attestation scoped

The system SHALL satisfy attestation_scoped as defined in the Constraints table and the v1 format reference.

Acceptance case: Attestation without scope rejected

  • GIVEN the fixture domain attestation_missing_scope()
  • WHEN the attestation_scoped check runs
  • THEN check(a) == failed

Rule: Attestation expiring

The system SHALL satisfy attestation_expiring as defined in the Constraints table and the v1 format reference.

Acceptance case: Expired attestation is unknown

  • GIVEN the fixture domain attestation_with_past_expiry()
  • WHEN the attestation_expiring check runs
  • THEN attestation_status(a) == Unknown ∧ independent_assurance unchanged

Rule: Verdict cache keyed

The system SHALL satisfy verdict_cache_keyed as defined in the Constraints table and the v1 format reference.

Acceptance case: Cache key includes checker

  • GIVEN the fixture domain same_pair_under_two_checker_versions()
  • WHEN the verdict_cache_keyed check runs
  • THEN keys differ ∧ no cross-hit

Rule: Verdict recorded immutable

The system SHALL satisfy verdict_recorded_immutable as defined in the Constraints table and the v1 format reference.

Acceptance case: Recorded verdict unchanged

  • GIVEN the fixture domain verdict_recorded_then_rerun_under_new_checker()
  • WHEN the verdict_recorded_immutable check runs
  • THEN old record unchanged ∧ new record appended

Acceptance case: Same contract different implementation requires new law checks

  • GIVEN two implementation artifacts have the same contract hash but different bytes
  • WHEN a law result cached for the first artifact is requested for the second
  • THEN the law cache misses and policy cannot reuse the first acceptance

Acceptance case: Expiry preserves independent structural checks

  • GIVEN a valid PassDeclared binding has an attestation expiring at 2026-10-06T15:00:00Z
  • WHEN evaluation occurs exactly at that timestamp
  • THEN attestation status is Unknown; structural assurance remains PassDeclared; policy requiring attestation refuses

Acceptance case: Timeout never becomes law pass

  • GIVEN a required sampled law reaches its resource budget without completing
  • WHEN the harness returns a result
  • THEN status is inconclusive and policy refuses

Acceptance case: Version claim cannot satisfy structural policy

  • GIVEN an uncontracted dependency has only a patch version label
  • WHEN policy requires PassDeclared
  • THEN the label remains metadata, assurance is Unknown, and policy refuses

Requirements

Requirement: Wild tiers design contract

The design corpus SHALL expose this capability’s constraints as normative, self-contained rules with acceptance cases, and SHALL link to a structurally valid shared v1 schema without claiming future runtime behavior is implemented.

Scenario: Wild tiers design is self-contained

  • GIVEN this spec, docs/wild-formats-v1.md, and schemas/wild-v1.schema.json
  • WHEN the design contract gate checks normative rule coverage, local references, and the shared schema
  • THEN every constraint has a corresponding rule and acceptance case
  • AND both referenced files exist and the schema is valid JSON Schema draft 2020-12
  • AND this capability is discoverable by strict OpenSpec validation

Requirement: Protected local checking context

An enforced local check SHALL receive its base, obligations, scope, policy, checker, test/law harnesses, environment, fixtures, budgets, and evaluation time from a trusted invocation outside candidate control. Candidate-proposed changes SHALL be evaluated against the accepted context first. An authorized obligation transition SHALL bind old/new commitments and be labelled intentional change rather than backward compatibility.

Scenario: Candidate edits its own judge

  • GIVEN a candidate deletes a law, narrows demand, or changes the policy or checker
  • WHEN trusted enforcement evaluates the candidate
  • THEN it retains the accepted context, reports the proposed change, and cannot accept by using the weaker candidate settings

Scenario: Authorized bug-fix changes an old obligation

  • GIVEN an external authority record accepts a named old-to-new obligation transition for a bug fix
  • WHEN the candidate passes the replacement requirements and unchanged obligations
  • THEN its disposition is accepted intentional change with affected consumers recorded, not backward-compatible success

Requirement: Evidence is bound and method labelled

Local evidence SHALL bind actual implementation and harness bytes, suite, fixtures, environment, scope, seed, and budgets. Current policy SHALL be evaluated afresh. Ordinary build/test success SHALL NOT become structural assurance or a v1 law result without the required harness guarantees. A sandbox that cannot enforce required restrictions SHALL yield inconclusive law evidence.

Scenario: Same contract but changed implementation

  • GIVEN an implementation changes bytes without changing its extracted contract
  • WHEN checking considers a previous executable law result
  • THEN that evidence cannot satisfy the new artifact’s law requirement

Scenario: Unsupported law isolation

  • GIVEN the available runner cannot prevent an accepted law from reading ambient files or the network
  • WHEN that law is required by policy
  • THEN its result is inconclusive and the local outcome is unknown unless another definite failure already requires rejection

wild-compose


id: wild.compose kind: intent statement: THE wild composer SHALL decide whether components at given revisions compose into a well-formed assembly, select revisions by deterministic lineage lookup within the supported model, and emit a certificate an independent verifier can re-check.

Wild compose

Purpose

This is a normative design specification; only the prototype and corpus gate scenarios explicitly identified below are implemented. Shared wire formats and decision rules are defined in wild v1 formats and the v1 schema.

An assembly is components plus bindings from required slots to provided slots. It is well-formed when every required slot is bound by a compatible provide. Substituting a component by an accretion of itself preserves well-formedness, which is what makes resolution a lookup instead of a search. Verdicts carry certificates that a separate verifier checks from content hashes.

Constraints

idkindexprtraces_to
assembly_is_bindingsinvariantan assembly is a set of component revisions plus bindings from each required slot to a provided slot[[wild.compose]]
binding_well_formedinvarianta binding is well-formed iff the v1 subtype relation holds for provider output and consumer input, limits and defaults satisfy demand, and facets and relations pass; an open provider sum binds only to an open consumer[[wild.compose]]
required_slots_boundinvariantevery required input of every component is bound by a well-formed binding[[wild.compose]]
substitution_preserves_assemblyinvariantreplacing a component with an accretion of itself keeps a well-formed assembly well-formed[[wild.compose]]
scoped_substitutioninvariantscoped replacement preserves every demanded output AND validates all required inputs of the replacement and its transitive dependency closure; restricting demand never hides newly introduced required inputs[[wild.compose]]
resolution_by_lineageinvariantfor a finite registry snapshot with one accepted tip per lineage, resolve traverses dependency closure using deterministic newest-tip lookup; missing tips, unmerged forks, singleton conflicts, or relation failures refuse selection without backtracking; dependency cycles reach a fixed point and are checked as a whole[[wild.compose]]
resolver_deterministicinvariantthe same registry snapshot and demand yield the same selection and certificate[[wild.compose]]
lineage_copies_listedinvariantwhen consumers demand different lineages of one package, each lineage is resolved separately and the copies are listed[[wild.compose]]
scoped_merge_proposedinvarianta consumer may be proposed a newer lineage when its demand accretes there; the move is a proposal and is never applied automatically[[wild.compose]]
boundary_needs_adapterinvariantvalues crossing between lineages need a registered adapter; otherwise the boundary is reported unbridged[[wild.compose]]
singleton_declaredinvarianta component declared singleton appears under exactly one lineage per assembly; a violation is a composition failure[[wild.compose]]
relation_slotsinvariantv1 equal and less_equal relations over declared scalar slots are checked after closure; missing values, incomparable types, and failed relations refuse composition; the resolver does not search older revisions to satisfy relations[[wild.compose]]
certificate_lists_bindingsinvariantthe v1 certificate names the assembly commitment, component instances, bindings, demanded slots, policy, checker, and content-addressed proof records; the bundle contains every referenced contract and proof[[wild.compose]]
certificate_completeinvariantverification compares the certificate assembly hash to the caller-supplied expected commitment, reconstructs closure from all component manifests, and rejects missing roots, components, demands, or required bindings[[wild.compose]]
certificate_tamper_evidentinvarianta corrupted hash or dropped binding fails verification; a substituted provider verifies only if it is compatible with the consumer's demand[[wild.compose]]
verifier_reads_only_certificateinvariantthe verifier reads the v1 bundle, caller-supplied assembly commitment, policy, trust roots, and evaluation time; it never calls the resolver or network[[wild.compose]]
verification_linearadvisoryverification performs O(B + S + P) indexed visits over bindings B, reachable contract/schema nodes S, and proof bytes P, excluding explicitly budgeted proof execution; benchmarking reports all three sizes and checker version[[wild.compose]]
coverage_reportedinvarianta composition verdict reports the share of bindings verified per tier; bindings to uncontracted providers are Unknown[[wild.compose]]
verdict_is_meetinvariantassembly structural assurance is the meet of binding assurance; required law, evidence, and attestation policy is evaluated for every binding; empty assemblies have PassDeclared assurance and vacuous coverage[[wild.compose]]
composition_is_categoryinvariantcompose is disjoint union of component instances and bindings with matching exposed interfaces; it is defined only when bindings, singleton constraints, and relations pass; empty assembly is identity and associativity holds where both sides are defined[[wild.compose]]

Model

States

  • demanded
  • resolved
  • certified
  • verified
  • unbridged
  • refused

Transitions

idfromtoguard
resolvedemandedresolved[[wild.compose.resolution_by_lineage]] ∧ [[wild.compose.resolver_deterministic]]
certifyresolvedcertified[[wild.compose.certificate_lists_bindings]]
verifycertifiedverified[[wild.compose.certificate_complete]] ∧ [[wild.compose.verifier_reads_only_certificate]]
flag_boundaryresolvedunbridged[[wild.compose.boundary_needs_adapter]]
bridgeunbridgedcertified[[wild.compose.certificate_lists_bindings]] ∧ requires a wild-bridge adapter_is_morphism
refuse_unboundresolvedrefused[[wild.compose.required_slots_bound]]
refuse_invalidcertifiedrefused[[wild.compose.binding_well_formed]]

Properties

idkindderives_fromgeneratorpredicate
assembly_lists_every_bindingunit[[wild.compose.assembly_is_bindings]]arbitrary_assembly()bindings cover all required slots
open_provider_needs_open_consumerunit[[wild.compose.binding_well_formed]]open_provider_sum_bound_to_closed_consumer()well_formed == false
unbound_required_slot_rejectedunit[[wild.compose.required_slots_bound]]assembly_with_one_unbound_required_input()well_formed == false
accretion_substitution_soundunit[[wild.compose.substitution_preserves_assembly]]well_formed_assembly_and_accepted_accretion()well_formed(after) == true
scoped_substitution_soundunit[[wild.compose.scoped_substitution]]assembly_and_change_accreting_on_used_slots()well_formed(after) == true
resolution_is_chain_maxunit[[wild.compose.resolution_by_lineage]]finite_snapshot_with_unique_tips_and_demand()selection == accepted tips ∧ backtracking_nodes == 0 or refusal lists violated constraints
resolution_reproducibleunit[[wild.compose.resolver_deterministic]]same_snapshot_resolved_twice()selection(a) == selection(b) ∧ cert(a) == cert(b)
copies_are_listedunit[[wild.compose.lineage_copies_listed]]consumers_on_two_lineages_of_one_package()report lists both copies
merge_is_a_proposalunit[[wild.compose.scoped_merge_proposed]]consumer_whose_demand_accretes_in_newer_lineage()proposal listed ∧ selection unchanged
unbridged_boundary_reportedunit[[wild.compose.boundary_needs_adapter]]value_crossing_lineages_without_adapter()status == unbridged
second_lineage_of_singleton_failsunit[[wild.compose.singleton_declared]]singleton_resolved_under_two_lineages()composition == failed
timeout_relation_checkedunit[[wild.compose.relation_slots]]backend_idle_timeout_below_balancer_timeout()composition == failed
certificate_names_all_fieldsunit[[wild.compose.certificate_lists_bindings]]arbitrary_certificate()each binding has consumer ∧ provider ∧ demand
missing_binding_rejectedunit[[wild.compose.certificate_complete]]certificate_with_one_binding_dropped()verify == rejected
corruption_detectedunit[[wild.compose.certificate_tamper_evident]]certificate_with_last_hash_digit_changed()verify == rejected
verifier_has_no_resolver_dependencyunit[[wild.compose.verifier_reads_only_certificate]]verifier_module_dependency_graph()no edge to resolver
verification_cost_linearunit[[wild.compose.verification_linear]]certificates_of_size([100, 1000, 10000])indexed visits ≤ k * (bindings + schema_nodes + proof_bytes) for recorded checker constant k
uncontracted_binding_is_unknownunit[[wild.compose.coverage_reported]]assembly_with_one_uncontracted_provider()binding.verdict == Unknown ∧ coverage lists it
verdict_equals_meetunit[[wild.compose.verdict_is_meet]]bindings_with_mixed_verdicts()assembly.assurance == meet(binding.assurance) ∧ policy checks each binding
assembly_composition_lawslaw[[wild.compose.composition_is_category]]three_assemblies_with_jointly_compatible_interfaces()identity: compose(empty, a) == a associativity: compose(compose(a, b), c) == compose(a, compose(b, c))

Notes

Simulation evidence (toy model, assumed parameters): 30,000 random four-component assemblies, 10,215 accepted accretions, zero assemblies broken by substitution; 22% of changes rejected by the full check were harmless to the specific assembly, which is the case for scoped_substitution. In a synthetic ecosystem (30 packages, 8 versions each), lineage resolution broke zero dependencies and needed no search, while a single-version semver resolver found no solution in 16.5% to 99% of cases depending on break rate and mislabelling. With truthful labels, lineage resolution and semver-with-duplicates coincide, so the contribution is machine-checked labels. A verifier re-checked about 41 bindings per assembly in about 1 ms and rejected all 750 corrupted-hash and 750 dropped-binding certificates.

Known limits: the wiring rule was tightened after the first run found 21 unsound cases involving open sums; that is a model decision, recorded in binding_well_formed. Assemblies in the tests had four components and four names (small-scope).

Design acceptance cases

These cases define future runtime behavior. They are not claims that the current prototypes implement the v1 protocol. Executable document and prototype gates are under Requirements.

Rule: Assembly is bindings

The system SHALL satisfy assembly_is_bindings as defined in the Constraints table and the v1 format reference.

Acceptance case: Assembly lists every binding

  • GIVEN the fixture domain arbitrary_assembly()
  • WHEN the assembly_is_bindings check runs
  • THEN bindings cover all required slots

Rule: Binding well formed

The system SHALL satisfy binding_well_formed as defined in the Constraints table and the v1 format reference.

Acceptance case: Open provider needs open consumer

  • GIVEN the fixture domain open_provider_sum_bound_to_closed_consumer()
  • WHEN the binding_well_formed check runs
  • THEN well_formed == false

Rule: Required slots bound

The system SHALL satisfy required_slots_bound as defined in the Constraints table and the v1 format reference.

Acceptance case: Unbound required slot rejected

  • GIVEN the fixture domain assembly_with_one_unbound_required_input()
  • WHEN the required_slots_bound check runs
  • THEN well_formed == false

Rule: Substitution preserves assembly

The system SHALL satisfy substitution_preserves_assembly as defined in the Constraints table and the v1 format reference.

Acceptance case: Accretion substitution sound

  • GIVEN the fixture domain well_formed_assembly_and_accepted_accretion()
  • WHEN the substitution_preserves_assembly check runs
  • THEN well_formed(after) == true

Rule: Scoped substitution

The system SHALL satisfy scoped_substitution as defined in the Constraints table and the v1 format reference.

Acceptance case: Scoped substitution sound

  • GIVEN the fixture domain assembly_and_change_accreting_on_used_slots()
  • WHEN the scoped_substitution check runs
  • THEN well_formed(after) == true

Rule: Resolution by lineage

The system SHALL satisfy resolution_by_lineage as defined in the Constraints table and the v1 format reference.

Acceptance case: Resolution is chain max

  • GIVEN the fixture domain finite_snapshot_with_unique_tips_and_demand()
  • WHEN the resolution_by_lineage check runs
  • THEN selection == accepted tips ∧ backtracking_nodes == 0 or refusal lists violated constraints

Rule: Resolver deterministic

The system SHALL satisfy resolver_deterministic as defined in the Constraints table and the v1 format reference.

Scope reconciliation: registry-mode newest-tip selection is retained unchanged; local validation accepts a host-selected pinned assembly and makes no newest-tip claim.

Acceptance case: Resolution reproducible

  • GIVEN the fixture domain same_snapshot_resolved_twice()
  • WHEN the resolver_deterministic check runs
  • THEN selection(a) == selection(b) ∧ cert(a) == cert(b)

Rule: Lineage copies listed

The system SHALL satisfy lineage_copies_listed as defined in the Constraints table and the v1 format reference.

Acceptance case: Copies are listed

  • GIVEN the fixture domain consumers_on_two_lineages_of_one_package()
  • WHEN the lineage_copies_listed check runs
  • THEN report lists both copies

Rule: Scoped merge proposed

The system SHALL satisfy scoped_merge_proposed as defined in the Constraints table and the v1 format reference.

Acceptance case: Merge is a proposal

  • GIVEN the fixture domain consumer_whose_demand_accretes_in_newer_lineage()
  • WHEN the scoped_merge_proposed check runs
  • THEN proposal listed ∧ selection unchanged

Rule: Boundary needs adapter

The system SHALL satisfy boundary_needs_adapter as defined in the Constraints table and the v1 format reference.

Acceptance case: Unbridged boundary reported

  • GIVEN the fixture domain value_crossing_lineages_without_adapter()
  • WHEN the boundary_needs_adapter check runs
  • THEN status == unbridged

Rule: Singleton declared

The system SHALL satisfy singleton_declared as defined in the Constraints table and the v1 format reference.

Acceptance case: Second lineage of singleton fails

  • GIVEN the fixture domain singleton_resolved_under_two_lineages()
  • WHEN the singleton_declared check runs
  • THEN composition == failed

Rule: Relation slots

The system SHALL satisfy relation_slots as defined in the Constraints table and the v1 format reference.

Acceptance case: Timeout relation checked

  • GIVEN the fixture domain backend_idle_timeout_below_balancer_timeout()
  • WHEN the relation_slots check runs
  • THEN composition == failed

Rule: Certificate lists bindings

The system SHALL satisfy certificate_lists_bindings as defined in the Constraints table and the v1 format reference.

Acceptance case: Certificate names all fields

  • GIVEN the fixture domain arbitrary_certificate()
  • WHEN the certificate_lists_bindings check runs
  • THEN each binding has consumer ∧ provider ∧ demand

Rule: Certificate complete

The system SHALL satisfy certificate_complete as defined in the Constraints table and the v1 format reference.

Acceptance case: Missing binding rejected

  • GIVEN the fixture domain certificate_with_one_binding_dropped()
  • WHEN the certificate_complete check runs
  • THEN verify == rejected

Rule: Certificate tamper evident

The system SHALL satisfy certificate_tamper_evident as defined in the Constraints table and the v1 format reference.

Acceptance case: Corruption detected

  • GIVEN the fixture domain certificate_with_last_hash_digit_changed()
  • WHEN the certificate_tamper_evident check runs
  • THEN verify == rejected

Rule: Verifier reads only certificate

The system SHALL satisfy verifier_reads_only_certificate as defined in the Constraints table and the v1 format reference.

Acceptance case: Verifier has no resolver dependency

  • GIVEN the fixture domain verifier_module_dependency_graph()
  • WHEN the verifier_reads_only_certificate check runs
  • THEN no edge to resolver

Rule: Verification linear

The system SHALL satisfy verification_linear as defined in the Constraints table and the v1 format reference.

Acceptance case: Verification cost linear

  • GIVEN the fixture domain certificates_of_size([100, 1000, 10000])
  • WHEN the verification_linear check runs
  • THEN indexed visits ≤ k * (bindings + schema_nodes + proof_bytes) for recorded checker constant k

Rule: Coverage reported

The system SHALL satisfy coverage_reported as defined in the Constraints table and the v1 format reference.

Acceptance case: Uncontracted binding is unknown

  • GIVEN the fixture domain assembly_with_one_uncontracted_provider()
  • WHEN the coverage_reported check runs
  • THEN binding.verdict == Unknown ∧ coverage lists it

Rule: Verdict is meet

The system SHALL satisfy verdict_is_meet as defined in the Constraints table and the v1 format reference.

Acceptance case: Verdict equals meet

  • GIVEN the fixture domain bindings_with_mixed_verdicts()
  • WHEN the verdict_is_meet check runs
  • THEN assembly.assurance == meet(binding.assurance) ∧ policy checks each binding

Rule: Composition is category

The system SHALL satisfy composition_is_category as defined in the Constraints table and the v1 format reference.

Acceptance case: Assembly composition laws

  • GIVEN the fixture domain three_assemblies_with_jointly_compatible_interfaces()
  • WHEN the composition_is_category check runs
  • THEN identity: compose(empty, a) == a associativity: compose(compose(a, b), c) == compose(a, compose(b, c))

Acceptance case: Scoped change adds an unbound dependency

  • GIVEN the replacement preserves demanded output a and introduces required input b
  • WHEN scoped substitution evaluates the replacement closure
  • THEN it refuses when b has no compatible provider

Acceptance case: Deleting a root subtree changes the commitment

  • GIVEN the caller supplies the expected assembly hash for roots a and b
  • WHEN a certificate omits root b and its entire subtree
  • THEN verification refuses the commitment mismatch before evaluating bindings

Acceptance case: Missing proof cannot establish law assurance

  • GIVEN a policy requires a law result whose implementation blob is absent
  • WHEN offline verification evaluates the bundle
  • THEN it reports Unknown or inconclusive and refuses that policy, without network access

Acceptance case: Empty assembly coverage is vacuous

  • GIVEN an assembly has no roots, components, or bindings
  • WHEN composition runs
  • THEN assurance is PassDeclared; coverage is 0/0 with null ratio

Acceptance case: Unmerged forks do not have a newest revision

  • GIVEN two accepted fork tips are incomparable
  • WHEN lineage lookup runs
  • THEN it refuses with both tip hashes until an explicit accretive merge is recorded
  • GIVEN the accepted tips violate a declared timeout relation but older revisions would pass
  • WHEN resolution completes closure and checks relations
  • THEN it refuses with the relation id; no older candidate is selected

Requirements

Requirement: Wild compose design contract

The design corpus SHALL expose this capability’s constraints as normative, self-contained rules with acceptance cases, and SHALL link to a structurally valid shared v1 schema without claiming future runtime behavior is implemented.

Scenario: Wild compose design is self-contained

  • GIVEN this spec, docs/wild-formats-v1.md, and schemas/wild-v1.schema.json
  • WHEN the design contract gate checks normative rule coverage, local references, and the shared schema
  • THEN every constraint has a corresponding rule and acceptance case
  • AND both referenced files exist and the schema is valid JSON Schema draft 2020-12
  • AND this capability is discoverable by strict OpenSpec validation

Requirement: Validate a host-selected local assembly

Local update evaluation SHALL validate the explicit assembly selected by the host lock rather than invoke registry newest-tip selection. It SHALL account for all roots, components, required inputs, transitive dependencies, declared singletons, and relations using existing v1 structural rules. Unknown entries SHALL remain in coverage and SHALL refuse policies requiring complete structure. The local report SHALL NOT claim native registry ancestry or constitute a v1 registry certificate.

Scenario: New provider dependency is not hidden by demand restriction

  • GIVEN a candidate preserves the consumer’s demanded output but adds an unsatisfied required dependency
  • WHEN the host-selected assembly is checked
  • THEN delivery is refused even though the root’s demanded output signature is unchanged

Scenario: Unknown dependency remains visible

  • GIVEN the lock contains a required dependency with no usable contract
  • WHEN the local assembly is evaluated under policy requiring declared structure
  • THEN that entry remains in the closure and coverage with Unknown assurance and delivery is refused

Scenario: Local pin does not claim newest lineage tip

  • GIVEN a valid explicitly pinned host assembly and no Wild registry
  • WHEN local structural checking succeeds
  • THEN the report identifies its local scope and makes no registry-tip or publication claim

wild-registry


id: wild.registry kind: intent statement: THE wild registry SHALL record revisions in an append-only, signed, auditable log and bind them to host ecosystem artifacts without altering those artifacts.

Wild registry

Purpose

This is a normative design specification; only the prototype and corpus gate scenarios explicitly identified below are implemented. Shared wire formats and decision rules are defined in wild v1 formats and the v1 schema.

The shared memory of the system: a authenticated hash-chained log with full v1 prefix proofs of signed revisions, adapters, advisories, and attestations. Consumers pin hashes from it. Host ecosystems (npm, Cargo, PyPI, Maven, containers) are never modified; a sidecar record ties a host artifact digest to a revision hash.

Constraints

idkindexprtraces_to
registry_append_onlyinvariantthe registry is a authenticated hash-chained log with full v1 prefix proofs; no revision is deleted or mutated after append[[wild.registry]]
consistency_proofsinvariantany two log heads can be checked for consistency by a proof, so a mirror can be audited[[wild.registry]]
signature_requiredinvariantevery submitted revision carries a signature by the lineage owner key[[wild.registry]]
namespace_ownershipinvarianteach authority-qualified lineage name maps to one active owner key at a log sequence; bootstrap requires a trusted namespace authority signature and public names never shadow a configured private authority[[wild.registry]]
key_rotation_signedinvariantnormal key rotation requires outgoing and incoming key signatures; compromise recovery requires the recovery key designated at namespace bootstrap, revokes the compromised key at an explicit sequence, and never rewrites historical entries[[wild.registry]]
lock_pins_hashesinvariantevery contracted v1 lock entry pins authority, lineage, contract hash, and artifact digest; unresolved host entries preserve their locator with Unknown status; tags and aliases are not identities[[wild.registry]]
sidecar_binds_artifact_digestinvarianta signed v1 sidecar binds host ecosystem, artifact locator, artifact digest, contract hash, extractor digest, and registry sequence; fetching bytes with a different artifact digest is rejected even if the contract is unchanged[[wild.registry]]
ecosystem_untouchedinvariantwild never replaces or mutates the host ecosystem's package, tag, or version; it adds a sidecar record[[wild.registry]]
advisories_never_deleteinvariantyanking or flagging a revision appends an advisory edge; the revision stays resolvable by hash[[wild.registry]]
retraction_only_experimentalinvariantexperimental retraction appends a notice and removes the revision from new tip selection; hash lookup retains bytes and notice; stable retraction is refused; no candidate yields Unknown[[wild.registry]]
mirror_equivalenceinvarianta mirror serving the same authenticated snapshot yields the same verdicts and certificates as the origin for identical caller policy, trust roots, and evaluation time[[wild.registry]]
verification_needs_no_writeinvariantreading, resolving, and verifying never require write access to the registry[[wild.registry]]

Model

States

  • submitted
  • signed
  • appended
  • advised
  • retracted

Transitions

idfromtoguard
signsubmittedsigned[[wild.registry.signature_required]] ∧ [[wild.registry.namespace_ownership]]
appendsignedappended[[wild.registry.registry_append_only]]
adviseappendedadvised[[wild.registry.advisories_never_delete]]
retractappendedretracted[[wild.registry.retraction_only_experimental]] ∧ per wild-core stability_tiers

Properties

idkindderives_fromgeneratorpredicate
rewrite_of_appended_rejectedunit[[wild.registry.registry_append_only]]log_with_attempted_rewrite()append(log, rewrite) == rejected
inconsistent_heads_detectedunit[[wild.registry.consistency_proofs]]two_heads_from_forked_logs()consistency_check == failed
unsigned_revision_rejectedunit[[wild.registry.signature_required]]submission_without_signature()sign == rejected
foreign_owner_rejectedunit[[wild.registry.namespace_ownership]]publish_to_lineage_with_different_key()sign == rejected
rotation_needs_outgoing_keyunit[[wild.registry.key_rotation_signed]]rotation_signed_with_new_key_only()rotation == rejected
alias_in_lock_rejectedunit[[wild.registry.lock_pins_hashes]]lockfile_entry_using_tag("latest")check(lock) == failed
digest_mismatch_rejectedunit[[wild.registry.sidecar_binds_artifact_digest]]sidecar_pointing_at_a_different_artifact()check(sidecar) == rejected
host_artifact_unchangedunit[[wild.registry.ecosystem_untouched]]publish_with_wild_enabled()host_artifact(before) == host_artifact(after)
yanked_revision_still_resolvesunit[[wild.registry.advisories_never_delete]]yanked_revision()resolve_by_hash == found ∧ advisory attached
stable_retraction_rejectedunit[[wild.registry.retraction_only_experimental]]retract_request_on_stable_lineage()retract == rejected
mirror_matches_originunit[[wild.registry.mirror_equivalence]]same_log_served_by_origin_and_mirror()verdicts(origin) == verdicts(mirror)
read_only_credentials_sufficeunit[[wild.registry.verification_needs_no_write]]resolve_and_verify_with_read_only_access()completes

Notes

Failure cases behind this spec: left-pad (an unpublished artifact broke builds), mutable tags (a repointed action tag), dependency confusion (public names shadowing internal ones), and signing-key rotation breaking installs. Registry ownership of names is a governance problem the tool can enforce but not solve (typosquatting remains out of scope).

Design acceptance cases

These cases define future runtime behavior. They are not claims that the current prototypes implement the v1 protocol. Executable document and prototype gates are under Requirements.

Rule: Registry append only

The system SHALL satisfy registry_append_only as defined in the Constraints table and the v1 format reference.

Acceptance case: Rewrite of appended rejected

  • GIVEN the fixture domain log_with_attempted_rewrite()
  • WHEN the registry_append_only check runs
  • THEN append(log, rewrite) == rejected

Rule: Consistency proofs

The system SHALL satisfy consistency_proofs as defined in the Constraints table and the v1 format reference.

Acceptance case: Inconsistent heads detected

  • GIVEN the fixture domain two_heads_from_forked_logs()
  • WHEN the consistency_proofs check runs
  • THEN consistency_check == failed

Rule: Signature required

The system SHALL satisfy signature_required as defined in the Constraints table and the v1 format reference.

Acceptance case: Unsigned revision rejected

  • GIVEN the fixture domain submission_without_signature()
  • WHEN the signature_required check runs
  • THEN sign == rejected

Rule: Namespace ownership

The system SHALL satisfy namespace_ownership as defined in the Constraints table and the v1 format reference.

Acceptance case: Foreign owner rejected

  • GIVEN the fixture domain publish_to_lineage_with_different_key()
  • WHEN the namespace_ownership check runs
  • THEN sign == rejected

Rule: Key rotation signed

The system SHALL satisfy key_rotation_signed as defined in the Constraints table and the v1 format reference.

Acceptance case: Rotation needs outgoing key

  • GIVEN the fixture domain rotation_signed_with_new_key_only()
  • WHEN the key_rotation_signed check runs
  • THEN rotation == rejected

Rule: Lock pins hashes

The system SHALL satisfy lock_pins_hashes as defined in the Constraints table and the v1 format reference.

Acceptance case: Alias in lock rejected

  • GIVEN the fixture domain lockfile_entry_using_tag("latest")
  • WHEN the lock_pins_hashes check runs
  • THEN check(lock) == failed

Rule: Sidecar binds artifact digest

The system SHALL satisfy sidecar_binds_artifact_digest as defined in the Constraints table and the v1 format reference.

Acceptance case: Digest mismatch rejected

  • GIVEN the fixture domain sidecar_pointing_at_a_different_artifact()
  • WHEN the sidecar_binds_artifact_digest check runs
  • THEN check(sidecar) == rejected

Rule: Ecosystem untouched

The system SHALL satisfy ecosystem_untouched as defined in the Constraints table and the v1 format reference.

Acceptance case: Host artifact unchanged

  • GIVEN the fixture domain publish_with_wild_enabled()
  • WHEN the ecosystem_untouched check runs
  • THEN host_artifact(before) == host_artifact(after)

Rule: Advisories never delete

The system SHALL satisfy advisories_never_delete as defined in the Constraints table and the v1 format reference.

Acceptance case: Yanked revision still resolves

  • GIVEN the fixture domain yanked_revision()
  • WHEN the advisories_never_delete check runs
  • THEN resolve_by_hash == found ∧ advisory attached

Rule: Retraction only experimental

The system SHALL satisfy retraction_only_experimental as defined in the Constraints table and the v1 format reference.

Acceptance case: Stable retraction rejected

  • GIVEN the fixture domain retract_request_on_stable_lineage()
  • WHEN the retraction_only_experimental check runs
  • THEN retract == rejected

Rule: Mirror equivalence

The system SHALL satisfy mirror_equivalence as defined in the Constraints table and the v1 format reference.

Acceptance case: Mirror matches origin

  • GIVEN the fixture domain same_log_served_by_origin_and_mirror()
  • WHEN the mirror_equivalence check runs
  • THEN verdicts(origin) == verdicts(mirror)

Rule: Verification needs no write

The system SHALL satisfy verification_needs_no_write as defined in the Constraints table and the v1 format reference.

Acceptance case: Read only credentials suffice

  • GIVEN the fixture domain resolve_and_verify_with_read_only_access()
  • WHEN the verification_needs_no_write check runs
  • THEN completes

Acceptance case: Private namespace cannot be shadowed

  • GIVEN a lock pins authority private.example and lineage acme.billing
  • WHEN a public registry publishes the same lineage spelling
  • THEN resolution retains the pinned authority and refuses public substitution

Acceptance case: Recovery follows the predesignated key

  • GIVEN the owner key is compromised and a recovery key was designated at bootstrap
  • WHEN a replacement key is submitted without outgoing-owner authorization
  • THEN it is accepted only through the authenticated recovery entry; forged recovery refuses

Acceptance case: Retraction preserves pinned bytes

  • GIVEN an experimental tip is retracted
  • WHEN a pinned hash is read and a new unconstrained lookup runs
  • THEN hash lookup returns bytes and notice; new lookup excludes the retracted tip and returns Unknown if no candidate exists

Requirements

Requirement: Wild registry design contract

The design corpus SHALL expose this capability’s constraints as normative, self-contained rules with acceptance cases, and SHALL link to a structurally valid shared v1 schema without claiming future runtime behavior is implemented.

Scenario: Wild registry design is self-contained

  • GIVEN this spec, docs/wild-formats-v1.md, and schemas/wild-v1.schema.json
  • WHEN the design contract gate checks normative rule coverage, local references, and the shared schema
  • THEN every constraint has a corresponding rule and acceptance case
  • AND both referenced files exist and the schema is valid JSON Schema draft 2020-12
  • AND this capability is discoverable by strict OpenSpec validation

wild-bridge


id: wild.bridge kind: intent statement: THE wild bridge SHALL connect incompatible lineages through checked adapters and SHALL describe uncontracted third-party software through labelled overlays, without raising its verdict above what was evidenced.

Wild bridge

Purpose

This is a normative design specification; only the prototype and corpus gate scenarios explicitly identified below are implemented. Shared wire formats and decision rules are defined in wild v1 formats and the v1 schema.

Where accretion ends, adapters begin. A break ships as a new lineage plus an explicitly directed adapter when one can be built; adapters are morphisms that compose, declare what they lose, and pass round-trip laws. Third-party software without contracts is handled by overlays, tests-as-laws, and legacy version claims recorded at the weakest tier.

Constraints

idkindexprtraces_to
break_requires_adapterinvarianta new lineage derived from an old one declares either registered directed adapters or unbridged status with a reason; publication of an unbridged lineage is allowed, but demanded cross-lineage boundaries without adapters refuse composition[[wild.bridge]]
adapter_is_morphisminvariantan adapter names source and target revision hashes and its artifact digest; A → B followed by B → C composes to A → C; identity and associativity hold for the declared mappings and observable equivalence[[wild.bridge]]
adapter_composition_coherentinvarianta composed adapter and any direct adapter must agree on the recorded law-suite domain modulo declared loss; a counterexample refuses coherence, and sample agreement is labelled sampled rather than universal equality[[wild.bridge]]
adapter_loss_declaredinvariantevery adapter declares lossless or lists the slots it loses[[wild.bridge]]
adapter_round_trip_lawinvarianta lossless adapter declares a reverse adapter and round-trip equality on its declared domain in both directions; validation labels proof, exhaustive, or sampled coverage and never promotes samples to universal losslessness[[wild.bridge]]
unknown_fields_preservedinvariantread-modify-write preserves unknown slots as opaque payloads except losses explicitly enumerated in a lossy adapter; a consumer requiring any declared lost slot refuses that adapter[[wild.bridge]]
adapter_draft_generatedinvariantadapt(old, new) emits a draft covering every derivable mapping and a TODO for each slot it cannot derive[[wild.bridge]]
adapter_validated_on_samplesinvarianta draft adapter is publishable only when all mappings are resolved, losses and law method are declared, and its required validation suite passes; unresolved mappings are not publishable[[wild.bridge]]
adapter_forms_closedinvariantadapter form ∈ {facade_library, wire_proxy, data_upcaster, component_wrapper}; adding a form requires a new wire schema version[[wild.bridge]]
opt_in_cross_lineageinvarianta consumer whose demand accretes in a newer lineage may adopt it without an adapter; adoption is opt-in per consumer[[wild.bridge]]
overlay_contractsinvarianta consumer may publish an overlay contract for an uncontracted upstream, bound to the upstream's artifact digest and labelled inferred[[wild.bridge]]
inferred_is_conservativeinvariantinferred contracts report the observed domain and do not claim a complete upstream schema; known unsupported constructs are opaque and absent observations remain Unknown; observations alone cannot establish PassDeclared structural assurance[[wild.bridge]]
legacy_semver_as_attestationinvarianta legacy version bump is an unverified metadata claim unless its publisher signs a scoped, expiring v1 attestation; it never establishes structural or law assurance[[wild.bridge]]
tests_are_default_lawsinvariantfor an uncontracted upstream, the dependent's passing integration tests are recorded as laws of the dependent[[wild.bridge]]
uncontracted_edges_unknowninvariantan uncontracted edge has Unknown structural assurance; a digest-bound explicit overlay may establish declared assurance for covered slots, while tests add only method-labelled law evidence for their exercised domain[[wild.bridge]]
standards_are_lineagesinvariantrevisions of protocols and schemas published by standards bodies are lineages and are checked by the same accretion relation[[wild.bridge]]

Model

States

  • break_found
  • adapter_drafted
  • adapter_validated
  • adapter_published
  • consumer_migrated

Transitions

idfromtoguard
draft_adapterbreak_foundadapter_drafted[[wild.bridge.adapter_draft_generated]]
validateadapter_draftedadapter_validated[[wild.bridge.adapter_validated_on_samples]] ∧ [[wild.bridge.adapter_round_trip_law]]
publish_adapteradapter_validatedadapter_published[[wild.bridge.adapter_loss_declared]] ∧ [[wild.bridge.adapter_forms_closed]]
migrateadapter_publishedconsumer_migrated[[wild.bridge.opt_in_cross_lineage]]

Properties

idkindderives_fromgeneratorpredicate
break_without_adapter_disclosedunit[[wild.bridge.break_requires_adapter]]new_lineage_without_registered_adapter()publish records unbridged ∧ cross_lineage_binding == refused
adapter_category_lawslaw[[wild.bridge.adapter_is_morphism]]arbitrary_adapter_chain(length: 3)identity: compose(id, a) == a associativity: compose(compose(a, b), c) == compose(a, compose(b, c))
composed_matches_directunit[[wild.bridge.adapter_composition_coherent]]adapters_a_b_and_direct_ab_disagreeing()check == failed ∧ mismatch reported
lossy_adapter_must_list_lossunit[[wild.bridge.adapter_loss_declared]]adapter_with_dropped_slot_declared_lossless()check == failed
lossless_needs_round_tripunit[[wild.bridge.adapter_round_trip_law]]lossless_adapter_failing_round_trip()validate == failed
round_trip_keeps_unknown_slotsunit[[wild.bridge.unknown_fields_preserved]]record_with_slots_outside_demand()unknown_slots(after) == unknown_slots(before) minus explicitly accepted declared losses
draft_marks_underivable_slotsunit[[wild.bridge.adapter_draft_generated]]contract_pair_with_one_unmappable_slot()draft has exactly one TODO
unvalidated_adapter_unpublishableunit[[wild.bridge.adapter_validated_on_samples]]draft_adapter_failing_laws()publish_adapter == rejected
unknown_adapter_form_rejectedunit[[wild.bridge.adapter_forms_closed]]adapter_declaring_form("magic")check == failed
unaffected_consumer_adopts_unaidedunit[[wild.bridge.opt_in_cross_lineage]]break_in_slot_a_consumer_never_uses()consumer_can_adopt == true ∧ adoption requires consent
overlay_is_labelled_inferredunit[[wild.bridge.overlay_contracts]]overlay_for_uncontracted_upstream()overlay.label == inferred ∧ overlay.digest == upstream.digest
unobserved_slots_are_opaqueunit[[wild.bridge.inferred_is_conservative]]traffic_covering_half_of_the_api()coverage names observed domain ∧ unobserved domain == Unknown
semver_never_above_attestationunit[[wild.bridge.legacy_semver_as_attestation]]dependency_without_contract_declaring_patch()claim.source == legacy_version ∧ structural_assurance == Unknown
tests_become_lawsunit[[wild.bridge.tests_are_default_laws]]dependent_with_passing_integration_test_on_uncontracted_upstream()dependent.laws includes the test
uncovered_edge_is_unknownunit[[wild.bridge.uncontracted_edges_unknown]]edge_to_uncontracted_provider_without_overlay_or_law()edge.assurance == Unknown
spec_revision_checked_like_packageunit[[wild.bridge.standards_are_lineages]]protocol_revision_that_removes_a_feature_added_in_the_prior_revision()accretes == false

Notes

Evidence behind this spec: simulation round 1 showed that a dependent with an integration law catches a mislabelled change in an uncontracted upstream, and one without such a law does not (hence tests_are_default_laws); consumers who never used a removed slot could adopt the new lineage unaided (hence opt_in_cross_lineage). Catalog cases: PodSecurityPolicy replacement and ISO 20022 translation (lossy adapters), unknown-field dropping on read-modify-write, and a protocol spec that removed a feature added one revision earlier.

Known limits: overlays and inferred contracts are only as good as their evidence; adapters between genuinely incompatible models (AngularJS to Angular) may be infeasible, in which case the break stays unbridged and is reported.

Design acceptance cases

These cases define future runtime behavior. They are not claims that the current prototypes implement the v1 protocol. Executable document and prototype gates are under Requirements.

Rule: Break requires adapter

The system SHALL satisfy break_requires_adapter as defined in the Constraints table and the v1 format reference.

Acceptance case: Break without adapter disclosed

  • GIVEN the fixture domain new_lineage_without_registered_adapter()
  • WHEN the break_requires_adapter check runs
  • THEN publish records unbridged ∧ cross_lineage_binding == refused

Rule: Adapter is morphism

The system SHALL satisfy adapter_is_morphism as defined in the Constraints table and the v1 format reference.

Acceptance case: Adapter category laws

  • GIVEN the fixture domain arbitrary_adapter_chain(length: 3)
  • WHEN the adapter_is_morphism check runs
  • THEN identity: compose(id, a) == a associativity: compose(compose(a, b), c) == compose(a, compose(b, c))

Rule: Adapter composition coherent

The system SHALL satisfy adapter_composition_coherent as defined in the Constraints table and the v1 format reference.

Acceptance case: Composed matches direct

  • GIVEN the fixture domain adapters_a_b_and_direct_ab_disagreeing()
  • WHEN the adapter_composition_coherent check runs
  • THEN check == failed ∧ mismatch reported

Rule: Adapter loss declared

The system SHALL satisfy adapter_loss_declared as defined in the Constraints table and the v1 format reference.

Acceptance case: Lossy adapter must list loss

  • GIVEN the fixture domain adapter_with_dropped_slot_declared_lossless()
  • WHEN the adapter_loss_declared check runs
  • THEN check == failed

Rule: Adapter round trip law

The system SHALL satisfy adapter_round_trip_law as defined in the Constraints table and the v1 format reference.

Acceptance case: Lossless needs round trip

  • GIVEN the fixture domain lossless_adapter_failing_round_trip()
  • WHEN the adapter_round_trip_law check runs
  • THEN validate == failed

Rule: Unknown fields preserved

The system SHALL satisfy unknown_fields_preserved as defined in the Constraints table and the v1 format reference.

Acceptance case: Round trip keeps unknown slots

  • GIVEN the fixture domain record_with_slots_outside_demand()
  • WHEN the unknown_fields_preserved check runs
  • THEN unknown_slots(after) == unknown_slots(before) minus explicitly accepted declared losses

Rule: Adapter draft generated

The system SHALL satisfy adapter_draft_generated as defined in the Constraints table and the v1 format reference.

Acceptance case: Draft marks underivable slots

  • GIVEN the fixture domain contract_pair_with_one_unmappable_slot()
  • WHEN the adapter_draft_generated check runs
  • THEN draft has exactly one TODO

Rule: Adapter validated on samples

The system SHALL satisfy adapter_validated_on_samples as defined in the Constraints table and the v1 format reference.

Acceptance case: Unvalidated adapter unpublishable

  • GIVEN the fixture domain draft_adapter_failing_laws()
  • WHEN the adapter_validated_on_samples check runs
  • THEN publish_adapter == rejected

Rule: Adapter forms closed

The system SHALL satisfy adapter_forms_closed as defined in the Constraints table and the v1 format reference.

Acceptance case: Unknown adapter form rejected

  • GIVEN the fixture domain adapter_declaring_form("magic")
  • WHEN the adapter_forms_closed check runs
  • THEN check == failed

Rule: Opt in cross lineage

The system SHALL satisfy opt_in_cross_lineage as defined in the Constraints table and the v1 format reference.

Acceptance case: Unaffected consumer adopts unaided

  • GIVEN the fixture domain break_in_slot_a_consumer_never_uses()
  • WHEN the opt_in_cross_lineage check runs
  • THEN consumer_can_adopt == true ∧ adoption requires consent

Rule: Overlay contracts

The system SHALL satisfy overlay_contracts as defined in the Constraints table and the v1 format reference.

Acceptance case: Overlay is labelled inferred

  • GIVEN the fixture domain overlay_for_uncontracted_upstream()
  • WHEN the overlay_contracts check runs
  • THEN overlay.label == inferred ∧ overlay.digest == upstream.digest

Rule: Inferred is conservative

The system SHALL satisfy inferred_is_conservative as defined in the Constraints table and the v1 format reference.

Acceptance case: Unobserved slots are opaque

  • GIVEN the fixture domain traffic_covering_half_of_the_api()
  • WHEN the inferred_is_conservative check runs
  • THEN coverage names observed domain ∧ unobserved domain == Unknown

Rule: Legacy semver as attestation

The system SHALL satisfy legacy_semver_as_attestation as defined in the Constraints table and the v1 format reference.

Acceptance case: Semver never above attestation

  • GIVEN the fixture domain dependency_without_contract_declaring_patch()
  • WHEN the legacy_semver_as_attestation check runs
  • THEN claim.source == legacy_version ∧ structural_assurance == Unknown

Rule: Tests are default laws

The system SHALL satisfy tests_are_default_laws as defined in the Constraints table and the v1 format reference.

Acceptance case: Tests become laws

  • GIVEN the fixture domain dependent_with_passing_integration_test_on_uncontracted_upstream()
  • WHEN the tests_are_default_laws check runs
  • THEN dependent.laws includes the test

Rule: Uncontracted edges unknown

The system SHALL satisfy uncontracted_edges_unknown as defined in the Constraints table and the v1 format reference.

Acceptance case: Uncovered edge is unknown

  • GIVEN the fixture domain edge_to_uncontracted_provider_without_overlay_or_law()
  • WHEN the uncontracted_edges_unknown check runs
  • THEN edge.assurance == Unknown

Rule: Standards are lineages

The system SHALL satisfy standards_are_lineages as defined in the Constraints table and the v1 format reference.

Acceptance case: Spec revision checked like package

  • GIVEN the fixture domain protocol_revision_that_removes_a_feature_added_in_the_prior_revision()
  • WHEN the standards_are_lineages check runs
  • THEN accretes == false

Acceptance case: Infeasible adapter leaves a disclosed boundary

  • GIVEN a new lineage cannot be adapted to its predecessor
  • WHEN it is published with unbridged status and reason
  • THEN publication succeeds but composition across the unbridged demanded boundary refuses

Acceptance case: Lossless requires both directions

  • GIVEN an A to B adapter has no reverse mapping
  • WHEN it claims lossless round-trip validation
  • THEN validation refuses the incomplete claim

Acceptance case: Declared loss affects consumer selection

  • GIVEN an adapter loses slot x and preserves unknown slot y
  • WHEN a consumer demands x
  • THEN composition refuses that adapter; consumers accepting declared loss retain y through read-modify-write

Requirements

Requirement: Wild bridge design contract

The design corpus SHALL expose this capability’s constraints as normative, self-contained rules with acceptance cases, and SHALL link to a structurally valid shared v1 schema without claiming future runtime behavior is implemented.

Scenario: Wild bridge design is self-contained

  • GIVEN this spec, docs/wild-formats-v1.md, and schemas/wild-v1.schema.json
  • WHEN the design contract gate checks normative rule coverage, local references, and the shared schema
  • THEN every constraint has a corresponding rule and acceptance case
  • AND both referenced files exist and the schema is valid JSON Schema draft 2020-12
  • AND this capability is discoverable by strict OpenSpec validation

wild-adopt


id: wild.adopt kind: intent statement: THE wild adoption layer SHALL let an existing project adopt contract versioning in stages, without changing its package manager, registry, or release process.

Wild adoption

Purpose

This is a normative design specification; only the prototype and corpus gate scenarios explicitly identified below are implemented. Shared wire formats and decision rules are defined in wild v1 formats and the v1 schema.

How existing, uncontracted software joins. The ladder is observe, shadow, gate, native. Each level adds enforcement; none requires rewriting the host ecosystem. Legacy version strings are kept as weak evidence. First enforcement runs in baseline mode, because stricter checking surfaces latent breaks that older tools hid.

Constraints

idkindexprtraces_to
history_reconstructedinvariantadopt(project) extracts each available historical release; missing source or extraction failure is preserved as an Unknown history node and cannot establish an accretion edge; version strings never establish edges[[wild.adopt]]
past_claims_auditedinvarianteach historical release reports declared version bump against computed verdict; disagreements are listed[[wild.adopt]]
adoption_levels_orderedinvariantlevels are ordered observe < shadow < gate < native; a project enters level n+1 only from level n[[wild.adopt]]
observe_is_read_onlyinvariantlevel observe writes nothing to source, manifest, registry, or CI configuration[[wild.adopt]]
shadow_never_blocksinvariantlevel shadow emits verdicts but never changes a build exit status[[wild.adopt]]
gate_scoped_to_new_changesinvariantlevel gate rejects newly introduced breaks and expired baseline acknowledgements; baseline ids are immutable and cannot be reset implicitly by init, retries, or stepping down and up[[wild.adopt]]
baseline_ack_expiresinvarianteach baseline break has an owner, issue time, expiry, and stable finding id; default expiry is 30 days; renewal requires a signed reason and new expiry and appends an audit event rather than replacing history[[wild.adopt]]
first_run_is_baselineinvariantfirst enforcement atomically records a baseline digest, existing findings, and 30-day acknowledgements owned by the initiating identity; it tolerates existing breaks only after baseline persistence succeeds; persistence failure refuses enforcement activation[[wild.adopt]]
lock_import_losslessinvariantimporting a host lockfile yields one lineage and hash per resolved dependency; unresolvable entries become Unknown, never dropped[[wild.adopt]]
demand_derived_from_codeinvariantdemand includes statically resolved usage and declared dynamic usage; unresolved reflection, plugins, or dynamic calls mark demand incomplete and block safe-removal and scoped-substitution claims; manual reductions require signed scoped expiring overrides and remain disclosed[[wild.adopt]]
safe_update_adviceinvariantfor a host version range, wild reports per candidate version whether demanded slots stay compatible; it never overrides the host resolver's choice; advice/check/observe never modify the manifest or host selection, and only explicit authorized update evaluation may apply a proposed manifest in an isolated workspace, with the host resolver selecting under that manifest[[wild.adopt]]
consumer_demand_trackableinvariantper slot, wild reports known consumers; removal_candidate(slot) is derived only when known demand is empty and all known demand manifests are complete and fresh; it is advisory and never authorizes removal within a stable lineage[[wild.adopt]]
integration_points_share_coreinvariantCLI, CI action, pre-commit hook, and ecosystem plugins call one core and emit the same envelope[[wild.adopt]]
init_needs_no_editsinvariantinit in a supported ecosystem produces extractor configuration, a baseline, and a CI hook without user edits[[wild.adopt]]
unsupported_ecosystem_degradesinvariantunsupported extraction yields Unknown assurance with scoped observations or metadata claims when available; observe and shadow succeed with diagnostics, while gate/native refuse any unmet required policy[[wild.adopt]]
adoption_progress_reportedadvisorystatus reports level, share of dependencies per tier, and open acknowledgements[[wild.adopt]]

Model

States

  • unmanaged
  • observed
  • shadowed
  • gated
  • native

Transitions

idfromtoguard
observeunmanagedobserved[[wild.adopt.observe_is_read_only]] ∧ [[wild.adopt.history_reconstructed]]
shadowobservedshadowed[[wild.adopt.shadow_never_blocks]]
gateshadowedgated[[wild.adopt.gate_scoped_to_new_changes]] ∧ [[wild.adopt.first_run_is_baseline]]
go_nativegatednative[[wild.adopt.init_needs_no_edits]] ∧ preserves wild-registry ecosystem_untouched and sidecar_binds_artifact_digest
step_downgatedshadowed[[wild.adopt.adoption_levels_ordered]]

Properties

idkindderives_fromgeneratorpredicate
history_graph_from_contractsunit[[wild.adopt.history_reconstructed]]git_history_with_mislabeled_semver()lineage_graph == computed_accretion_graph
semver_disagreement_listedunit[[wild.adopt.past_claims_audited]]release_tagged_patch_that_removes_a_slot()audit lists the release
level_skip_rejectedunit[[wild.adopt.adoption_levels_ordered]]project_at_observe_requesting_gate()transition == rejected
observe_writes_nothingunit[[wild.adopt.observe_is_read_only]]repo_snapshot_before_and_after_observe()snapshot(before) == snapshot(after)
shadow_exit_status_unchangedunit[[wild.adopt.shadow_never_blocks]]build_with_a_computed_break_in_shadow()exit_status == host_exit_status
baseline_break_tolerated_new_rejectedunit[[wild.adopt.gate_scoped_to_new_changes]]repo_with_old_break_then_new_break()old == tolerated ∧ new == rejected
expired_ack_rejectsunit[[wild.adopt.baseline_ack_expires]]acknowledged_break_past_expiry()check(ack) == rejected
first_run_rejects_nothing_oldunit[[wild.adopt.first_run_is_baseline]]repo_with_many_latent_breaks_first_run()rejections == 0 ∧ baseline lists all
lock_entries_all_accountedunit[[wild.adopt.lock_import_lossless]]lockfile_with_unresolvable_entry()count(imported) == count(lock) ∧ entry.verdict == Unknown
demand_matches_usageunit[[wild.adopt.demand_derived_from_code]]consumer_using_slots([a, b])demand == {a, b}
advice_leaves_resolver_aloneunit[[wild.adopt.safe_update_advice]]range_with_one_incompatible_candidate()advice flags candidate ∧ host_choice unchanged
zero_demand_slot_removableunit[[wild.adopt.consumer_demand_trackable]]slot_with_no_known_consumers()removal_candidate(slot) == true ∧ advisory_only ∧ no stored flag
same_envelope_everywhereunit[[wild.adopt.integration_points_share_core]]same_change_via_cli_action_and_hook()envelope(cli) == envelope(action) == envelope(hook)
init_works_uneditedunit[[wild.adopt.init_needs_no_edits]]fresh_repo_in_supported_ecosystem()init leaves a runnable baseline and CI hook
unsupported_degrades_not_errorsunit[[wild.adopt.unsupported_ecosystem_degrades]]project_in_unsupported_language()result.assurance == Unknown ∧ observe_exit_status == ok
status_lists_tier_sharesunit[[wild.adopt.adoption_progress_reported]]project_with_mixed_dependencies()status lists level ∧ per-tier shares ∧ open acknowledgements

Notes

Lesson from the catalog: pip’s stricter resolver in 2020 exposed conflicts older installers hid, so first enforcement must not reject legacy breaks (first_run_is_baseline). Baseline acknowledgements expire so old breaks cannot be silenced forever.

Known limits: a removable slot means no known consumer demands it, not that none exists (see open_world_disclosed in wild). Extractor noise on first runs is the main adoption risk and is reported in wild.extract.

Design acceptance cases

These cases define future runtime behavior. They are not claims that the current prototypes implement the v1 protocol. Executable document and prototype gates are under Requirements.

Rule: History reconstructed

The system SHALL satisfy history_reconstructed as defined in the Constraints table and the v1 format reference.

Acceptance case: History graph from contracts

  • GIVEN the fixture domain git_history_with_mislabeled_semver()
  • WHEN the history_reconstructed check runs
  • THEN lineage_graph == computed_accretion_graph

Rule: Past claims audited

The system SHALL satisfy past_claims_audited as defined in the Constraints table and the v1 format reference.

Acceptance case: Semver disagreement listed

  • GIVEN the fixture domain release_tagged_patch_that_removes_a_slot()
  • WHEN the past_claims_audited check runs
  • THEN audit lists the release

Rule: Adoption levels ordered

The system SHALL satisfy adoption_levels_ordered as defined in the Constraints table and the v1 format reference.

Acceptance case: Level skip rejected

  • GIVEN the fixture domain project_at_observe_requesting_gate()
  • WHEN the adoption_levels_ordered check runs
  • THEN transition == rejected

Rule: Observe is read only

The system SHALL satisfy observe_is_read_only as defined in the Constraints table and the v1 format reference.

Acceptance case: Observe writes nothing

  • GIVEN the fixture domain repo_snapshot_before_and_after_observe()
  • WHEN the observe_is_read_only check runs
  • THEN snapshot(before) == snapshot(after)

Rule: Shadow never blocks

The system SHALL satisfy shadow_never_blocks as defined in the Constraints table and the v1 format reference.

Acceptance case: Shadow exit status unchanged

  • GIVEN the fixture domain build_with_a_computed_break_in_shadow()
  • WHEN the shadow_never_blocks check runs
  • THEN exit_status == host_exit_status

Rule: Gate scoped to new changes

The system SHALL satisfy gate_scoped_to_new_changes as defined in the Constraints table and the v1 format reference.

Acceptance case: Baseline break tolerated new rejected

  • GIVEN the fixture domain repo_with_old_break_then_new_break()
  • WHEN the gate_scoped_to_new_changes check runs
  • THEN old == tolerated ∧ new == rejected

Rule: Baseline ack expires

The system SHALL satisfy baseline_ack_expires as defined in the Constraints table and the v1 format reference.

Acceptance case: Expired ack rejects

  • GIVEN the fixture domain acknowledged_break_past_expiry()
  • WHEN the baseline_ack_expires check runs
  • THEN check(ack) == rejected

Rule: First run is baseline

The system SHALL satisfy first_run_is_baseline as defined in the Constraints table and the v1 format reference.

Acceptance case: First run rejects nothing old

  • GIVEN the fixture domain repo_with_many_latent_breaks_first_run()
  • WHEN the first_run_is_baseline check runs
  • THEN rejections == 0 ∧ baseline lists all

Rule: Lock import lossless

The system SHALL satisfy lock_import_lossless as defined in the Constraints table and the v1 format reference.

Acceptance case: Lock entries all accounted

  • GIVEN the fixture domain lockfile_with_unresolvable_entry()
  • WHEN the lock_import_lossless check runs
  • THEN count(imported) == count(lock) ∧ entry.verdict == Unknown

Rule: Demand derived from code

The system SHALL satisfy demand_derived_from_code as defined in the Constraints table and the v1 format reference.

Acceptance case: Demand matches usage

  • GIVEN the fixture domain consumer_using_slots([a, b])
  • WHEN the demand_derived_from_code check runs
  • THEN demand == {a, b}

Rule: Safe update advice

The system SHALL satisfy safe_update_advice as defined in the Constraints table and the v1 format reference.

Scope reconciliation: advice/check/observe never modify the manifest or host selection. Only explicit update evaluation may apply an authorized proposed manifest in isolation; Cargo selects under that manifest.

Acceptance case: Advice leaves resolver alone

  • GIVEN the fixture domain range_with_one_incompatible_candidate()
  • WHEN the safe_update_advice check runs
  • THEN advice flags candidate ∧ host_choice unchanged

Rule: Consumer demand trackable

The system SHALL satisfy consumer_demand_trackable as defined in the Constraints table and the v1 format reference.

Acceptance case: Zero demand slot removable

  • GIVEN the fixture domain slot_with_no_known_consumers()
  • WHEN the consumer_demand_trackable check runs
  • THEN removal_candidate(slot) == true ∧ advisory_only ∧ no stored flag

Rule: Integration points share core

The system SHALL satisfy integration_points_share_core as defined in the Constraints table and the v1 format reference.

Acceptance case: Same envelope everywhere

  • GIVEN the fixture domain same_change_via_cli_action_and_hook()
  • WHEN the integration_points_share_core check runs
  • THEN envelope(cli) == envelope(action) == envelope(hook)

Rule: Init needs no edits

The system SHALL satisfy init_needs_no_edits as defined in the Constraints table and the v1 format reference.

Acceptance case: Init works unedited

  • GIVEN the fixture domain fresh_repo_in_supported_ecosystem()
  • WHEN the init_needs_no_edits check runs
  • THEN init leaves a runnable baseline and CI hook

Rule: Unsupported ecosystem degrades

The system SHALL satisfy unsupported_ecosystem_degrades as defined in the Constraints table and the v1 format reference.

Acceptance case: Unsupported degrades not errors

  • GIVEN the fixture domain project_in_unsupported_language()
  • WHEN the unsupported_ecosystem_degrades check runs
  • THEN result.assurance == Unknown ∧ observe_exit_status == ok

Rule: Adoption progress reported

The system SHALL satisfy adoption_progress_reported as defined in the Constraints table and the v1 format reference.

Acceptance case: Status lists tier shares

  • GIVEN the fixture domain project_with_mixed_dependencies()
  • WHEN the adoption_progress_reported check runs
  • THEN status lists level ∧ per-tier shares ∧ open acknowledgements

Acceptance case: Reinitialization cannot erase baseline findings

  • GIVEN a project has an immutable baseline with an expired acknowledgement
  • WHEN init is rerun or enforcement is stepped down and up
  • THEN the baseline id remains unchanged and the expired finding still refuses enforcement

Acceptance case: Dynamic calls prevent safe removal advice

  • GIVEN reflection leaves a known consumer demand manifest incomplete
  • WHEN a slot has no statically identified consumers
  • THEN removal_candidate is not asserted and scoped substitution is refused

Acceptance case: Unavailable history remains visible

  • GIVEN historical release source is missing
  • WHEN adoption reconstructs history
  • THEN the release remains an Unknown node and no accretion edge is inferred across it

Acceptance case: Unsupported ecosystem respects enforcement policy

  • GIVEN extraction is unsupported and policy requires PassDeclared
  • WHEN observe and gate modes evaluate the same project
  • THEN observe returns diagnostics with exit 0; gate refuses with exit 1

Requirements

Requirement: Wild adopt design contract

The design corpus SHALL expose this capability’s constraints as normative, self-contained rules with acceptance cases, and SHALL link to a structurally valid shared v1 schema without claiming future runtime behavior is implemented.

Scenario: Wild adopt design is self-contained

  • GIVEN this spec, docs/wild-formats-v1.md, and schemas/wild-v1.schema.json
  • WHEN the design contract gate checks normative rule coverage, local references, and the shared schema
  • THEN every constraint has a corresponding rule and acceptance case
  • AND both referenced files exist and the schema is valid JSON Schema draft 2020-12
  • AND this capability is discoverable by strict OpenSpec validation

Requirement: Standalone local compatibility check

Wild SHALL check supplied base/candidate bundles for a named consumer scope without requiring registry publication, upstream contract adoption, historical reconstruction, or activation of adoption gate/native modes. It SHALL use v1 envelopes and the local-1 report contract, write only explicitly requested report artifacts, and preserve host manifests, lockfiles, source, and CI configuration.

Scenario: First result in an existing repository

  • GIVEN supported local bundles and an explicit check request with no Wild registry or adoption history
  • WHEN wild check evaluates the requested boundary
  • THEN it reports structural assurance, law methods, scope, coverage, and stable diagnostics
  • AND project files and adoption level remain unchanged

Scenario: A result separates policy from execution

  • GIVEN a required analysis gap, a known structural break, and a malformed request in three separate runs
  • WHEN checks finish
  • THEN the local outcomes are respectively unknown, reject, and error with exits 1, 1, and 2
  • AND all refuse policy acceptance without calling missing evidence a structural counterexample

Requirement: Separate authored obligations from extracted facts

Wild SHALL accept human- or agent-authored obligation drafts using the same local-1 format and authority rules, store them separately from mined facts, and preserve accepted obligations when re-extracting candidate code. Authorship SHALL NOT raise assurance. Prose without an executable or structural predicate SHALL remain unverified, and contradictions with extracted facts SHALL remain visible.

Scenario: Regeneration cannot erase intent

  • GIVEN an accepted law and a candidate that regenerates its contracts without that law
  • WHEN the candidate is checked
  • THEN the original law is still evaluated and the proposed deletion is reported separately

Scenario: Human and agent predicates receive equal checking

  • GIVEN otherwise identical executable obligations with human and agent origin labels
  • WHEN the same checker evaluates them on identical committed inputs
  • THEN their assurance and law results match while provenance retains the different origins

Requirement: Explicit authorized update planning

Wild SHALL provide a separate local update mode that records an exact target, original range, proposed manifest edit, base/configuration commitments, and allowed actions. Advice/check/observe SHALL retain their read-only host-selection behavior. Evaluation SHALL require external project authority bound to the plan before applying any edit in isolation; missing authority SHALL NOT be inferred from compatibility evidence.

Scenario: Plan without changing the application

  • GIVEN a candidate excluded by the original Cargo range
  • WHEN wild update plan runs
  • THEN it writes only the requested proposal and identifies the exact range change and pending checks
  • AND the original manifest, lockfile, source, and host selection are unchanged

Scenario: Candidate self-authorization fails

  • GIVEN a candidate supplies an authority file not committed by the trusted invocation
  • WHEN update evaluation starts
  • THEN it refuses before applying the planned edit

Requirement: Real host resolution and update delivery

Wild SHALL evaluate the authorized plan in isolation using actual Cargo resolution, inspect the selected target and complete dependency closure, build/test with a fixed lock, and evaluate protected obligations on those artifacts. It SHALL deliver a pinned diff only after every required check succeeds and output persistence completes. Missing required evidence SHALL remain unknown; runtime/platform/provenance/license/organization constraints SHALL NOT be silently relaxed with the version range.

Scenario: Compatible release outside the old range

  • GIVEN a frozen registry target excluded by the original manifest that removes only an unused function in a completely supported scope
  • WHEN an authorized manifest change resolves that exact target and all required closure, build, test, and contract checks pass
  • THEN the output contains a delivered pinned direct-update diff and evidence for the actual artifacts
  • AND the original worktree remains unchanged

Scenario: Permitted patch breaks a consumer

  • GIVEN a patch release allowed by the old range removes a demanded function
  • WHEN the actual selected target is evaluated
  • THEN the update is refused with the violated demand and no delivered-update claim

Scenario: Cargo selects a different artifact

  • GIVEN a plan for a specific source and release
  • WHEN actual resolution selects a different source or release
  • THEN evaluation refuses and records both requested and actual identities

Scenario: Environment constraint survives range relaxation

  • GIVEN an otherwise compatible target requires an unsupported Rust version or violates a required provenance policy
  • WHEN the manifest-range change is evaluated
  • THEN the relevant constraint refuses delivery independently of compatibility

Scenario: Failed persistence or stale base cannot deliver

  • GIVEN checks pass but the output cannot be durably written or an input commitment no longer matches
  • WHEN delivery is finalized
  • THEN the result is error or refusal with the cause and does not claim a delivered update

Requirement: Direct updates and migrations remain distinct

Wild SHALL classify manifest/lock-only changes as direct updates and supplied consumer/adapter changes as migrations. Both SHALL satisfy protected intended outcomes. Authorized obligation changes SHALL be recorded as intentional transitions and SHALL NOT count as backward-compatible direct updates. The first implementation SHALL accept supplied migration patches without requiring automatic migration generation.

Scenario: Consumer repair is a migration

  • GIVEN an update passes only after a supplied consumer-code patch
  • WHEN the original intended outcomes and new closure pass validation
  • THEN the result includes that patch and reports migration rather than direct compatibility

Scenario: Removed assertion is not preserved behavior

  • GIVEN a migration deletes a protected consumer test or obligation
  • WHEN evaluation runs without a separately authorized intent transition
  • THEN the original obligation remains required and the deletion cannot make delivery pass

wild-deploy


id: wild.deploy kind: intent statement: THE wild deployer SHALL decide, from declared floors and observed live revisions, when each service may deploy, so that continuous deployment needs no manual ordering or lockstep release.

Wild deploy

Purpose

This is a normative design specification; only the prototype and corpus gate scenarios explicitly identified below are implemented. Shared wire formats and decision rules are defined in wild v1 formats and the v1 schema.

Rollout rules on top of published revisions. Accretion makes old consumers safe against new providers, but a consumer that starts using a new slot needs its provider live first. This spec turns that into a computed gate, plus safe rollback and lineage retirement.

Constraints

idkindexprtraces_to
deploy_requires_published_revisioninvarianta revision is deployable only if it is published in the registry and passed tiers identity, shape, and laws[[wild.deploy]]
floor_declaredinvariantfor each demanded provider on a totally ordered accepted ancestry, floor is the least revision covering demand; incomparable covering minima require an explicit pinned covering revision and cannot be represented by a guessed scalar floor[[wild.deploy]]
provider_live_before_consumerinvarianta consumer may deploy only when every provider revision reachable by its traffic satisfies its floor, all required policy passes, and a coordination lease protects the live snapshot; one new canary instance does not satisfy the floor for traffic reaching old instances[[wild.deploy]]
gate_order_derivedinvarianta deploy plan orders services by a topological order of floor edges; manual ordering is not accepted[[wild.deploy]]
floor_cycle_rejectedinvariantonly unsatisfied floor prerequisites create ordering edges; existing dependency cycles whose floors are already satisfied are allowed; an unsatisfied prerequisite cycle is refused with members listed and simultaneous deployment is not offered[[wild.deploy]]
gate_decision_pureinvariantthe gate is a pure function of floors, routing, live snapshot, policy, coordination generation, and explicit evaluation time; it performs no clock or network reads[[wild.deploy]]
live_state_freshinvariantreports include observed_at, ttl_seconds, generation, and every traffic-reachable revision; at evaluation_time ≥ observed_at + ttl_seconds or on missing/future-dated reports state is Unknown and blocks; default ttl is 60 seconds[[wild.deploy]]
rolling_overlap_safeinvariantduring a roll, old and new revisions serve concurrently only when the new revision accretes the old one; a non-accretion is never rolled in place[[wild.deploy]]
lineages_served_concurrentlyinvarianta break ships as a new lineage while the old lineage keeps serving until retirement[[wild.deploy]]
retire_on_zero_demandinvariantretirement requires empty known demand, fresh complete consumer reports, zero routed traffic, and a policy grace period (default seven days) continuously satisfied; missing reports or renewed demand restart the grace period; registry bytes remain[[wild.deploy]]
canary_traffic_boundedinvariantcanary traffic share never exceeds the policy maximum[[wild.deploy]]
evidence_required_to_promoteinvariantpromotion requires every binding to satisfy the v1 policy, fresh complete live state, and a valid coordination lease; structural Reject or relevant law counterexample is never promoted[[wild.deploy]]
rollback_respects_floorsinvariantprovider rollback checks floors of all live and in-flight consumers plus irreversible writes under the same coordination lease; generation change or lease loss aborts and requires revalidation; otherwise violating consumers roll back first[[wild.deploy]]
irreversible_edges_declaredinvariantirreversible writers persist a monotone first-write barrier before acknowledging such writes; after the barrier rollback past it is refused, including canary and rolling aborts; unknown barrier status fails closed[[wild.deploy]]
emergency_override_recordedinvariantan authorized override names exact overridable policy findings, signer, reason, and expiry in a log entry; structural Reject, Unknown reachability, lease loss, and irreversible-write barriers are never overridable[[wild.deploy]]
deploy_envelopeinvariantevery deploy command emits an envelope with stage, revision hashes, and gate verdict[[wild.deploy]]
stage_durations_reportedadvisoryeach deployment reports time spent per stage from commit to live[[wild.deploy]]
deploy_impact_estimatedadvisorybefore the gate runs, the plan lists the known consumers each deployment affects[[wild.deploy]]

Model

States

  • committed
  • checked
  • gated
  • canary
  • rolling
  • live
  • rolled_back
  • contracted

Transitions

idfromtoguard
checkcommittedchecked[[wild.deploy.deploy_requires_published_revision]] ∧ requires wild-registry registry_append_only
gatecheckedgated[[wild.deploy.provider_live_before_consumer]] ∧ [[wild.deploy.gate_decision_pure]]
start_canarygatedcanary[[wild.deploy.canary_traffic_bounded]]
promotecanaryrolling[[wild.deploy.evidence_required_to_promote]]
finish_rollrollinglive[[wild.deploy.rolling_overlap_safe]]
abort_canarycanaryrolled_back[[wild.deploy.rollback_respects_floors]] ∧ [[wild.deploy.irreversible_edges_declared]]
abort_rollrollingrolled_back[[wild.deploy.rollback_respects_floors]] ∧ [[wild.deploy.irreversible_edges_declared]]
rollback_liveliverolled_back[[wild.deploy.rollback_respects_floors]] ∧ [[wild.deploy.irreversible_edges_declared]]
retryrolled_backcommitted[[wild.deploy.deploy_requires_published_revision]]
contractlivecontracted[[wild.deploy.retire_on_zero_demand]] ∧ [[wild.deploy.live_state_fresh]]

Properties

idkindderives_fromgeneratorpredicate
unpublished_revision_not_deployedunit[[wild.deploy.deploy_requires_published_revision]]revision_absent_from_registry()deploy == rejected
floor_is_least_covering_revisionunit[[wild.deploy.floor_declared]]lineage_chain_with_demand()floor == min(r in chain where demand ⊆ provides(r))
consumer_waits_for_providerunit[[wild.deploy.provider_live_before_consumer]]consumer_floor_above_live_provider()gate == blocked
plan_order_is_topologicalunit[[wild.deploy.gate_order_derived]]random_dag_of_floor_edges()for each edge (p, c): index(p) < index(c)
cycle_reported_with_membersunit[[wild.deploy.floor_cycle_rejected]]floor_edges_forming_a_cycle()plan == rejected ∧ members listed
gate_ignores_clockunit[[wild.deploy.gate_decision_pure]]same_explicit_evaluation_inputs_with_varied_host_clock()gate(a) == gate(b)
stale_report_blocksunit[[wild.deploy.live_state_fresh]]live_report_past_ttl()gate == blocked ∧ state == Unknown
accretion_roll_has_no_failuresunit[[wild.deploy.rolling_overlap_safe]]rolling_update_of_accretion_pair()no contract-incompatibility failures on the declared demand domain; unrelated operational failures excluded
lineages_overlap_until_retiredunit[[wild.deploy.lineages_served_concurrently]]break_shipped_as_new_lineage()served(old) ∧ served(new) until retire
retire_blocked_while_demandedunit[[wild.deploy.retire_on_zero_demand]]old_lineage_with_one_known_consumer()retire == rejected
canary_share_cappedunit[[wild.deploy.canary_traffic_bounded]]canary_request_above_policy_max()share ≤ policy_max
exact_reject_not_promotableunit[[wild.deploy.evidence_required_to_promote]]shape_Reject_with_clean_canary()promote == rejected
rollback_below_floor_blockedunit[[wild.deploy.rollback_respects_floors]]provider_rollback_below_a_live_floor()rollback == blocked ∧ consumers listed first
irreversible_rollback_blockedunit[[wild.deploy.irreversible_edges_declared]]irreversible_revision_after_first_write()rollback == rejected
override_needs_expiryunit[[wild.deploy.emergency_override_recorded]]override_without_expiry()override == rejected
envelope_has_stage_and_hashesunit[[wild.deploy.deploy_envelope]]arbitrary_deploy_result()envelope has stage ∧ revision hashes ∧ gate verdict
durations_listed_per_stageunit[[wild.deploy.stage_durations_reported]]completed_deployment()report lists duration for each stage
impact_lists_consumersunit[[wild.deploy.deploy_impact_estimated]]plan_for_provider_with_known_consumers()plan lists affected consumers before gate

Notes

Simulation findings behind these rules (toy model, assumed durations): an additive roll of 20 instances produced no failed requests, an uncoordinated break failed roughly a third of calls hitting the changed slot, manual expand/contract took about four working days end to end, and only a small minority of random deploy orders were safe, hence the derived order. Median lead time matched a modern canary pipeline (about 0.8 hours); the gains were in the tail (waiting on consumers) and in user-impact minutes (about 2.4 times lower than the canary baseline across nine sensitivity runs). Escaped undeclared-behavior defects occurred at the same rate as in the canary baseline.

Known limits: the gate trusts the live-revision reports it receives; stale or missing reports fail closed. Retirement is only safe against known consumers. Data written by a new revision is outside accretion unless declared irreversible.

Design acceptance cases

These cases define future runtime behavior. They are not claims that the current prototypes implement the v1 protocol. Executable document and prototype gates are under Requirements.

Rule: Deploy requires published revision

The system SHALL satisfy deploy_requires_published_revision as defined in the Constraints table and the v1 format reference.

Acceptance case: Unpublished revision not deployed

  • GIVEN the fixture domain revision_absent_from_registry()
  • WHEN the deploy_requires_published_revision check runs
  • THEN deploy == rejected

Rule: Floor declared

The system SHALL satisfy floor_declared as defined in the Constraints table and the v1 format reference.

Acceptance case: Floor is least covering revision

  • GIVEN the fixture domain lineage_chain_with_demand()
  • WHEN the floor_declared check runs
  • THEN floor == min(r in chain where demand ⊆ provides(r))

Rule: Provider live before consumer

The system SHALL satisfy provider_live_before_consumer as defined in the Constraints table and the v1 format reference.

Acceptance case: Consumer waits for provider

  • GIVEN the fixture domain consumer_floor_above_live_provider()
  • WHEN the provider_live_before_consumer check runs
  • THEN gate == blocked

Rule: Gate order derived

The system SHALL satisfy gate_order_derived as defined in the Constraints table and the v1 format reference.

Acceptance case: Plan order is topological

  • GIVEN the fixture domain random_dag_of_floor_edges()
  • WHEN the gate_order_derived check runs
  • THEN for each edge (p, c): index(p) < index(c)

Rule: Floor cycle rejected

The system SHALL satisfy floor_cycle_rejected as defined in the Constraints table and the v1 format reference.

Acceptance case: Cycle reported with members

  • GIVEN the fixture domain floor_edges_forming_a_cycle()
  • WHEN the floor_cycle_rejected check runs
  • THEN plan == rejected ∧ members listed

Rule: Gate decision pure

The system SHALL satisfy gate_decision_pure as defined in the Constraints table and the v1 format reference.

Acceptance case: Gate ignores clock

  • GIVEN the fixture domain same_explicit_evaluation_inputs_with_varied_host_clock()
  • WHEN the gate_decision_pure check runs
  • THEN gate(a) == gate(b)

Rule: Live state fresh

The system SHALL satisfy live_state_fresh as defined in the Constraints table and the v1 format reference.

Acceptance case: Stale report blocks

  • GIVEN the fixture domain live_report_past_ttl()
  • WHEN the live_state_fresh check runs
  • THEN gate == blocked ∧ state == Unknown

Rule: Rolling overlap safe

The system SHALL satisfy rolling_overlap_safe as defined in the Constraints table and the v1 format reference.

Acceptance case: Accretion roll has no failures

  • GIVEN the fixture domain rolling_update_of_accretion_pair()
  • WHEN the rolling_overlap_safe check runs
  • THEN no contract-incompatibility failures on the declared demand domain; unrelated operational failures excluded

Rule: Lineages served concurrently

The system SHALL satisfy lineages_served_concurrently as defined in the Constraints table and the v1 format reference.

Acceptance case: Lineages overlap until retired

  • GIVEN the fixture domain break_shipped_as_new_lineage()
  • WHEN the lineages_served_concurrently check runs
  • THEN served(old) ∧ served(new) until retire

Rule: Retire on zero demand

The system SHALL satisfy retire_on_zero_demand as defined in the Constraints table and the v1 format reference.

Acceptance case: Retire blocked while demanded

  • GIVEN the fixture domain old_lineage_with_one_known_consumer()
  • WHEN the retire_on_zero_demand check runs
  • THEN retire == rejected

Rule: Canary traffic bounded

The system SHALL satisfy canary_traffic_bounded as defined in the Constraints table and the v1 format reference.

Acceptance case: Canary share capped

  • GIVEN the fixture domain canary_request_above_policy_max()
  • WHEN the canary_traffic_bounded check runs
  • THEN share ≤ policy_max

Rule: Evidence required to promote

The system SHALL satisfy evidence_required_to_promote as defined in the Constraints table and the v1 format reference.

Acceptance case: Exact reject not promotable

  • GIVEN the fixture domain shape_Reject_with_clean_canary()
  • WHEN the evidence_required_to_promote check runs
  • THEN promote == rejected

Rule: Rollback respects floors

The system SHALL satisfy rollback_respects_floors as defined in the Constraints table and the v1 format reference.

Acceptance case: Rollback below floor blocked

  • GIVEN the fixture domain provider_rollback_below_a_live_floor()
  • WHEN the rollback_respects_floors check runs
  • THEN rollback == blocked ∧ consumers listed first

Rule: Irreversible edges declared

The system SHALL satisfy irreversible_edges_declared as defined in the Constraints table and the v1 format reference.

Acceptance case: Irreversible rollback blocked

  • GIVEN the fixture domain irreversible_revision_after_first_write()
  • WHEN the irreversible_edges_declared check runs
  • THEN rollback == rejected

Rule: Emergency override recorded

The system SHALL satisfy emergency_override_recorded as defined in the Constraints table and the v1 format reference.

Acceptance case: Override needs expiry

  • GIVEN the fixture domain override_without_expiry()
  • WHEN the emergency_override_recorded check runs
  • THEN override == rejected

Rule: Deploy envelope

The system SHALL satisfy deploy_envelope as defined in the Constraints table and the v1 format reference.

Acceptance case: Envelope has stage and hashes

  • GIVEN the fixture domain arbitrary_deploy_result()
  • WHEN the deploy_envelope check runs
  • THEN envelope has stage ∧ revision hashes ∧ gate verdict

Rule: Stage durations reported

The system SHALL satisfy stage_durations_reported as defined in the Constraints table and the v1 format reference.

Acceptance case: Durations listed per stage

  • GIVEN the fixture domain completed_deployment()
  • WHEN the stage_durations_reported check runs
  • THEN report lists duration for each stage

Rule: Deploy impact estimated

The system SHALL satisfy deploy_impact_estimated as defined in the Constraints table and the v1 format reference.

Acceptance case: Impact lists consumers

  • GIVEN the fixture domain plan_for_provider_with_known_consumers()
  • WHEN the deploy_impact_estimated check runs
  • THEN plan lists affected consumers before gate

Acceptance case: Mixed rollout does not satisfy a new floor

  • GIVEN a provider routes 90 percent of requests to revision r1 and 10 percent to r2; a consumer requires a slot first provided by r2
  • WHEN the consumer deploy gate runs
  • THEN it blocks until all reachable routes cover the floor or the consumer is pinned exclusively to covering instances

Acceptance case: Clock is an explicit evaluation input

  • GIVEN a report observed at 15:00:00Z has ttl_seconds 60
  • WHEN the pure gate receives evaluation time 15:01:00Z
  • THEN the report is Unknown and deployment blocks regardless of the host clock

Acceptance case: Concurrent rollback invalidates the gate

  • GIVEN a gate was accepted at coordination generation 12
  • WHEN provider rollback advances the generation before consumer route activation
  • THEN activation aborts and revalidates; the old approval cannot authorize it

Acceptance case: Canary writes can prevent abort rollback

  • GIVEN a canary persisted an irreversible first-write barrier
  • WHEN the canary attempts rollback below the barrier
  • THEN rollback refuses just as it would after full promotion

Acceptance case: Satisfied dependency cycle does not block rollout

  • GIVEN two services depend on each other and both live providers already cover every floor
  • WHEN the deploy plan computes unsatisfied prerequisites
  • THEN it has no cyclic ordering edges and can proceed subject to policy and lease

Requirements

Requirement: Prototype deployment simulation

The prototype deployment simulation SHALL run its overlap, deploy-order, pipeline-sensitivity, and checker-cost models, so the assumptions behind the design remain runnable while wild itself is unbuilt; this gate does not establish runtime floor, lease, TTL, or rollback conformance.

Scenario: Prototype deployment simulation runs clean

  • GIVEN the deployment scenarios encoded in prototype/wild_cd_sim.py
  • WHEN the deployment simulation runs
  • THEN it exits 0 and produces non-empty output
  • AND the gate executes this behavior as a declared contract test

Requirement: Wild deploy design contract

The design corpus SHALL expose this capability’s constraints as normative, self-contained rules with acceptance cases, and SHALL link to a structurally valid shared v1 schema without claiming future runtime behavior is implemented.

Scenario: Wild deploy design is self-contained

  • GIVEN this spec, docs/wild-formats-v1.md, and schemas/wild-v1.schema.json
  • WHEN the design contract gate checks normative rule coverage, local references, and the shared schema
  • THEN every constraint has a corresponding rule and acceptance case
  • AND both referenced files exist and the schema is valid JSON Schema draft 2020-12
  • AND this capability is discoverable by strict OpenSpec validation

wild-extract


id: wild.extract kind: intent statement: THE wild extraction layer SHALL turn schemas, source code, and data artifacts of any ecosystem into Contract IR through pluggable, deterministic extractors that never drop a construct silently.

Wild extract

Purpose

This is a normative design specification; only the prototype and corpus gate scenarios explicitly identified below are implemented. Shared wire formats and decision rules are defined in wild v1 formats and the v1 schema.

The language-blind core sees only IR. Everything ecosystem-specific lives in extractors (schemas, source APIs, feature files, templates) and in law harnesses that run recorded properties against an implementation. Anything an extractor cannot express becomes an opaque, frozen slot and is reported.

Constraints

idkindexprtraces_to
extractor_contractextension_pointfor every conforming extractor E: extract(source) yields ContractIR, is deterministic, and reports coverage listing every unextracted construct[[wild.extract]]
law_harnessextension_pointrun(suite, implementation, seed, fixtures, budgets) yields the v1 LawResult; it declares proof, exhaustive, or sampled method and returns pass, counterexample, or inconclusive with all content digests[[wild.extract]]
extraction_totalinvariantevery parsed declaration relevant to an exported contract maps to a typed or opaque slot; unsupported syntax yields a source-range diagnostic and incomplete extraction, never an invented complete contract[[wild.extract]]
extractor_deterministicinvariantthe same supplied source bundle, extractor artifact digest, options, and IR version yield the same canonical IR bytes; imported schemas and generated artifacts must be supplied and hashed as inputs[[wild.extract]]
extractor_isolatedinvariantextractors read only the source they are given and perform no network or write access[[wild.extract]]
ir_versionedinvariantemitted IR names its schema version; the core refuses IR of an unknown version[[wild.extract]]
data_plane_extractorsinvariantschemas, templates, and feature files have extractors under the same contract as code extractors[[wild.extract]]
ecosystems_pluggableinvariantsupporting a new ecosystem requires an extractor only, with no change to the core[[wild.extract]]
extractor_coverage_reportedadvisoryeach extraction reports the share of constructs mapped to opaque slots[[wild.extract]]
failure_reportedeffectan unreadable source emits a failure report naming the source and the cause[[wild.extract]]
extractor_noise_reportedadvisoryeach extractor reports false breaks / independently adjudicated candidate breaks, sample size, history range, and adjudication source; zero adjudications yield Unknown, not a zero rate[[wild.extract]]

Model

States

  • source_read
  • parsed
  • mapped
  • reported
  • failed (emits: [[wild.extract.failure_reported]])

Transitions

idfromtoguard
parsesource_readparsed[[wild.extract.extractor_isolated]]
mapparsedmapped[[wild.extract.extraction_total]]
reportmappedreported[[wild.extract.extractor_deterministic]] ∧ [[wild.extract.ir_versioned]]
fail_readsource_readfailedsource unreadable under [[wild.extract.extractor_isolated]]
fail_parseparsedfailedviolation of [[wild.extract.extraction_total]]
fail_mapmappedfailedviolation of [[wild.extract.extractor_deterministic]] or [[wild.extract.ir_versioned]]

Properties

idkindderives_fromgeneratorpredicateobserves
extractor_reports_coverageunit[[wild.extract.extractor_contract]]extractor_output_with_unmapped_construct()coverage lists the construct
harness_deterministic_given_seedunit[[wild.extract.law_harness]]harness_run_twice_with_same_seed()result(a) == result(b) or result.status == inconclusive with nondeterminism diagnostic
no_silent_dropunit[[wild.extract.extraction_total]]source_with_unsupported_construct()slot_for(construct) is opaque
same_source_same_bytesunit[[wild.extract.extractor_deterministic]]source_extracted_twice()bytes(a) == bytes(b)
extractor_has_no_side_effectsunit[[wild.extract.extractor_isolated]]extractor_run_with_network_and_writes_blocked()extract completes ∧ no write attempted
unknown_ir_version_refusedunit[[wild.extract.ir_versioned]]ir_with_version("99")core == refused
feature_file_extracts_like_codeunit[[wild.extract.data_plane_extractors]]feature_file_with_known_arity()ir.arity == known_arity
new_ecosystem_needs_no_core_changeunit[[wild.extract.ecosystems_pluggable]]extractor_for_new_ecosystem_added()core_diff == empty
opaque_share_reportedunit[[wild.extract.extractor_coverage_reported]]source_with_known_opaque_count(3 of 10)report.opaque_share == 0.3
unreadable_source_reportedunit[[wild.extract.failure_reported]]source_path_that_does_not_exist()report names the source ∧ the cause[[wild.extract.failure_reported]]
noise_rate_reportedunit[[wild.extract.extractor_noise_reported]]extraction_run_over_known_history()report has false_break_rate_ppm and adjudicated_breaks; zero denominator yields null

Notes

The IR is a common denominator, so extraction is lossy by nature; opaque slots are frozen, which can raise false breaks. That is why noise is measured and reported rather than hidden. Facet-specific extraction (ABI, layout, serialization) arrives as additional extractors under the same contract.

The shared v1 IR, canonical form, consumer manifest, lockfile, sidecar, certificate, and law-result formats are normative in docs/wild-formats-v1.md and schemas/wild-v1.schema.json. Ecosystem-specific extraction must declare its supported syntax and demand-analysis limits before it can claim complete coverage.

Design acceptance cases

These cases define future runtime behavior. They are not claims that the current prototypes implement the v1 protocol. Executable document and prototype gates are under Requirements.

Rule: Extractor contract

The system SHALL satisfy extractor_contract as defined in the Constraints table and the v1 format reference.

Acceptance case: Extractor reports coverage

  • GIVEN the fixture domain extractor_output_with_unmapped_construct()
  • WHEN the extractor_contract check runs
  • THEN coverage lists the construct

Rule: Law harness

The system SHALL satisfy law_harness as defined in the Constraints table and the v1 format reference.

Acceptance case: Harness deterministic given seed

  • GIVEN the fixture domain harness_run_twice_with_same_seed()
  • WHEN the law_harness check runs
  • THEN result(a) == result(b) or result.status == inconclusive with nondeterminism diagnostic

Rule: Extraction total

The system SHALL satisfy extraction_total as defined in the Constraints table and the v1 format reference.

Acceptance case: No silent drop

  • GIVEN the fixture domain source_with_unsupported_construct()
  • WHEN the extraction_total check runs
  • THEN slot_for(construct) is opaque

Rule: Extractor deterministic

The system SHALL satisfy extractor_deterministic as defined in the Constraints table and the v1 format reference.

Acceptance case: Same source same bytes

  • GIVEN the fixture domain source_extracted_twice()
  • WHEN the extractor_deterministic check runs
  • THEN bytes(a) == bytes(b)

Rule: Extractor isolated

The system SHALL satisfy extractor_isolated as defined in the Constraints table and the v1 format reference.

Acceptance case: Extractor has no side effects

  • GIVEN the fixture domain extractor_run_with_network_and_writes_blocked()
  • WHEN the extractor_isolated check runs
  • THEN extract completes ∧ no write attempted

Rule: Ir versioned

The system SHALL satisfy ir_versioned as defined in the Constraints table and the v1 format reference.

Acceptance case: Unknown ir version refused

  • GIVEN the fixture domain ir_with_version("99")
  • WHEN the ir_versioned check runs
  • THEN core == refused

Rule: Data plane extractors

The system SHALL satisfy data_plane_extractors as defined in the Constraints table and the v1 format reference.

Acceptance case: Feature file extracts like code

  • GIVEN the fixture domain feature_file_with_known_arity()
  • WHEN the data_plane_extractors check runs
  • THEN ir.arity == known_arity

Rule: Ecosystems pluggable

The system SHALL satisfy ecosystems_pluggable as defined in the Constraints table and the v1 format reference.

Acceptance case: New ecosystem needs no core change

  • GIVEN the fixture domain extractor_for_new_ecosystem_added()
  • WHEN the ecosystems_pluggable check runs
  • THEN core_diff == empty

Rule: Extractor coverage reported

The system SHALL satisfy extractor_coverage_reported as defined in the Constraints table and the v1 format reference.

Acceptance case: Opaque share reported

  • GIVEN the fixture domain source_with_known_opaque_count(3 of 10)
  • WHEN the extractor_coverage_reported check runs
  • THEN report.opaque_share == 0.3

Rule: Failure reported

The system SHALL satisfy failure_reported as defined in the Constraints table and the v1 format reference.

Acceptance case: Unreadable source reported

  • GIVEN the fixture domain source_path_that_does_not_exist()
  • WHEN the failure_reported check runs
  • THEN report names the source ∧ the cause

Rule: Extractor noise reported

The system SHALL satisfy extractor_noise_reported as defined in the Constraints table and the v1 format reference.

Acceptance case: Noise rate reported

  • GIVEN the fixture domain extraction_run_over_known_history()
  • WHEN the extractor_noise_reported check runs
  • THEN report has false_break_rate_ppm and adjudicated_breaks; zero denominator yields null

Acceptance case: Incomplete parser cannot claim complete inventory

  • GIVEN unsupported syntax prevents inventory of exported declarations
  • WHEN extraction runs
  • THEN it emits source-range diagnostics with incomplete coverage, not a fabricated complete contract

Acceptance case: No adjudications means unknown false-break rate

  • GIVEN history has zero independently adjudicated candidate breaks
  • WHEN the noise report is generated
  • THEN the rate is Unknown and the denominator is reported as zero

Requirements

Requirement: Wild extract design contract

The design corpus SHALL expose this capability’s constraints as normative, self-contained rules with acceptance cases, and SHALL link to a structurally valid shared v1 schema without claiming future runtime behavior is implemented.

Scenario: Wild extract design is self-contained

  • GIVEN this spec, docs/wild-formats-v1.md, and schemas/wild-v1.schema.json
  • WHEN the design contract gate checks normative rule coverage, local references, and the shared schema
  • THEN every constraint has a corresponding rule and acceptance case
  • AND both referenced files exist and the schema is valid JSON Schema draft 2020-12
  • AND this capability is discoverable by strict OpenSpec validation

Requirement: Bounded deterministic Rust extraction

The local extractor SHALL implement the rust-cargo-local-1 profile defined in this change’s design, bind every result to supplied source/build inputs and extractor identity, and emit existing v1 contracts plus separate provenance and completeness records. It SHALL perform no network access or writes to the source bundle. Equivalent supported declaration structure SHALL yield identical semantic contract bytes independently of checkout location. Unknown declaration inventory SHALL prevent complete extraction claims. The profile’s signature subset SHALL treat String as a supported owned-text scalar (text-owned) and &str and &String as a supported borrowed-text scalar (text-borrowed), each emitted without interval fields; mutable text references, bare str, and other text-like constructs SHALL remain unsupported and disclosed. A public enum without cfg gating SHALL inventory each of its variants as a named slot under the enum’s qualified meaning (<crate>::<Enum>::<Variant>) instead of a single opaque enum item, following the identity law (crate identity plus qualified path, never line numbers); cfg-gated variants and generic public enums SHALL keep the honest gap. Impl blocks SHALL be accounted per construct: public inherent impl methods SHALL inventory as type-qualified opaque slots (<crate>::<module>::<Type>::<method>), plain-private impl items SHALL carry no public API surface, and trait impls together with restricted-visibility (pub(crate)/pub(in)) impl items SHALL keep named unsupported-construct gaps; impl bodies SHALL be walked so demands inside them are never silently dropped.

Scenario: Repeated extraction and formatting

  • GIVEN two bundles with equivalent supported declarations, with only whitespace and checkout location different
  • WHEN the pinned extractor processes both under the same profile and build context
  • THEN semantic contract bytes match while raw input identities and source provenance remain accurately distinct

Scenario: Generated export cannot disappear

  • GIVEN a macro or build script can generate exported declarations unavailable to the profile
  • WHEN extraction runs
  • THEN it reports the construct and incomplete inventory and does not invent a complete contract

Scenario: Changed build input requires new extraction

  • GIVEN a prior report and changed feature selection, target, toolchain, or dependency source
  • WHEN the prior extraction is submitted for the new bundle
  • THEN input binding fails and a fresh extraction is required

Scenario: Text-taking public functions become genuine slots

  • GIVEN a provider whose public functions take or return text (arguments of &str, String, or &String, and a String return)
  • WHEN extraction runs
  • THEN the functions surface as function-type slots whose arguments and results carry the text-borrowed/text-owned scalars with no interval fields, &String normalizes to text-borrowed, and the report claims complete inventory with no diagnostics

Scenario: Mutable and bare text stays unsupported

  • GIVEN a provider with a public function taking &mut str (or bare str, char, Cow<str>)
  • WHEN extraction runs
  • THEN the report retains the unsupported-construct gap, the function surfaces as an opaque slot, and inventory is incomplete

Scenario: Public enum variants become named slots

  • GIVEN a provider whose public enum declares two variants and a consumer that constructs a dep-qualified variant
  • WHEN extraction runs
  • THEN each variant inventories as a named slot under the enum’s qualified meaning, the single opaque enum item does not appear, the variant construction resolves as supported demand, and the extraction claims complete inventory with no diagnostics

Scenario: Trait impls and restricted impl items are disclosed per construct

  • GIVEN a provider with an inherent impl exposing a public method, a private method, and a pub(crate) method, plus two trait impls on the same type
  • WHEN extraction runs
  • THEN the public method inventories as a type-qualified opaque slot, the private method carries no public API surface, and the report retains named unsupported-construct gaps for the pub(crate) method and each trait impl — with no blanket impl-block gap

Requirement: Explicit consumer demand coverage

The extractor SHALL resolve supported direct consumer usages to provider slots and SHALL disclose every unsupported usage mechanism encountered in the selected source domain. Macro invocations in expression or statement position whose head is a whitelisted std macro with a closed, argument-confined expansion and whose token trees parse as a comma-separated expression list SHALL be part of the supported demand profile: their arguments SHALL be descended and any demands found there recorded like direct calls, and they SHALL NOT emit an incomplete-demand gap. Any other macro invocation in either position — an unlisted head, or a whitelisted head whose tokens do not parse as an expression list — SHALL keep the incomplete-demand disclosure rather than being silently skipped. A whitelisted macro invocation whose format string implicitly captures an identifier that names a provider item SHALL keep the incomplete-demand disclosure as well. A method call whose receiver resolves in the bounded shapes — a path expression resolving through the bounded demand rules, or a call expression whose head resolves to an inventoried constructor or free function with a recorded syntactic return type — SHALL create the demand <crate>::<Type>::<method>: resolution against the inventoried impl-method or typed slots yields supported demand, and a method absent from the inventory SHALL keep the incomplete-demand gap naming the full path. A method-call receiver outside the bounded shapes (a multi-hop chain beyond one resolved hop, field access, macro output, or an unknown identifier) SHALL keep the incomplete-demand gap naming the receiver. Enum-variant demand paths SHALL resolve as supported demand when the variant is inventoried; unknown variant paths SHALL keep the incomplete-demand gap naming the path. Incomplete demand SHALL prevent scoped-substitution acceptance. Restricting consumer demand SHALL NOT discard required inputs of any selected provider or its transitive dependencies.

Scenario: Used and unused removals differ

  • GIVEN a complete supported consumer demands function a but not function b
  • WHEN a candidate removes b while retaining a and all required dependency bindings
  • THEN the scoped structural check can pass although a whole-provider accretion check reports the removal

Scenario: Hidden usage blocks a scoped claim

  • GIVEN the consumer contains an unresolved macro, a method call whose receiver is outside the bounded resolution shapes, or a function-pointer flow
  • WHEN the known direct demand would otherwise pass
  • THEN the report retains the gap and refuses scoped acceptance with Unknown structural assurance

Scenario: Argument-confined std macro does not block a scoped claim

  • GIVEN a consumer whose code contains a whitelisted std macro invocation in statement position (e.g. println!("v={}", 1);) alongside a direct dependency-qualified provider call
  • WHEN extraction runs
  • THEN the std macro emits no incomplete-demand gap and the provider call still resolves to a provider slot

Scenario: Demands inside supported macro arguments are recorded

  • GIVEN a whitelisted macro invocation in expression or statement position whose arguments reference provider functions (e.g. assert_eq!(a(), b())) and no other consumer code calls those functions
  • WHEN extraction runs
  • THEN the demands for a and b are recorded exactly like direct calls

Scenario: Unsupported macro remains disclosed

  • GIVEN a macro invocation in expression or statement position with an unlisted head, or a whitelisted macro whose tokens do not parse as a comma-separated expression list
  • WHEN extraction runs
  • THEN the report retains the incomplete-demand gap and refuses scoped acceptance with Unknown structural assurance

Scenario: format_args! does not block a scoped claim

  • GIVEN a consumer whose code contains a routed format_args! invocation with positional arguments (e.g. writer.write_fmt(format_args!("hello {}", "world"));) alongside a direct dependency-qualified provider call
  • WHEN extraction runs
  • THEN the format_args! invocation emits no incomplete-demand gap and the provider call still resolves to a provider slot

Scenario: Demands inside format_args! arguments are recorded

  • GIVEN a routed format_args! invocation with positional arguments referencing provider functions (e.g. writer.write_fmt(format_args!("v={} plus {}", add_one(1), 2));) and no other consumer code calls add_one
  • WHEN extraction runs
  • THEN the demand for add_one is recorded exactly like a direct call

Scenario: Demands inside format_args! named-argument values are recorded

  • GIVEN a routed format_args! invocation whose named-argument value references a provider function (e.g. take_args(format_args!("{x} then {x}", x = add_one(1)));) and no other consumer code calls add_one
  • WHEN extraction runs
  • THEN the demand for add_one is recorded exactly like a direct call and no incomplete-demand gap is emitted

Scenario: Format capture naming a provider item is disclosed

  • GIVEN a consumer with a whitelisted macro invocation whose format string implicitly captures an identifier naming a provider value item — directly (use provider::MAX; followed by println!("max={MAX}");) or through a consumer-side alias (use provider::MAX as LIMIT; followed by take_args(format_args!("{LIMIT}"));) — and no other consumer code references that provider item
  • WHEN extraction runs
  • THEN the report retains the incomplete-demand gap and refuses scoped acceptance with Unknown structural assurance

Scenario: Resolved method call becomes supported demand

  • GIVEN a consumer whose method call’s receiver is a call resolving to an inventoried same-crate constructor with a recorded syntactic return type (e.g. Meter::new().tick() where new returns Meter)
  • WHEN extraction runs
  • THEN the demand Meter::tick is recorded and resolves against the inventoried type-qualified impl-method slot with no incomplete-demand gap

Scenario: Method absent from inventory keeps gap

  • GIVEN a consumer whose method call’s receiver resolves in the bounded shapes but whose method is absent from the inventory (e.g. Meter::new().tock())
  • WHEN extraction runs
  • THEN the report retains the incomplete-demand gap naming the full <crate>::<Type>::<method> path and refuses scoped acceptance with Unknown structural assurance

Scenario: Unbounded method receiver keeps gap

  • GIVEN a consumer with a multi-hop method chain beyond one resolved hop (e.g. Meter::new().tick().untick())
  • WHEN extraction runs
  • THEN the report retains the incomplete-demand gap naming the receiver, and the one-hop demand inside the chain is still recorded

Scenario: Variant demand paths resolve

  • GIVEN a consumer that constructs a dep-qualified inventoried variant (e.g. provider::Mode::Slow(1)) and a same-crate inventoried variant in expression position (e.g. let f = Flavor::Sour;)
  • WHEN extraction runs
  • THEN both demands are recorded as supported and no incomplete-demand gap is emitted

Scenario: Unknown variant paths keep the gap

  • GIVEN a consumer referencing provider::Mode::Huge and a same-crate Flavor::Salty, neither inventoried
  • WHEN extraction runs
  • THEN the report retains the incomplete-demand gap naming each path and refuses scoped acceptance with Unknown structural assurance

112 integration failures vs. an accretive-contract versioning tool

Verdicts (about the proposed tool, not the world):

  • S: detectable or preventable mechanically if the design is adopted
  • P: partly; needs an extra facet (ABI, behavior, dialect, environment), laws, or adapters
  • N: outside versioning (governance, business, hardware, coordination)

Examples come from memory and are not individually re-verified. Check specifics before citing.

Tally: S 43, P 57, N 12.

A. Dependency and packaging

#CaseFailureVHandling
1left-pad unpublishedArtifact vanished, builds brokeSAppend-only immutable registry
2event-stream takeoverMalicious maintainer shipped codePNew capabilities show as new requires in the diff; trust is out of scope
3Diamond ranges (npm/pip)Incompatible ranges unsatisfiableSLineage is a chain; take the max
4Python 2→3Breaking change, no bridgePNew lineage name plus mandatory adapter; language-level adapters only partly feasible
5Caret range, breaking minorDeclared minor actually brokeSCompatibility computed, not asserted
60.x semver loophole“Anything may change”SNo special-case versions
7Yanked crate/gemLockfiles reference withdrawn releasePNever delete; mark with advisory edge
8npm peerDependency duplicates (React)Two copies, hooks breakPSingleton contract kind; needs runtime check
9Rust types across majorsv1 Error ≠ v2 ErrorPAdapter plus declared shared identity
10Maven nearest-winsSilently picks older versionSResolver picks max in chain
11Dependency confusionPublic package shadows internal namePNamespace ownership in registry
12TyposquattingLookalike package namesNSocial/registry policy
13Phantom dependenciesImport works only via hoistingSExtracted demands vs declared demands
14Floating latest Docker tagSame tag, different bitsSContent-addressed revisions
15Mutable GitHub Action tagsTag repointed to malicious commitSHash identity
16Lockfile drift between envsCI ≠ prodSHash-pinned revisions

B. ABI and platform

#CaseFailureVHandling
17C++ std::string dual ABI (GCC 5)Link/runtime errorsPABI facet separate from API
18Rust unstable ABIdylib mismatchPABI facet; hash must match
19glibc symbol versions“GLIBC_2.xx not found”PSymbol versioning is accretion; build floor is a requires
20Windows DLL hellShared DLL overwrittenSContent-addressed side-by-side
21Java serialVersionUIDDeserialization failsPSerialization facet
22CPython C-extension ABIWheel per minor versionPabi3 = declared frozen subset
23Node native addon ABINODE_MODULE_VERSION mismatchPSame as 22
24Struct padding/endiannessLayout mismatch across platformsSLayout facet in IR
25FFI/JNI struct driftSilent memory corruptionSLayout hash
26Linux “never break userspace”Rare semantic regressionsPBehavioral laws
27Linux in-kernel APIOut-of-tree modules breakPExplicit “unstable” lineage
28Android targetSdk changesSame API, new behaviorPDefaults as slots; behavior laws
29Swift pre-5.0 ABIApps bundled runtimePABI facet

C. Schema and serialization

#CaseFailureVHandling
30Protobuf field-number reuseOld data misreadSNames/ids never reassigned
31proto2 required fieldCan never be removedSRequires polarity
32Protobuf unknown enum valueOld client mishandlesPOpen vs closed sum flag
33Avro non-transitive BACKWARDv1→v3 breaks despite adjacent passesSTransitive closure
34Avro added field, no defaultOld readers failSNew provide must be optional
35Thrift field id/type changeWire mismatchSShape diff
36JSON int64 in JavaScriptPrecision lossPNumeric range in scalar facet
37null vs absent fieldSemantics divergePPresence as slot attribute
38additionalProperties:falseAdded field breaks strict clientSOpen/closed record flag
39NOT NULL column, old writersInserts failSWriters’ requires grew
40Dropping column, old readersQueries failSProvides shrank
41Column renameNeeds expand/contractSNew name plus adapter (dual-write)
42ORM/DB driftModel ≠ actual schemaPExtract both and diff
43Parquet/Arrow column reorderPositional readers breakPPositional vs named slot flag
44CSV header changeDownstream parsers breakSShape diff
45Date format/timezone in payloadSilent misinterpretationPSemantic type facet
46XML any / namespacesExtension collisionsSOpen record with namespaced names
47GraphQL field removalUnknown clients breakPOnly declared demand is knowable
48GraphQL enum additionExhaustive clients breakSOutput-position sum is closed
49OpenAPI vs implementation driftSpec liesPExtract from code and spec; diff

D. Services and protocols

#CaseFailureVHandling
50/v1→/v2 copies whole APICoarse bump forces total migrationSPer-slot compatibility
51Twitter API v1.1 / pricingAccess removedNBusiness decision
52Google Reader shutdownService endedNBusiness decision
53Chrome SameSite defaultSame cookie, new behaviorPDefaults as behavior slots
54TLS 1.0 removalOld clients locked outPCapability negotiation as requires/provides
55HTTP middlebox ossificationProtocol can’t evolveNNetwork reality
56DNS flag dayNeeds global coordinationNCoordination
57gRPC status/deadline per languageDivergent semanticsPCross-language laws
58Retry/idempotency changeDuplicate side effectsPIdempotency as law
59Offset→cursor paginationDifferent protocolSNew name plus adapter
60Rate-limit tighteningIntegrations throttledPNon-functional laws
61Webhook payload evolutionReceivers unknownPDeclared demands only
62OAuth scope restrictionCapability narrowedPCapability as requires
63Parsed error stringsClients depend on textPHyrum: undeclared surface
64Unspecified ordering (Go map)Code relied on orderPDeclare unordered; cannot stop reliance
65Performance regressionComplexity change breaks callersPBounds as laws
66Token TTL changeCached tokens expire earlyPBehavior law

E. Language and library

#CaseFailureVHandling
67Java 9 modulesIllegal reflective accessPReflection surface undeclared
68Log4j JNDI defaultDangerous default behaviorPDefaults as slots
69Node createCipher removalAPI removedSProvides shrank
70AngularJS→AngularRewrite under same brandPNew lineage; adapter extremely hard
71Perl 6 / RakuIncompatible successorSLineage rename
72Swift 2→3 renamesMass source breakageSRename = adapter (migrator)
73Ruby 3 kwargsSame signature, new semanticsPCall-semantics law
74C undefined behaviorOptimizers exploit UBNLanguage spec problem
75JS flatten→flat (MooTools)Monkey-patching collided with new builtinPOpen-world extension
76Python async keywordIdentifiers became reservedSReserved names are a shared namespace
77Go compat promise exceptionsUnkeyed struct literalsPClosed-record flag
78Rust trait impl ambiguityAdded impl/method breaks callersPCoherence facet
79Scala 2.12 vs 2.13 binaryIncompatible artifactsSArtifact suffix = lineage name
80Java default-method conflictDiamond default methodsSName collision in merge
81Overload ambiguityAdded overload breaks call sitesPResolution rules per language
82Inference breakageReturn-type change alters inferencePLanguage-specific facet
83Struct field additionBreaks positional/exhaustive useSClosed-record flag
84Floating-point determinismDiffers by platform/flagsNHardware/compiler
85ICU/Unicode collationSort order changesPDialect/environment requires
86Regex dialectsPCRE vs RE2 behaviorPDialect named in contract

F. Distributed systems and runtime

#CaseFailureVHandling
87Rolling deploy N/N+1Mixed versions coexistSAccretion = bidirectional safety
88Stale cached objectsOld serialization after deploySTransitive compatibility
89Kafka in-flight old messagesLong retention outlives schemaSTransitive compatibility
90Event-sourcing replayYears-old eventsSUpcasters are adapters
91Feature-flag combinatoricsUntested combinationsPFlags as slots; explosion remains
92Mobile long-tail clientsOld apps never updateSAccretion keeps them working
93Root cert expiry (Let’s Encrypt 2021)Old devices fail TLSNTime/trust
94Y2038 / int32 timeOverflowPWidth in scalar facet
95Kubernetes API removalsextensions/v1beta1 goneSapiVersion lineage plus conversion
96Terraform provider upgradeResource semantics changePBehavior laws
97Helm values schemaValues keys changeSShape diff
98YAML “Norway problem”Parser dialect differencesPDialect named
99CRD conversion webhook failureConversion bugPAdapter law tests
100nginx directive removalConfigs refuse to loadSProvides shrank

G. Standards, hardware, data, humans

#CaseFailureVHandling
101Mars Climate OrbiterUnits mismatchPUnits in IR
102Ariane 5Ariane 4 assumptions reusedPEnvironment assumptions as requires
103Knight CapitalReused flag changed meaning mid-deploySNames never change meaning
104HL7 v2Vendor-specific interpretationPProfiles as contracts
105Bluetooth/USB interoperabilityImplementation quirksNHardware certification
106OOXML transitional vs strictTwo dialectsPDialect lineage
107CSS vendor prefixes/quirksBrowser divergenceNImplementation diversity
108SQL dialectsPortable SQL isn’tPDialect lineage
109Emoji version glyphsMissing charactersNClient updates
110Excel gene names → datesAuto-typing corrupts dataPSemantic type facet
111EDI X12 versionsTrading-partner mismatchSNegotiated adapters
112tzdata changesFuture timestamps change meaningNPolitical reality

What this changes in the design

  1. Contracts need facets, not one shape: API, ABI/layout, serialization, behavior/defaults, dialect, environment. Most P verdicts live in the last four.
  2. Defaults and environment are first-class slots. Many failures are same signature, new behavior (53, 68, 73, 28).
  3. Name identity must be enforced hard (103, 30, 9). A name’s meaning never changes.
  4. Polarity plus open/closed flags resolve a large cluster (31, 38, 48, 77, 83).
  5. Open-world demand is irreducible (47, 61, 63, 75). Say so in output rather than pretend otherwise.
  6. N cases need a different tool: governance, deprecation schedules, coordination.

50 more integration failures (113-162)

Continues the first catalog (rows 1-112). Each row below introduces a failure mechanism not used in the first list.

Verdicts (about the proposed accretive-contract tool): S = mechanically detectable or preventable if adopted. P = partly; needs an extra facet, laws, or adapters. N = outside versioning.

Sourcing: rows 113-122 were checked against web sources this session (linked). Rows 123-162 are from memory and should be verified before citing.

Tally for this batch: S 16, P 33, N 1. Combined with part 1 (162 cases): S 59, P 90, N 13.

A. Verified this session

#CaseFailureVHandlingSource
113CrowdStrike Channel File 291 (Jul 2024)A new template type defined 21 input fields, but the code feeding the interpreter supplied 20; out-of-bounds read crashed ~8.5M hosts. Data shipped outside the code release pathSExtract arity from both the data schema and the interpreter; a mismatch is a failed accretion check. Data-plane artifacts need contracts tooRCA
114Cloudflare outage, 18 Nov 2025A DB permissions change made a generated feature file double in size and exceed a hard-coded limit in the proxyPDeclared limits (cardinality, size) become slots. Undeclared hard-coded limits stay invisiblepost-mortem
115Cloudflare leap second (Jan 2017)Code assumed time never goes backwards; a negative duration panicked the DNS softwarePEnvironment assumptions (monotonic clock) as requires; cannot infer them from codeCloudflare
116Let’s Encrypt drops clientAuth EKU (2026)Certificates were reused for mTLS client auth, a capability never promised for that purposePOnly declared demand is knowable. Consumers must declare the purpose; unknown dual-use remainsLet’s Encrypt
117CA/B Forum SC-081 certificate lifetimesMax validity falls 398→200 days (Mar 2026), 100 (2027), 47 (2029); manual renewal processes breakPA scheduled sunset is a time-indexed shrink of provides; contracts need a schedule field so the break is computable years aheadSectigo
118MCP spec 2025-03-26 → 2025-06-18JSON-RPC batching was added, then removed one revision laterSA standard violating accretion between consecutive revisions: the checker’s exact remitchangelog
119Redis BSD → RSAL/SSPL → AGPLLicense changes forced forks and migrationsPLicense as a contract facet (SPDX diff is mechanical; legal meaning is not)InfoQ
120Redis vs Valkey after the forkForks diverge: newer RDB files are not interchangeable, so data needs a logical migrationPFork = two accretions from a common ancestor; a pushout exists only if no semantic collision, so divergence is detectable but not repairablemigration guide
121ChatGPT model retirements (Feb 2026)GPT-4o and others left ChatGPT; existing chats defaulted to a successor model. API access was unchanged at announcementPMutable aliases are an identity problem (pin by hash: S). Behavior drift of the successor is notYourStory
122Chrome third-party cookies / Privacy SandboxA planned replacement stack was built on, then 10 APIs were retired Oct 2025 while cookies stayedPStability tiers: an experimental lineage may be retracted, and the tool should label it so consumers knowEngadget

B. From memory (verify before citing)

#CaseFailureVHandling
123Bitcoin fork, Mar 2013Versions 0.7 and 0.8 disagreed on a database-imposed limit; the chain splitPImplicit consensus rules defined by an implementation must be declared as contract
124Upgradeable smart-contract proxiesNew implementation reorders storage variables and corrupts stateSLayout facet; append-only storage slots
125Parity multisig library (2017)A shared library contract was destroyed, freezing dependent walletsPDependency liveness as requires; irreversible operations flagged
126Git SHA-1 → SHA-256Hash algorithm is part of object identity; repos are mutually unreadablePHash algorithm belongs in identity; interop needs a bridge adapter
127OpenSSL 3.0 providersLegacy algorithms moved behind a provider not loaded by defaultPCapability set as provides; loading is environment
128Kubernetes dockershim removalContainer-runtime interface dropped from kubeletSProvides shrank; external adapter (cri-dockerd) existed
129Kubernetes PodSecurityPolicy → Pod Security AdmissionReplacement is less expressive, so policies cannot be translated exactlyPLossy adapter; the tool should report what is lost
130Chrome Manifest V2 → V3Blocking webRequest capability removed from extensionsSProvides shrank; resolution is a policy choice
131Safari ITP storage capsScript-writable storage can be purged after days without interactionPDurability as a declared guarantee
132macOS Catalina drops 32-bit appsUnmaintained binaries stop runningPAdapters impossible without a maintainer
133Adobe Flash end of lifePlugin platform removed; content strandedPEmulators (Ruffle) act as adapters
134GitHub master → mainScripts hard-coded the default branch namePConventions hard-coded instead of declared
135PEP 668 externally-managed environmentspip install into system Python now errorsPTooling policy change; environment requires
136Webpack 5 drops Node polyfillsBundler had implicitly provided shimsPExtract implicit provisions from tooling
137colors / faker sabotage (2022)Owner shipped intentionally broken versionsSRegistry rejects a breaking change without a new name
138HTTP request smugglingFront-end and back-end parse message length differentlyPCross-implementation conformance laws
139Gmail/Yahoo bulk-sender rules (2024)Receivers tightened authentication requirements; mail rejectedPReceiver’s requires grew; senders may not track them
140CPython free-threaded buildExtensions assumed a global interpreter lockPThread-safety facet, opt-in declaration
141NumPy 2.0 C-API changeWheels built against 1.x failed under 2.xPABI facet; build floor as requires
142Protobuf generated code vs runtimeOld generated files rejected by newer runtimeSGenerated artifact embeds a required-runtime range
143PostgreSQL major upgradesOn-disk format incompatible across majorsSEach major a lineage; pg_upgrade is the adapter
144Elasticsearch / Lucene index lookbackIndices only readable one major backSDeliberately non-transitive; checker flags it
145Kafka rolling upgradeProtocol/message-format pins force a two-phase upgrade orderPDeployment sequencing is outside the contract
146Terraform state upgradesNewer versions write state older ones cannot read; no downgradePEdges can be irreversible; declare reversibility
147Python PEP 517 build isolationBuilds that relied on ambient build deps failedPBuild-time contract
148ISO 20022 / MT coexistenceRicher messages truncated when translated to old formatSAdapter round-trip law detects loss
1493G network sunsetDevices lost connectivityNInfrastructure retirement
150Excel 1900 leap-year bugA deliberate bug kept for compatibilityPQuirk lineage: bug-compat declared, not hidden
151OpenSSL 1.1 opaque structsCode touching struct fields brokeSClosed/opaque layout flag
152Case-insensitive filesystemsRepos with case-colliding paths break on macOS/WindowsPFilesystem semantics as environment
153LB idle timeout vs backend keep-aliveIntermittent 502s from mismatched timeoutsPRelational constraint across two contracts
154Retry amplificationEach layer retries; compatible parts overload the wholePCompositional law (retry budget)
155JVM DNS cachingClient ignores TTL; stale endpointsPClient behavior vs protocol
156Repo signing key rotationKey change breaks installsPTrust-anchor lineage
157WASI preview1 → preview2Module interface model replacedSNew lineage plus adapter
158Sync → async API changeSame name, new calling conventionSEffect facet (async is a different type)
159Ethereum/ETC fork replaySigned transactions valid on both chainsSLineage id inside signed payloads (chain id)
160WordPress “Tested up to”Host compatibility is a human claimPReplace assertion with checked compatibility
161pip’s stricter resolver (2020)Enforcement exposed conflicts old installers hidSAdoption needs baseline/grandfather mode
162Old client read-modify-writeTyped clients drop unknown newer fields on updateSRound-trip law: preserve unknown fields

What this batch adds to the design

  1. Data-plane artifacts need contracts (113, 114): content files, feature files, templates.
  2. Declared limits are slots (114): sizes, cardinalities, timeouts.
  3. Sunset schedules and stability tiers (117, 122): breaks can be computed years ahead, and some lineages are explicitly retractable.
  4. Standards can violate accretion too (118).
  5. Adapters need laws (148, 162): lossless round-trip and unknown-field preservation.
  6. Lineage id belongs in identity (126, 159).
  7. Relations between contracts (153) and emergent properties (154) are beyond per-contract checking.
  8. Irreversibility and sequencing (146, 145): edges can be one-way; upgrade order matters.
  9. Adoption mode (161): first enforcement will surface latent breaks, so a baseline is required.

llms.txt

The machine-readable landing page, mirrored from llms.txt and served at https://wild.charlyvibes.com/llms.txt.