ADR-0081: Exact root GNU version compatibility admission
Status: accepted
Date: 2026-08-10
Decision owners: NAUX architecture and x86-64 root-requester compatibility boundary
Context
ADR-0080 independently inventories the GNU version namespaces requested by the sealed root worker and binds each requirement file to one reviewed direct provider. ADR-0077 independently inventories the definitions exported by those sealed providers. Neither decision proves that a root requirement is actually present in its named provider.
Root dynamic-symbol inventory and later symbol lookup must not infer namespace compatibility while resolving a symbol. That would merge requester facts, provider facts, namespace compatibility, and lookup precedence into one authority boundary. It would also permit an identically named namespace in a different provider to mask a missing definition in the provider explicitly named by the root worker.
Decision drivers
- Consume only fully verified ADR-0080 requirement and ADR-0077 definition evidence; do not decode ELF bytes again.
- Select definitions only inside the exact provider already bound by each root requirement record.
- Preserve requester order and both source/target evidence identities.
- Require exact primary-name and System V ELF-hash equality.
- Refuse weak requirements until a separately reviewed fallback policy exists.
- Keep namespace compatibility separate from root symbol inventory, lookup, interposition, binding, and relocation.
Considered options
Defer compatibility to symbol lookup
Rejected. A lookup engine must consume compatibility authority, not mint it.
Search every provider for a matching version name
Rejected. GNU Verneed.vn_file names the provider namespace. A same-name
definition in another provider is not a substitute.
Match any auxiliary name in a definition chain
Rejected. ADR-0077 identifies the first Verdaux name and vd_hash as the
primary definition identity. Parent names are evidence, not aliases that mint
new definitions.
Treat weak requirements as ordinary strong matches
Rejected. Weak fallback semantics require a separate policy and adversarial corpus. ADR-0081 records no fallback authority.
Emit a proof-only ordered compatibility ledger
Selected. One binding is emitted for every strong ADR-0080 auxiliary, in exact requirement/auxiliary order, and points to exactly one primary ADR-0077 definition in the already-bound provider.
Decision
Introduce a root compatibility evidence object. Emission first independently replays ADR-0080 and ADR-0077, then joins only their verified evidence:
- every root requirement retains its ADR-0080 record identity, declaration ordinal, provider ordinal, provider evidence identity, file name, and ordered auxiliary sequence;
- a requirement with nonzero flags fails closed; weak compatibility is not admitted;
- the selected definition object must have the same provider ordinal and SONAME already bound by ADR-0080;
- exactly one definition in that object must have both the same primary name and the same System V ELF name hash as the requirement auxiliary;
- every binding seals the root record/auxiliary ordinals and hashes, local requester version index, provider definition-object hash, selected definition ordinal/hash/name/name-hash/version-index/flags, and its own ordered binding ordinal;
- an aggregate seal binds both predecessor policy/evidence roots, exact requirement and provider counts, all twenty ordered bindings, and the domain-separated ADR-0081 policy identity.
Verification preflights bounded evidence shape and all predecessor identities, then fully regenerates the compatibility ledger and requires exact equality. No byte source, path, loader, definition decoder, symbol table, or host search state participates in the join.
Frozen limits
- exactly one root requester and at most 65 sealed providers;
- at most 64 root requirement records and 64 auxiliaries per requirement;
- at most 4,096 total bindings;
- names at most 256 bytes;
- accepted ADR-0080 root-version policy root
1e728341f69e0cb1ba9d5ce8a6400cdbe72c8866a1ed8ec8e52a1a50fa9fecdf; - accepted ADR-0077 provider-definition policy root
f447533303533aca4f761a202aafecdff11a428b48aa3b51fa7bd81cda9172ce; - strong exact-name/hash compatibility only;
- proof-only admission; encoder policy remains
1.4.0.
Consequences
- Positive: later root symbol inventory and lookup can consume a sealed namespace-compatibility ledger rather than repeating provider selection.
- Positive: identically named versions in different providers cannot be
substituted across a
vn_fileboundary. - Positive: the join needs no new ELF parser or filesystem authority.
- Negative: any missing or weak root requirement rejects the entire ledger.
- Negative: verification replays the complete ADR-0080 and ADR-0077 chains.
- Open: root
dynsym/versym, symbol lookup scopes, weak/unique semantics, visibility/type rules, relocation, mapping, initialization, TLS/IFUNC, and execution remain separate decisions.
Acceptance gates
- Lock twenty ordered strong bindings with per-file counts 3, 16, and 1.
- Prove the two
GLIBC_2.3requirements select different exact providers and definitions according to their ADR-0080 file binding. - Missing, duplicate, ambiguous, weak, cross-provider, name/hash, ordinal, count, reorder, stale-root, and shallow mutations fail closed.
- A coherent alternate valid provider/definition selection with every local and aggregate seal recomputed still fails independent regeneration.
- Production source has no filesystem, path, process, object-byte, ELF parser, host loader, root-symbol, lookup, relocation, native, timing, or claim authority.
- Focused, workspace, strict lint, governance, refinement, format, shell, link, parity, static-authority, and descriptor-replay gates pass before acceptance.
Related decisions
- ADR-0075 supplies exact provider identities transitively replayed by both inputs.
- ADR-0077 supplies the provider definition namespaces.
- ADR-0078 establishes the analogous provider-requester join but grants no root authority.
- ADR-0080 supplies root requirement and direct-provider identities.
Acceptance record
Accepted on 2026-08-10 under policy root
db6e8c4640a19a7a7c7925d97c64923ccbd4e5baf9c3a293786f962b13a1df0e.
The root ledger contains twenty ordered strong bindings over three requirement
records with exact per-provider counts 3, 16, and 1. Every binding preserves
the ADR-0080 requirement and auxiliary identities, declaration/provider
identity, local requester index, exact ADR-0077 definition object and record,
primary name/hash, definition index/flags, and its global order.
Both GLIBC_2.3 requirements are present deliberately: the libc request binds
provider 2 and definition index 4, while the loader request binds provider 0
and definition index 3. Their definition-object evidence hashes differ. A
coherent mutation that replaces one complete requester/provider/definition
tuple with the other valid tuple and recomputes the binding and aggregate seals
still fails independent regeneration. Weak, missing, ambiguous, wrong-hash,
reordered, stale-predecessor, shallow, and cross-provider mutations also fail
closed.
Focused default and all-feature carriers pass in 588.45 and 604.21 seconds.
The final all-feature workspace exits successfully: the library suite reports
415 passed, zero failed, and six intentionally ignored tests in 439.88
seconds; process isolation reports three passed and zero failed in 293.44
seconds; the ADR-0073 through ADR-0081 carrier reports two passed and zero
failed in 607.00 seconds. Strict Clippy with warnings denied, cargo check,
22/22 governance, 8/8 strict refinement, all nine shell syntax checks,
format/diff, 349/349 local Markdown targets, frozen policy-root tests, static-authority
inspection, shallow/deep mutation probes, and exact descriptor replay after
source deletion pass.
Acceptance grants no root dynamic-symbol or .gnu.version inventory, symbol
lookup, selection, interposition, binding, weak fallback, visibility/type
compatibility, mapping, relocation, initialization, execution, sandbox,
standalone, timing, performance-claim, or global encoder-policy authority.