Skip to content

feat(298): drop vestigial cabi_realloc + defer dead memory.grow (unblocks --memory shared --address-rebase) - #345

Merged
avrabe merged 2 commits into
mainfrom
feat/298-drop-vestigial-realloc
Jul 15, 2026
Merged

feat(298): drop vestigial cabi_realloc + defer dead memory.grow (unblocks --memory shared --address-rebase)#345
avrabe merged 2 commits into
mainfrom
feat/298-drop-vestigial-realloc

Conversation

@avrabe

@avrabe avrabe commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Wires the previously-INERT cabi_realloc_drop_provably_safe verdict so a fully-internalised boundary drops its dead allocator — removing the last dead artifact that blocked the lean single-address-space MCU fuse (SR-50, the #326#334#298 MCU-dissolve arc).

What it does

When the boundary is provably vestigial (core output, no adapters, all lifts scalar) AND address_rebasing is on AND the allocator is provably dead, meld drops the cabi_realloc* exports (allocator DCEs downstream) and defers the dead memory.grow to unreachable — so --memory shared --address-rebase (which otherwise hard-errors on memory.grow) succeeds. Every other path is byte-identical.

Mythos discover pass — 2 findings, both fixed on this branch

  • FINDING 1 (HIGH): module-wide grow-defer was unsound — the boundary verdict proves no marshalling realloc is needed, not that the allocator is dead. A scalar-interface component that allocates internally (Vec/Stringdlmallocsbrkmemory.grow, reachable from a live export) would fuse-Ok then trap at runtime (a compile error silently downgraded to a trap). Fix: a call-graph reachability probe (memory_probe::module_has_reachable_memory_grow — roots = live exports minus the dropped cabi_realloc*, start, ref.func/elem targets; edges = call/return_call; fail-safe on parse error) ANDed into the gate. Now only fires when no memory.grow is reachable from a live non-cabi_realloc root; a live internal grow keeps cabi_realloc and the clean hard-error.
  • FINDING 2 (LOW): tightened the export match to cabi_realloc / cabi_realloc$<digits> (was starts_with, which could drop a lookalike export).

Tests (467 lib + 7 integration green; clippy + fmt clean)

scalar_boundary_drops_realloc_and_defers_grow (positive), live_internal_grow_keeps_realloc_and_hard_errors (FINDING 1), tight_match_preserves_realloc_lookalike_export (FINDING 2), 3 verdict-branch negatives (string lift / component output / adapter site all keep realloc + hard-error), non-shared guard, + 11 memory_probe unit tests (transitive dlmalloc/sbrk reachability live vs dead, elem/start roots, malformed fail-safe).

Falsification

If the reachability gate regressed, live_internal_grow_keeps_realloc_and_hard_errors (fuses-Ok-then-would-trap) fails. If the drop misfired, a verdict-branch negative fails. If the match broadened, tight_match_preserves_realloc_lookalike_export fails.

Refs #298, #299, SR-50, SYS-8, LS-D-3.

🤖 Generated with Claude Code

@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 14, 2026
@avrabe

avrabe commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

Mythos discover pass — done, two findings fixed in this PR

Adversarial pass on the export-drop + grow-defer wiring. Cleared: gating (defer flag only consulted under address_rebasing, which the drop already requires; the resource re-rewrite pass hardcodes address_rebasing:false), verdict boundary reasoning (type_contains_pointers covers string/list params+results), and the shared-vs-multimemory dedup namespaces.

FINDING 1 (HIGH) — fixed. The defer_grow_under_rebase flag was module-wide, but cabi_realloc_drop_provably_safe only proves the boundary needs no realloc — NOT that the allocator is dead. A scalar-interface component that allocates internally (Vec/Stringdlmalloc/sbrkmemory.grow, reachable from a live export) would fuse-Ok then trap at runtime — a compile error silently downgraded to a runtime trap. Fixed with a call-graph reachability probe (memory_probe::module_has_reachable_memory_grow) ANDed into the gate via allocator_grow_is_dead(): roots = live exports minus the dropped cabi_realloc* + start + ref.func/elem targets; edges = call/return_call; fail-safe true (assume live) on any parse error. The drop/defer now fires only when every memory.grow is unreachable except via the dropped allocator. Regression test live_internal_grow_keeps_realloc_and_hard_errors.

FINDING 2 (LOW) — fixed. starts_with("cabi_realloc$") could drop a legitimately-named export; tightened to cabi_realloc$ + non-empty ASCII digits (is_vestigial_realloc_export_name). Test tight_match_preserves_realloc_lookalike_export.

11 new memory_probe unit tests cover transitive dlmalloc/sbrk reachability (live and dead-under-realloc), elem/start roots, suffixed/lookalike realloc, and malformed fail-safe. 467 lib + 7 integration green; clippy + fmt clean. mythos-pass-done.

@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/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

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown

Mythos delta-pass (auto)

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

File Verdict Hypothesis
meld-core/src/merger.rs ❌ FINDING with_defer_grow_under_rebase is declared pub, so any external meld-core consumer (including the existing fuzzer fuzz_merger_idempotent.rs) can call it with true without running allocator_grow_is_dead(); the assignment at line 1995 then propagates defer_grow_under_rebase = true into every module's IndexMaps, and the rewriter silently replaces every live memory.grow with unreachable, converting a fuse-time hard error into a runtime trap and violating the semantic-preservation invariant.

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 and others added 2 commits July 15, 2026 05:14
…ised

Plan for #298 (v0.41.0): when cabi_realloc_drop_provably_safe (core output, no
adapters, all lifts scalar — already computed, INERT), wire the drop: remove the
cabi_realloc* exports (allocator DCEs downstream) + defer the now-dead
memory.grow under rebasing (IndexMaps::defer_grow_under_rebase), unblocking the
lean --memory shared --address-rebase MCU fuse. Conservatism is load-bearing
(over-drop = silent marshalling corruption). derives-from SYS-8, mitigates
LS-D-3. rivet validate PASS.

Refs #298, #299, SR-50.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Wire the (previously INERT) cabi_realloc_drop_provably_safe verdict: when a
component boundary is fully internalised (core output, no adapters, all lifts
scalar) AND address rebasing is on AND the allocator is provably dead, meld
drops the cabi_realloc* exports (allocator DCEs downstream) and defers the dead
memory.grow to `unreachable`, unblocking the lean --memory shared
--address-rebase MCU fuse (SR-50). All other paths byte-identical.

Mythos discover pass (this branch) found + fixed two findings:
- FINDING 1 (HIGH): module-wide grow-defer was unsound — the boundary verdict
  proves no *marshalling* realloc is needed, NOT that the allocator is dead. A
  scalar-interface component that allocates internally (Vec/String -> dlmalloc
  -> sbrk -> memory.grow, reachable from a live export) would fuse-Ok then TRAP
  at runtime (a compile error silently downgraded to a trap). FIX: new
  memory_probe::module_has_reachable_memory_grow — a call-graph reachability
  probe (roots = exports except the dropped cabi_realloc*, start, ref.func/elem
  targets; edges = call/return_call; fail-safe true on parse error) ANDed into
  the gate via allocator_grow_is_dead(). Now only fires when NO memory.grow is
  reachable from a live non-cabi_realloc root; a live internal grow keeps
  cabi_realloc and preserves the clean hard-error.
- FINDING 2 (LOW): tightened the export match to cabi_realloc or cabi_realloc$
  + non-empty ASCII digits (was starts_with, which could drop a lookalike).

Verdict conservatism preserved (fail-safe false/keep on any uncertainty; the new
gate only ever PREVENTS a drop). Detection: exports named cabi_realloc /
cabi_realloc$<digits>. Export removal only (loom DCEs the dead code).

467 lib + 7 drop_realloc integration tests green (incl.
live_internal_grow_keeps_realloc_and_hard_errors,
tight_match_preserves_realloc_lookalike_export, and 11 memory_probe unit tests);
clippy + fmt clean.

Refs #298, #299, SR-50, SYS-8, LS-D-3.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@avrabe
avrabe force-pushed the feat/298-drop-vestigial-realloc branch from a8a8ef2 to f01f266 Compare July 15, 2026 03:15
@avrabe
avrabe merged commit 8abb688 into main Jul 15, 2026
16 of 17 checks passed
@avrabe
avrabe deleted the feat/298-drop-vestigial-realloc branch July 15, 2026 03:31
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