Skip to content

fix(resource-graph,merger): match full (iface, rn) tuple in 4 sites (LS-A-17/18/19)#156

Open
avrabe wants to merge 1 commit into
mainfrom
fix/resource-graph-key-matching
Open

fix(resource-graph,merger): match full (iface, rn) tuple in 4 sites (LS-A-17/18/19)#156
avrabe wants to merge 1 commit into
mainfrom
fix/resource-graph-key-matching

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented May 14, 2026

Fifth fix from the post-v0.8.0 Mythos delta-pass sweep. Four related bugs in resource_graph.rs (3) and merger.rs (1), all about cleanup / classifier loops dropping the interface dimension of (component, interface, resource_name) tuples or using suffix matching where exact match was required.

The bugs

LS Site Effect
LS-A-17a resource_graph.rs definer purge (279-308) Same-resource-name across different interfaces → wrong definer purged
LS-A-17b resource_graph.rs terminal exporter (242-264) Unrelated resource import disqualifies the definer
LS-A-18 resource_graph.rs first pass (124-172) Re-exporter that drops a foreign resource invisible to graph → wrong-table drop → UB
LS-A-19 merger.rs dedup-skip (2127-2153) ends_with("float") matches both float and bigfloat

All four lead to silent cross-resource confusion or wrong-handle-table routing with no host trap.

Fixes

  • definer purge: filter by (idx == from_comp && iface == ri && r == rn) — full tuple match.
  • terminal exporter: scope to_also_imports_resource to the iface under attribution (and [export]-prefixed variants).
  • first-pass: extracted ResourcePrefixKind enum; handle Drop arm as ImportsFrom edge (matches second pass).
  • merger dedup: exact-match against format!("[resource-{rep,new}]{rn}").

Tests (3 new)

  • ls_a_17_definer_survives_unrelated_import_with_same_resource_name
  • ls_a_17_terminal_definer_with_unrelated_resource_import
  • ls_a_18_drop_on_foreign_resource_registers_node_for_reexporter

Tier-5 gate

Touches resource_graph.rs and merger.rs (both Tier-5).

Test plan

  • cargo test -p meld-core --lib — 211 pass (208 prior + 3 new)
  • cargo clippy --all-targets -- -D warnings — clean
  • cargo fmt --check — clean
  • YAML lint
  • CI green on smithy
  • mythos-pass-done label

Refs

  • LS-A-17 (UCA-F-2, H-1, H-3)
  • LS-A-18 (UCA-F-2, H-3)
  • LS-A-19 (UCA-M-9, H-1, H-10)
  • Discovered by post-v0.8.0 Mythos delta-pass on resource_graph.rs and merger.rs

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 14, 2026

Mythos delta-pass required

This PR modifies one or more Tier-5 source files (per
scripts/mythos/rank.md):

meld-core/src/merger.rs
meld-core/src/resource_graph.rs

Before merge, run the Mythos discover protocol on the
modified Tier-5 files:

  1. Follow scripts/mythos/discover.md
    — one fresh agent session per touched Tier-5 file.
  2. For each finding, the agent must produce both a Kani
    harness and a failing PoC test (per the protocol's
    "if you cannot produce both, do not report" rule).
  3. Attach a comment on this PR with either the findings
    (formatted per discover.md's output schema) or
    NO FINDINGS.
  4. Add the mythos-pass-done label to this PR.

Why this gate exists: LS-A-10
(CABI alignment padding in async-lift retptr writeback) was
found by the v0.8.0 pre-release Mythos pass — but it had
lived in the callback emitter since #128, across six
releases. A PR-time gate would have caught it at review
time instead of at the release boundary.

The gate check on this PR will pass once the label is
applied.

@avrabe avrabe added the mythos-pass-done Mythos delta-pass completed on Tier-5 file changes; findings (or NO FINDINGS) attached to PR label May 14, 2026
@avrabe
Copy link
Copy Markdown
Contributor Author

avrabe commented May 14, 2026

Mythos delta-pass evidence

Tier-5 files touched: meld-core/src/resource_graph.rs, meld-core/src/merger.rs.

The post-v0.8.0 Mythos sweep on resource_graph.rs returned 3 findings (F1/F2/F3) all about the cleanup loops dropping the iface dimension; the merger.rs sweep included finding C (ends_with suffix match). All four PoCs concrete — agent constructed ParsedComponents directly. PoCs are folded into 3 regression tests. The merger ends_with fix is verified via code review + integration with the test fixture pattern.

Adjacent observations from these scans not in any PR yet (still tracking):

…LS-A-17/18/19)

Four sites in meld-core either dropped the interface dimension of the
(component, interface, resource_name) tuple or used substring/suffix
matching where exact match was required. All led to silent cross-
resource confusion or wrong-handle-table routing with no host trap.

LS-A-17a — resource_graph.rs definer purge (lines 279-308). The
cleanup filter ignored the iface when removing defines_cache entries.
A component importing `[resource-rep]X` from interface I_x AND defining
its own `[resource-rep]X` in unrelated interface I_y lost the
(comp, I_y, X) definer entry.

LS-A-17b — resource_graph.rs terminal-exporter pass (lines 242-264).
`to_also_imports_resource` checked any iface, mis-classifying a
definer as a re-exporter when the consumer imported any unrelated
resource interface (e.g. wasi:io/poll).

LS-A-18 — resource_graph.rs first pass (~lines 124-172) only stripped
`[resource-rep]` and `[resource-new]` prefixes. A re-exporter that
imports `[resource-drop]Y` for a foreign resource Y never registered
Y in the graph; the drop call then routed to the first matching
handle-table fallback (LS-A-15 family), invoking a foreign dtor on a
foreign rep.

LS-A-19 — merger.rs::add_unresolved_imports dedup-skip path used
`imp.name.ends_with(rn)`. Two distinct resources sharing a suffix
(`float` / `bigfloat`) collided into the same tracking entry.

Fixes:
- definer purge: filter by (idx == from_comp && iface == ri && r == rn)
- terminal exporter: scope to_also_imports check to the iface under
  attribution (and [export]-prefixed variants)
- first-pass: extracted ResourcePrefixKind enum; handle Drop arm as
  ImportsFrom edge (matches second pass)
- merger dedup: exact-match against format!("[resource-{rep,new}]{rn}")

Tests (3 new):
- ls_a_17_definer_survives_unrelated_import_with_same_resource_name
- ls_a_17_terminal_definer_with_unrelated_resource_import
- ls_a_18_drop_on_foreign_resource_registers_node_for_reexporter

LS-A-17/18/19 added to safety/stpa/loss-scenarios.yaml. Discovered by
the post-v0.8.0 Mythos delta-pass sweep on resource_graph.rs and
merger.rs.

Refs: LS-A-17, LS-A-18 (UCA-F-2, H-1, H-3), LS-A-19 (UCA-M-9, H-1, H-10)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@avrabe avrabe force-pushed the fix/resource-graph-key-matching branch from c9eb19d to 2b199ea Compare May 15, 2026 14:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

mythos-pass-done Mythos delta-pass completed on Tier-5 file changes; findings (or NO FINDINGS) attached to PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant