ADR-0080: Sealed root-worker GNU version requirement inventory
Status: accepted
Date: 2026-08-10
Decision owners: NAUX architecture and x86-64 root-requester boundary
Context
ADR-0076 inventories version requirements made by the three exact dependency
providers. ADR-0077 through ADR-0079 prove provider namespace compatibility and
inventory their dynamic symbols. The sealed root worker is a different ELF
object: its own undefined symbols are the requests a future sovereign resolver
must eventually satisfy, but its DT_VERNEED/Vernaux chains have never been
independently inventoried.
ADR-0071 records the worker’s direct DT_NEEDED names, and ADR-0072 admits the
exact caller-reviewed declarations. ADR-0075 closes those names over exact
provider identities. None of those decisions proves which GNU version
namespaces the worker requests. Reading those chains later inside symbol lookup
would merge requester inventory, provider compatibility, and resolution into
one oversized authority boundary.
Decision drivers
- Read only the already verified, immutable root-worker descriptor; never reopen its original path.
- Independently decode the root ELF layout and exact GNU
Verneed/Vernauxchains without section headers or a host ELF library. - Bind every requirement filename to exactly one direct ADR-0072 declaration and exactly one ADR-0075 provider identity.
- Preserve record/auxiliary order, flags, hashes, local version indices, names, offsets, and predecessor identities under explicit limits.
- Keep requirement inventory separate from definition matching and symbol lookup.
Considered options
Reuse host-loader diagnostics
Rejected. Loader output and host search state are not sealed semantic inputs.
Trust ADR-0071 direct dependencies as version requirements
Rejected. DT_NEEDED proves only an object-level declaration. It contains no
version name, version hash, flags, or local version index.
Reuse ADR-0076 evidence for the root worker
Rejected. ADR-0076 is explicitly scoped to canonical ADR-0075 providers and binds each record to a provider object ordinal. The worker is the root requester, not another provider appearance.
Combine requirement inventory, definition matching, and symbol lookup
Rejected. These are three different judgments. A malformed requester chain must fail before NAUX considers provider namespaces or lookup precedence.
Emit a root-only proof ledger and defer compatibility
Selected. ADR-0080 inventories exactly what the worker asks for and which
reviewed direct provider the filename denotes. A later ADR must independently
join those names to ADR-0077 definitions before root dynsym/versym or
symbol resolution can consume them.
Decision
Introduce one root-worker requirement evidence object. Emission first replays ADR-0071, ADR-0072, and the accepted ADR-0075 closure, then obtains bytes only from the verified artifact descriptor. The new decoder independently:
- validates ELF64 little-endian x86-64
ET_DYN, program headers, bounded read-onlyPT_LOADmappings, and one exactPT_DYNAMICsegment; - requires paired
DT_STRTAB/DT_STRSZand paired optionalDT_VERNEED/DT_VERNEEDNUMtags with a canonical terminated dynamic table; - walks exactly
DT_VERNEEDNUM16-byte records and each exact 16-byteVernauxchain, rejecting overlaps, early/late terminals, zero counts, invalid relative offsets, unsupported revisions, and reserved flags; - decodes bounded printable names from the admitted string table and verifies every auxiliary’s System V ELF name hash;
- requires every requirement filename to equal exactly one ordered ADR-0072
direct dependency and one exact ADR-0075 provider SONAME; the interpreter is
not an implicit dependency candidate unless explicitly declared by
DT_NEEDED; - preserves root artifact identity, declaration ordinal, provider ordinal, record/auxiliary ordinals, raw fields, exact names/hashes/indices, record ranges, predecessor evidence hashes, and domain-separated local/aggregate seals.
Verification preflights bounded evidence shape and predecessor roots, then replays the decoder from the immutable descriptor and requires exact evidence equality. Requirement order is semantic evidence and is never sorted or deduplicated.
Frozen limits
- exactly one root requester;
- at most 64 program headers, 16 load segments, and 4,096 dynamic entries;
- at most 64 root requirement records and 64 auxiliaries per requirement;
- at most 4,096 total root auxiliaries;
- string table at most 1 MiB and each filename/version name at most 256 bytes;
Verneedrevision exactly 1;- only zero or GNU weak flag bits are structurally recognized; weak compatibility remains ungranted;
- accepted ADR-0071 inventory policy root
1a6c96c8b47a2001d9969488785c6bb2b846c378280b0498f2c16b0f14fd3bbf; - accepted ADR-0072 declaration policy root
5a69470530ec8f65be018f53927379381a6d20cec7ca9076a69441a80183ec22; - accepted ADR-0075 closure policy root
6835b65f73be7d214da23b20c92b93013ac02c5f3b96c4abf743cd503761bd56; - proof-only inventory; encoder policy remains
1.4.0.
Consequences
- Positive: a future resolver receives a complete root requester namespace ledger instead of decoding version chains while binding symbols.
- Positive: every requirement file is already tied to a reviewed sealed provider identity without using host search paths.
- Positive: path replacement after artifact admission cannot change the inventoried root bytes.
- Negative: successful inventory does not prove that any requested version or symbol exists.
- Negative: verification replays the accepted artifact/declaration/closure chain before decoding.
- Risk: weak requirements remain recorded but cannot be interpreted as fallback authority.
- Open: root requirement-to-definition compatibility, root dynamic-symbol and version-index inventory, lookup scopes, interposition, binding, relocation, mapping, initialization, TLS/IFUNC and execution remain separate decisions.
Acceptance gates
- Lock the exact ordered root
VerneedandVernauxcounts, filenames, provider ordinals, version names, hashes, flags, and local indices. - Missing, duplicate, mismatched, truncated, excessive, overlapping, early/late-terminal, revision, flag, count, offset, string, name/hash, declaration/provider, stale-root, reorder, and locally resealed mutations fail closed.
- A coherent mutation selecting a different valid direct provider and recomputing every local seal still fails independent regeneration.
- Replay remains exact after source-path replacement; production source has no filesystem, path, process, section-header, host parser/loader, definition-matching, symbol, 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-0071 supplies
the sealed root ELF and exact direct
DT_NEEDEDdeclarations. - ADR-0072 supplies caller-reviewed direct dependency authority.
- ADR-0075 supplies exact canonical provider identities.
- ADR-0077 is the future compatibility target but grants no authority to this inventory.
- ADR-0079 supplies only provider symbol facts, not root requester facts.
Acceptance record
Accepted on 2026-08-10 under policy root
1e728341f69e0cb1ba9d5ce8a6400cdbe72c8866a1ed8ec8e52a1a50fa9fecdf.
The immutable root worker exposes three ordered requirement records and twenty
ordered auxiliaries: three GCC_* names for libgcc_s.so.1, sixteen
GLIBC_* names for libc.so.6, and one GLIBC_2.3 name for
ld-linux-x86-64.so.2. Every file binds to its exact ADR-0072 declaration and
ADR-0075 provider. Local version indices are sealed per exact artifact and
remain valid and globally unique; they are not falsely equated across
different feature-linked worker binaries.
Raw probes reject dynamic-tag, count, revision, file/name offset, duplicate file, auxiliary-link, flag, version-index, and ELF-name-hash mutations. Evidence probes reject stale predecessor roots, totals, records, auxiliaries, and a coherent alternate direct-provider choice after all affected seals are recomputed. Admission, inventory, mutation, and verification continue from the sealed descriptor after the original root-worker source is replaced and deleted.
The final all-feature workspace exits successfully. The library suite reports
413 passed, zero failed, and six intentionally ignored tests in 434.92 seconds;
the ADR-0073 through ADR-0080 carrier reports two passed and zero failed in
524.68 seconds; the process-isolation carrier reports three passed and zero
failed in 308.73 seconds. Strict Clippy with warnings denied, cargo check,
22/22 governance, 8/8 strict refinement, all nine shell syntax checks,
format/diff, 343/343 local Markdown targets, locked policy-root tests,
production static-authority inspection, raw/evidence mutation probes, and
exact descriptor replay pass.
Acceptance grants no requirement-to-definition compatibility, root dynamic-
symbol or .gnu.version inventory, lookup, selection, interposition, binding,
weak fallback, mapping, relocation, initialization, execution, sandbox,
standalone, timing, performance-claim, or global encoder-policy authority.