fix(resource_graph): #295 — rep-backed Defines authoritative over export-inferred terminal (LS-A-17 hardening)#296
Conversation
…ort-inferred terminal (LS-A-17 hardening) The terminal-exporter pass in `ResourceGraph::build` attributed a definer via `defines_cache.insert` / `definer_cache.insert` BEFORE the rep-backed `defines_candidates` were merged in with `.or_insert`, so an export-name terminal component holding NO canonical `ResourceRep` could silently OVERRIDE a genuine rep-backed definer for the same `(iface, rn)`. Surfaced by a bounded Mythos discovery sweep (#295); reachability to a live misroute was REFUTED — the resolver consumes `resource_definer` only as `.is_some()` and the routing override at resolver.rs:3116 is downgrade-only + heuristic-gated, so a wrong definer value cannot steer a route. This is therefore robustness HARDENING, not a correctness fix. Fix: compute `rep_backed_resources` (the set of `(iface, rn)` with a rep-backed `Defines` candidate) and skip export-inferred attribution for those — rep-backed `Defines` is authoritative; export-inference fills ONLY the genuine no-rep (flattened-canonical) case it exists for. Behaviour-unchanged where the terminal exporter IS the rep holder (the cases LS-A-17/18 + the live routing already exercise); only the rep-vs-export conflict now resolves toward the rep holder. Oracle (proven red→green): ls_a_17_rep_backed_definer_authoritative_over_export_terminal — a rep holder (comp 0) + a no-rep export terminal (comp 1) for the same interface; asserts resource_definer == Some(0), defines_resource(0)=true, defines_resource(1)=false. Confirmed FAILING (Some(1)) on the pre-fix code, passing after. Traceability: LS-A-17 Fix section extended with the #295 hardening + residual note (the no-rep-collision last-wins determinism, .is_some()-immune at every consumer). resource_graph 4/0; full meld-core suite 0 failed; clippy -D warnings + fmt clean; LS-N gate 57/0/0 (LS-A-17 already gated); rivet validate 0 broken cross-refs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Mythos delta-pass requiredThis PR modifies one or more Tier-5 source files (per Before merge, run the Mythos discover protocol on the
Why this gate exists: LS-A-10 The gate check on this PR will pass once the label is |
LS-N verification gate✅ 57/57 approved LS entries verified
Approved Failed LS entries(none) Missing regression tests(none) Updated automatically by |
Mythos clean-room delta-pass — VERDICT: REFUTED (hardening sound, behaviour-preserving)A fresh-context adversarial verifier attacked the change (bounded; throwaway probes reverted, tree clean):
Additional safety note: even if that degenerate input were somehow reachable, post-fix ( No failing reachable test could be constructed → REFUTED. The hardening is sound. Working tree confirmed clean. |
Mythos delta-pass (auto)✅ NO FINDINGS across 1 Tier-5 file(s)
Auto-run via |
…ensitive (mythos-auto finding) The mythos-auto discover pass on PR #296 caught an incompleteness in the first commit's guard (my manual clean-room pass missed it): `rep_backed_resources` was keyed by the exact interface string, but `defines_resource`/`resource_definer` and the terminal-exporter `iface_matches` are `[export]`-prefix-INSENSITIVE. So a rep holder registered under `svc:lib/api` did not match a terminal whose resource node is keyed `[export]svc:lib/api` (a distinct map key) — the guard's `.contains()` returned false, the no-rep terminal was still attributed, and `defines_resource(1, "svc:lib/api", "thing")` wrongly returned true via the `[export]`-alias lookup. Fix: normalise the `[export]` prefix (strip it) on BOTH the `rep_backed_resources` keys and the membership check, matching `defines_resource`'s bare/`[export]` lookup semantics. Oracle (proven red→green): new `ls_a_17_rep_backed_guard_is_export_prefix_insensitive` — rep holder under bare `svc:lib/api`, no-rep terminal node under `[export]svc:lib/api`; asserts `defines_resource(1, ..)` is false. Confirmed FAILING on the prior commit, passing after. resource_graph 5/0; full meld-core suite 0 failed; clippy -D warnings + fmt clean; LS-N 57/0/0; rivet validate 0 broken cross-refs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Iteration: mythos-auto caught an
|
What
Closes the #295 follow-up: defensive hardening of
ResourceGraph::build's definer attribution. The terminal-exporter pass randefines_cache.insert/definer_cache.insertbefore the rep-backeddefines_candidateswere merged with.or_insert, so an export-name terminal holding noResourceRepcould silently override a genuine rep-backed definer for the same(iface, rn).Why it's hardening, not a correctness fix
Reachability to a live misroute was REFUTED (#295): the resolver consumes
resource_defineronly as.is_some(), and the routing override atresolver.rs:3116is downgrade-only + heuristic-gated, so a wrong definer value can't steer a route. This makes the resource queries robust against future consumers; it changes no current routing.Fix
Compute
rep_backed_resources(the(iface,rn)set with a rep-backedDefinescandidate) and skip export-inferred attribution for those — rep-backedDefinesis authoritative; export-inference fills only the genuine no-rep (flattened-canonical) case it exists for. Behaviour-unchanged where the terminal exporter is the rep holder (the verified-correct LS-A-17/18 + live-routing cases); only the rep-vs-export conflict resolves toward the rep holder.Oracle (proven red→green)
ls_a_17_rep_backed_definer_authoritative_over_export_terminal: a rep holder (comp 0) + a no-rep export terminal (comp 1) for the same interface → assertsresource_definer == Some(0),defines_resource(0)=true,defines_resource(1)=false. Confirmed FAILING (Some(1)) on the pre-fix code, passing after.Traceability & verification
.is_some()-immune at every consumer). Honest framing: robustness, reachability-refuted — not a new loss path.meld-coresuite 0 failed; clippy-D warnings+ fmt clean; LS-N gate 57/0/0 (LS-A-17 already gated; the newls_a_17_test adds coverage);rivet validate0 broken cross-refs.Scope
Tier-5 (
resource_graph.rs) → Mythos clean-room delta-pass +mythos-pass-donelabel before merge.🤖 Generated with Claude Code