Skip to content

chore: DWARF / witness mapping discovery for fused output (sub-#130)#131

Merged
avrabe merged 2 commits into
mainfrom
chore/dwarf-witness-discovery
May 18, 2026
Merged

chore: DWARF / witness mapping discovery for fused output (sub-#130)#131
avrabe merged 2 commits into
mainfrom
chore/dwarf-witness-discovery

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented May 1, 2026

Summary

Rebased + refreshed for Phase 1.5 (post-#135)

Original draft sat for 16 days while Phase 1.5 (PR #135, commit c7a2c0b) flipped the default DWARF policy from PassThrough to Strip. The fixup commit on this branch:

  1. Adds the new dwarf_handling field to both helper builders.
  2. Renames fuse_defaultfuse_passthrough — the discovery oracle was never "whatever default does", it was "pin passthrough for Phase 2 to flip".
  3. Re-purposes the original current_default_is_merge_not_drop test (which asserted the pre-1.5 default) to current_default_is_strip_post_phase_1_5 (post-1.5 reality + future-flip canary).
  4. Updates docstrings to reflect Phase 1.5 as shipped rather than upcoming.

5/5 discovery tests pass; full meld-core lib suite is 236/236.

What the test pins

DWARF sections at top level of fused module: {
    ".debug_abbrev": 2,  ".debug_info": 2,  ".debug_line": 2,
    ".debug_loc": 2,     ".debug_ranges": 2, ".debug_str": 2,
}
input  code-section length (sum across embedded modules): 231531 bytes
fused  code-section length:                                213242 bytes

(Numbers from tests/wit_bindgen/fixtures/lists.wasm; duplicate sections per the buggy passthrough; addresses inside encoded against the input's old code section.)

Audit findings (committed in the test docstring + filed in #130)

  • FuserConfig::default().dwarf_handling is now DwarfHandling::Strip (Phase 1.5). To exercise the passthrough path you must opt in via dwarf_handling: DwarfHandling::PassThrough.
  • merger.rs:2010-2012 naively concatenates per-module custom_sections with no dedup or rewriting.
  • lib.rs::encode_output (line 1390 area) emits all of them unless Drop is configured OR Strip removes them.
  • No code anywhere in meld-core/src/ parses or rewrites .debug_* content.
  • Component-level custom sections are dropped at parse time; only core-module custom sections flow through.

Cross-repo dependency: witness

pulseengine/witness v0.11.x is the consumer that breaks under PassThrough. It uses gimli (crates/witness-core/src/decisions.rs) to build a (code-section byte offset) -> (file, line) map for MC/DC attribution. The DWARF passed through by meld today (when PassThrough is opted-into) gives gimli wrong + duplicated input.

Witness is intentionally NOT a meld-core dependency. End-to-end "run witness on a fused module and check coverage" lives in the cross-repo integration story; this PR is the meld-side discovery oracle.

Test plan

  • CI green (Format, Clippy, Test, Coverage, Bench, Fuzz, Mythos gate, LS-N gate)
  • Mythos auto-runner: this PR adds a new TEST file, not a Tier-5 source file — detect job will set any=false and matrix-scan will skip. Next Tier-5 PR (likely Phase 2 DWARF Phase 2: address remap (#130) #143's actual remap code) gets the full auto-runner test.

Sequencing post-merge

🤖 Generated with Claude Code

avrabe and others added 2 commits May 18, 2026 18:39
meld currently passes DWARF custom sections through fusion byte-for-byte.
DWARF addresses encode byte offsets into the per-input code section, but
fusion rewrites function bodies into a new merged code section — so every
preserved DWARF address points at the wrong instruction (or out of
range). The pulseengine `witness` MC/DC tool reads those addresses via
gimli, so coverage attribution for fused modules is currently silently
wrong.

This change:
- Adds `meld-core/tests/dwarf_passthrough.rs` pinning the current
  lossy-but-present behaviour as five green tests so any future
  remapping work has a clear oracle to flip.
- Documents the witness DWARF contract and the cross-repo integration
  shape in the test's module docstring (witness intentionally stays
  out of meld-core's dep graph).

No production code changes — defaults are unchanged. Phased plan
(Phase 1.5 explicit policy, Phase 2 DWARF remap, Phase 3 adapter DIEs)
tracked in #130.

Refs #130

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Phase 1.5 shipped on main in PR #135 (commit c7a2c0b) during the 16
days this branch sat idle. The DWARF default flipped from PassThrough
(broken-but-present) to Strip (correct-but-lossy), and `FuserConfig`
gained a new `dwarf_handling` field.

Three rebase-driven updates:

1. Add the `dwarf_handling` field to both helper builders. The
   PassThrough path is the one Phase 2 (#143) will flip from broken
   to correct, so the existing tests' premise — pin the broken
   behaviour as a Phase-2 oracle — needs the explicit opt-in now
   that Strip is the default.

2. Rename `fuse_default` → `fuse_passthrough` to make its scope
   explicit. The discovery oracle was never about "whatever the
   default does" — it was about pinning passthrough behaviour for
   Phase 2 to flip — and that's clearer post-1.5.

3. Re-purpose the `current_default_is_merge_not_drop` test to
   `current_default_is_strip_post_phase_1_5`. The original was
   written to flag a future default flip; the flip has now
   happened, so the assertion inverts. Future changes (e.g.
   Phase 2 making PassThrough the new default) continue to be
   surfaced by this same test.

4. Update docstrings and inline comments referencing Phase 1.5 as
   "will ship" to "shipped in #135 / PR c7a2c0b".

All 5 discovery tests still pass against the updated helpers, and
the full meld-core lib suite (236/236) is unaffected.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@avrabe avrabe force-pushed the chore/dwarf-witness-discovery branch from 59cfebb to 4e72d47 Compare May 18, 2026 16:57
@avrabe avrabe marked this pull request as ready for review May 18, 2026 16:58
@github-actions
Copy link
Copy Markdown

LS-N verification gate

⚠️ 16/19 verified — 3 missing regression tests

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

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
  • LS-CP-4
  • LS-A-8
  • LS-A-9

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

@avrabe avrabe merged commit 77f5f3b into main May 18, 2026
14 checks passed
@avrabe avrabe deleted the chore/dwarf-witness-discovery branch May 18, 2026 19:02
@avrabe avrabe mentioned this pull request May 20, 2026
2 tasks
avrabe added a commit that referenced this pull request May 21, 2026
P3 cross-component stream-pair detection foundation + a fully
operational Mythos delta-pass auto-runner. 12 commits since v0.8.1.

Headline changes:

- Cross-component stream<T> pairing detection (#141, ADR-3). The
  StreamPairGraph foundation for the in-module stream adapter: meld
  now inventories at resolve time which fused components form
  producer -> consumer stream pairings. The ring-buffer / copy-chain
  emitter is a runtime-verified follow-up (ADR-3 Path N).

- Mythos delta-pass auto-runner (#162, #164, #170, #173, #175). The
  AI-driven discover protocol now runs automatically on every
  Tier-5 PR by the maintainer, via claude-code-action on a Max-plan
  OAuth token. Five plumbing fixes brought it to a working
  end-to-end state: scan -> NO_FINDINGS verdict -> sticky comment ->
  mythos-pass-done label.

- LS-N verification gate (#161, #165). Every approved loss-scenario
  in safety/stpa/loss-scenarios.yaml is now enforced to have a
  matching ls_<letter>_<num>_* regression test; 19/19 verified.

- DWARF / witness-mapping discovery (#131) — Phase 1 of the #130
  epic; pins today's lossy passthrough as the green-to-red oracle
  for the Phase 2 remap work.

- Regression coverage for LS-A-8/9/19 and LS-CP-4 (#163/165/166/169)
  — closed every missing-test entry the LS-N gate surfaced.

- CI footprint reduction (#171) — bench/fuzz/ci skip on docs- and
  safety-only PRs; meld is a leaner consumer of the shared fleet.

- fuzz.yml musl-target drop (#170, closes #168) — fixes the
  recurring "sanitizer incompatible with statically linked libc"
  fuzz failures.

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant