Skip to content

fix(fuse): coalesce + index-remap the name section under --preserve-names (#328)#333

Merged
avrabe merged 1 commit into
mainfrom
fix/328-name-section-coalesce-remap
Jul 11, 2026
Merged

fix(fuse): coalesce + index-remap the name section under --preserve-names (#328)#333
avrabe merged 1 commit into
mainfrom
fix/328-name-section-coalesce-remap

Conversation

@avrabe

@avrabe avrabe commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

First fix of the v0.39.0 combined release.

What

--preserve-names emitted duplicate name custom sections (llvm-dwarfdump rejects the module) with stale, pre-fusion function indices (wrong labels). Now it emits one coalesced name section whose indices are remapped into the fused space. Same class as #222 (producers), applied to name — plus the index remap producers didn't need.

How

  • MergedModule.fused_function_names: BTreeMap<u32,String> accumulates fused-indexed names.
  • merger.rs: name is remapped via function_index_map at the per-module merge (accumulate_remapped_function_names) instead of copied verbatim; unmapped (dead) entries dropped — never a wrong index (LS-D-1); non-function subsections dropped this pass.
  • encode_output: emits exactly one name section from the accumulator under preserve_names, in the LLVM-required order.

Verification

  • Unit test accumulate_remapped_function_names_remaps_and_drops_unmapped (remaps mapped indices; drops unmapped).
  • Full pre-commit suite green (fmt, clippy, all tests) — no regressions.

Gate

Tier-5 (merger.rs, adapter/) → needs a Mythos discover pass + mythos-pass-done before merge (in progress). rivet requirement scoped release: v0.39.0 to follow. Held for your merge nod.

Refs #328.

🤖 Generated with Claude Code

…ames (#328)

`--preserve-names` copied every input module's `name` custom section verbatim
into the fused module. With multiple modules that produced (a) DUPLICATE `name`
sections — llvm-dwarfdump rejects the whole module (`out of order section type:
0`) — and (b) function-name entries carrying each source module's PRE-fusion
indices, so names labelled the wrong fused functions. `wasm-tools validate`
passes, so it was silent. Same class as #222 (producers), never applied to
`name`.

Fix (the #222 pattern + index remapping):
- `MergedModule` gains `fused_function_names: BTreeMap<u32, String>`.
- At the per-module custom-section merge (merger.rs), `name` is no longer copied
  verbatim; `accumulate_remapped_function_names` parses it and remaps each
  function-name entry from `(comp, module, orig_idx)` into the fused index space
  via `function_index_map` (already populated by the preceding function merge).
  Entries with no mapping (dead/internalized) are dropped — never a wrong index
  (LS-D-1). Non-function subsections are dropped in this pass.
- At encode (`encode_output`, `preserve_names` branch) exactly ONE coalesced
  `name` section is emitted from the accumulator, in the LLVM-required order.

So the output carries a single `name` section whose indices are all in the fused
space. Pinned by `accumulate_remapped_function_names_remaps_and_drops_unmapped`.

Tier-5 (merger.rs, adapter/): needs a Mythos discover pass before merge.

Refs #328.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

Mythos delta-pass required

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

meld-core/src/adapter/fact.rs
meld-core/src/merger.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.

@github-actions

Copy link
Copy Markdown

LS-N verification gate

59/59 approved LS entries verified

count
Passed (≥1 test, all green) 59
Failed (≥1 test failure) 0
Missing (no ls_*_NN_* test found) 0

Approved loss-scenarios.yaml entries are expected to have a
regression test named ls_<letter>_<num>_* (e.g. LS-A-11
ls_a_11_*). The gate runs each prefix via cargo test --lib --no-fail-fast and aggregates pass/fail/missing.

Failed LS entries

(none)

Missing regression tests

(none)

Updated automatically by tools/post_verification_comment.py.
Source of truth: safety/stpa/loss-scenarios.yaml.

@github-actions

Copy link
Copy Markdown

Mythos delta-pass (auto)

1 finding(s) across 2 Tier-5 file(s)

File Verdict Hypothesis
`` ✅ NO FINDINGS
meld-core/src/merger.rs ❌ FINDING discover step failed before emitting structured output — see workflow logs

Auto-run via anthropics/claude-code-action@v1
(SHA-pinned) on the touched Tier-5 files, using the
maintainer's Max-plan OAuth token. See
.github/workflows/mythos-auto.yml and
scripts/mythos/discover.md.

@avrabe

avrabe commented Jul 11, 2026

Copy link
Copy Markdown
Contributor Author

Mythos discover pass: NO FINDINGS (manual)

The automated Mythos pass (meld-core/src/merger.rs) job timed outReached maximum number of turns (30) — merger.rs is ~5800 lines, so the automated discover step exhausted its turn budget before emitting a verdict, and the workflow synthesized a placeholder FINDING ("discover step failed before emitting structured output"). It is not a real finding.

A full manual adversarial discover pass on this change (accumulate_remapped_function_names, the merge-loop routing, and the encode_output emission) returned NO FINDINGS. Angles checked, all correct by construction:

  • Imported-function index space (highest risk): the name section's function-name subsection and function_index_map share the identical origin index space (imports keyed by import_func_idx; defined funcs by import_func_count + old_idx, merger.rs:1446/1864). No offset mismatch — the exact bug class fuse --preserve-names emits duplicate + index-stale 'name' sections: llvm-dwarfdump rejects whole module and names point at wrong functions (same class as #222, for 'name') #328 fixes is handled right.
  • Ordering: function-index population (1707-1868) completes before the custom-section merge loop (2177) in the same per-module pass; import_counts.func is finalized up-front. Unmapped entries dropped, never emitted at a wrong index (LS-D-1).
  • Correctness anchor: the remap reuses the same function_index_map that rewrites call-instruction targets, so wrong indices would break every call and be caught by validation/tests.
  • Emission point (after code, LLVM order), ascending NameMap::append (BTreeMap), adapters unnamed (indices beyond the map), malformed-section drop — all correct.

Adding mythos-pass-done to signal the discover pass is complete.

@avrabe avrabe added the mythos-pass-done Mythos delta-pass completed on Tier-5 file changes; findings (or NO FINDINGS) attached to PR label Jul 11, 2026
@avrabe avrabe merged commit 63e5f28 into main Jul 11, 2026
13 of 16 checks passed
@avrabe avrabe deleted the fix/328-name-section-coalesce-remap branch July 11, 2026 04:13
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