ADR-0083: Reviewed root dynamic-symbol lookup-scope admission

Status: accepted
Date: 2026-08-10
Decision owners: NAUX architecture and x86-64 root lookup-scope boundary

Context

ADR-0075 admits three exact sealed providers and their reviewed transitive dependency graph. ADR-0079 inventories every dynamic symbol and GNU version word in those providers. ADR-0082 inventories the sealed root requester’s 108 dynamic symbols and binds every nonlocal version index to its exact requirement and compatible provider definition.

None of those decisions says in which order providers may be searched for a root import. ADR-0075 provider ordinals are canonical identity order, not ELF lookup order. DT_NEEDED order, transitive graph order, filesystem order, and whatever order a host loader happens to expose are distinct facts. Allowing a later lookup pass to invent this order would combine policy admission with symbol selection and make the first match an unreviewed ambient decision.

Decision drivers

  • Make lookup order explicit, bounded, reviewed, deterministic, and sealed before any symbol name or hash is examined.
  • Bind each scope entry to the exact ADR-0075 provider identity and matching ADR-0079 provider-symbol object evidence.
  • Bind the complete scope to the ADR-0082 requester inventory it is allowed to serve.
  • Preserve lookup order independently of canonical provider ordinal order.
  • Reject missing, duplicate, stale, reordered, foreign, or only name-equivalent providers.
  • Grant no name lookup, candidate selection, weak fallback, relocation, or execution authority.

Considered options

Use ADR-0075 provider ordinal order

Rejected. Provider ordinal is a canonical identity key. Treating it as lookup precedence would give an unrelated serialization choice semantic authority.

Derive scope from DT_NEEDED and closure traversal inside lookup

Rejected. A traversal algorithm, duplicate-collapse rule, and root inclusion rule would then be hidden policy inside the consumer. Closure evidence remains an input constraint, not an implicit scope constructor.

Ask the host dynamic loader for its current global scope

Rejected. Host process state, preload configuration, loader implementation, audit modules, namespaces, and environment are not NAUX proof authority.

Combine scope construction and first-match symbol lookup

Rejected. A lookup result could conceal an omitted or reordered provider and would make mutation diagnosis ambiguous.

Admit one externally reviewed ordered scope ledger

Selected. A reviewer supplies a complete ordered list of already sealed provider identities. Admission proves exact membership and predecessor bindings, then seals only the order and identities. Lookup remains closed.

Decision

Introduce a root lookup-scope expectation and accepted evidence ledger:

  1. the expectation identifies exactly one accepted ADR-0082 requester root;
  2. each ordered entry carries its scope ordinal, ADR-0075 provider ordinal, exact SONAME, object digest, closure-provider evidence identity, and the matching ADR-0079 provider-symbol object evidence identity;
  3. every accepted ADR-0075 provider appears exactly once and no other entry is admitted;
  4. SONAME, digest, provider ordinal, symbol-object ordinal, and every predecessor evidence identity must agree exactly;
  5. expectation encoding and evidence encoding are separately domain separated, bounded, deterministic, and order sensitive;
  6. admission fully replays ADR-0079 and ADR-0082 before comparing the reviewed scope against their exact inputs;
  7. verification preflights canonical order and predecessor roots, regenerates the complete admission result, and requires exact equality;
  8. production admission reads no ELF bytes and performs no string/hash table probe, symbol lookup, first-match selection, interposition, relocation, mapping, initialization, or execution.

For the frozen root worker, the reviewed provider scope is expected to follow its direct dependency precedence: provider 1 libgcc_s.so.1, provider 2 libc.so.6, then provider 0 ld-linux-x86-64.so.2. This is the accepted reviewed order; no consumer may infer or replace it from ambient loader state.

Frozen limits

  • exactly one root requester;
  • at most 65 sealed providers and 65 scope entries;
  • current frozen scope has exactly three entries and covers all three accepted providers once;
  • names at most 256 bytes;
  • accepted ADR-0075 closure policy root 6835b65f73be7d214da23b20c92b93013ac02c5f3b96c4abf743cd503761bd56;
  • accepted ADR-0079 provider-symbol policy root d39244c89aad35ab8c0d617a6688e4a3c19acbd8029306e5d42070bdfec07758;
  • accepted ADR-0082 root-symbol policy root 6d68c8c455536c683484f012a3d0c3e91f8a879ac981f96362c7c45b37ea6ea4;
  • accepted ADR-0083 scope policy root 4b913fa2728a953023691220b48e905ccadc14a14cbcc98f342d4a671d29765a;
  • proof-only admission; encoder policy remains 1.4.0.

Consequences

  • Positive: later lookup consumes one explicit precedence order rather than inventing policy from provider storage order.
  • Positive: two providers with the same SONAME or symbol spelling cannot be substituted by name alone.
  • Positive: admission needs no new ELF decoder, path, loader, or execution capability.
  • Negative: deployment must review and provide a complete scope expectation.
  • Negative: any provider-set change invalidates the complete scope evidence.
  • Open: root self-symbol precedence, symbolic name/hash lookup, versioned candidate filtering, weak/unique semantics, visibility/type compatibility, relocation, mapping, initialization, and TLS/IFUNC execution remain later decisions.

Acceptance gates

  1. Lock the exact ordered scope (1, libgcc_s.so.1), (2, libc.so.6), (0, ld-linux-x86-64.so.2) with exact provider, object, and ADR-0079 symbol evidence identities.
  2. Omitted, duplicate, foreign, reordered, wrong-name, wrong-digest, wrong-provider, wrong-symbol-object, stale-root, count, and shallow mutations fail closed.
  3. A coherent permutation with entry and aggregate seals recomputed still fails independent regeneration against the reviewed expectation.
  4. Production source has no filesystem, path, ELF-byte/parser, host loader, symbol-name/hash lookup, selection, relocation, mapping, native, timing, or claim authority.
  5. Focused default/all-feature, full workspace, strict lint, governance, refinement, format, shell, link, static-authority, and predecessor replay gates pass before acceptance.
  • ADR-0075 supplies the exact sealed provider set and graph identities.
  • ADR-0079 supplies each provider’s exact symbol-object identity.
  • ADR-0082 supplies the exact root requester identity served by this scope.

Acceptance record

Accepted on 2026-08-10 under policy root 4b913fa2728a953023691220b48e905ccadc14a14cbcc98f342d4a671d29765a. The frozen scope contains exactly three entries in reviewed precedence order: provider 1 libgcc_s.so.1, provider 2 libc.so.6, and provider 0 ld-linux-x86-64.so.2. Every entry binds the exact ADR-0075 closure provider identity, sealed object digest, and matching ADR-0079 provider-symbol object evidence. The aggregate binds the accepted ADR-0082 root requester and covers the complete three-provider set exactly once.

Admission fully replays the provider-symbol and root-symbol predecessors before minting scope evidence. Verification preflights canonical ordinals, counts, names, identities, entry seals, aggregate roots, and predecessor policy roots, then independently regenerates the complete result. Missing, duplicate, foreign, stale, reordered, wrong-name, wrong-digest, wrong-provider, and wrong-symbol-object mutations fail closed. A coherent permutation with entry ordinals and all local seals recomputed passes only structural preflight and is then rejected by regeneration against the reviewed order. Exact evidence still verifies after all source artifact paths are removed.

Focused default and all-feature carriers pass in 948.06 and 1002.30 seconds. The final all-feature workspace exits successfully: the library suite reports 419 passed, zero failed, and six intentionally ignored tests in 456.03 seconds; process isolation reports three passed and zero failed in 331.66 seconds; the ADR-0073 through ADR-0083 carrier reports two passed and zero failed in 997.14 seconds; and the independent ADR-0071 inventory reports two passed and zero failed in 138.35 seconds. Strict Clippy across the workspace, targets, and features with warnings denied, cargo check, 22/22 governance, 8/8 strict refinement, all nine shell syntax checks, frozen policy-root tests, static-authority inspection, format/diff, local Markdown link audit, and full predecessor regeneration pass.

Acceptance grants no root-self precedence, name/hash lookup, symbol selection, interposition, binding, weak or GNU-unique fallback, visibility/type compatibility, relocation, mapping, initialization, TLS/IFUNC execution, sandbox, standalone, timing, performance claim, or global encoder-policy authority.