feat(#396): synth-provenance-v1 branch-transformation map + reconciliation gate (VCR-DEC-003)#774
Merged
Merged
Conversation
…VCR-DEC-003) Add the object-branch-class side-table the provenance emitter needs to enumerate real object conditional branches (line_map records which wasm op an instruction came from, not whether it IS a conditional branch). Captured at the ARM encode loop alongside line_map; additive metadata, .text byte-identical. - synth-core: BranchClass enum + BranchMap type + CompiledFunction.branch_map - synth-backend/arm: classify_arm_branch + populate in the encode loop - riscv/aarch64: empty branch_map (ARM-only in v1) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
synth-core::provenance — the branch-transformation map. Per-function derivation from op stream + op_offsets + line_map + branch_map: - preserved (br_if/br), folded-predication (select), split-into-object-branches (br_table), eliminated-constant (folded/fact-spec-dropped source branch). - object_cond_branches carries clause (a): every REAL object conditional branch (from BranchMap) reconciled back to its source op; unresolved (i64/trap-guard) branches surfaced with a note, never hidden. - 3 unit tests: preserved+folded, unresolved-surfaced, eliminated-recorded. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
…(VCR-DEC-003) Wire the emitter into compile_all_exports: derive per-function provenance from the compiled op stream + line_map/branch_map, write <output>.provenance.json. Eliminated-constant entries derived from the fact-spec kept-set. Demonstrated on control_step.wasm (SYNTH_CMP_SELECT_FUSE=1): 5 Select ops -> folded-predication (object_pc = the IT-block predicated move, no branch), 2 BrIf + 1 Br -> preserved, and both real object conditional branches reconcile back to their source BrIf conditions (clause a). ELF byte-identical with/without the flag (frozen-safe). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
…C-003) Non-vacuous gate: provenance_branches_396.wat exercises br_if (preserved), select (folded-predication), br_table (split-into-object-branches) in one func. The gate parses the sidecar as an independent consumer and asserts: - (a) every REAL object conditional branch (from object_cond_branches, derived from BranchMap) resolves to a source WASM condition; - (b) the folded select is recorded folded WITH its object realization, and no object branch traces back to it (proves a real fold, not a mislabel); - split carries count + object PCs; source<->object correspondence both ways. Verified non-vacuous: mislabeling SelectMove as CondBranch turns the gate RED (the 'traces back to a folded select' assertion fires); reverted. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
- .github/workflows/ci.yml: dedicated provenance-gate job (reconciliation gate + emitter unit tests), named so a provenance regression is a visible red. - artifacts/verified-codegen-roadmap.yaml: VCR-DEC-003 proposed -> implemented; document the shipped emitter, schema, gate, and the named v1 follow-ups (optimized ir_to_arm source_line, i64/trap-guard unresolved branches, RISC-V/ AArch64 branch_map, witness#130 object-disposition compose). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
…chema Advisor-caught gaps off the gate's happy path: 1. Loud-decline: a function whose lowering dropped source_line (line_map all-None) but emitted object branches can't reconcile — warn + skip that function rather than serialize a map that lies to witness (mirrors --debug-line's warn-on-unservable-path). Frozen-safe: sidecar-only. 2. eliminated-constant join key: was hardcoded instruction_offset=0 (all eliminated entries collided at 0). Now looks up the ORIGINAL-stream byte offset from func.op_offsets[orig_idx] (unfiltered) and threads it; unit test asserts the real offset. Signature: (usize,String) -> (usize,String,u32). 3. Roadmap ledger: rivet rejects sw-integration-verification verifies-linking a sw-req directly (needs an intermediate design artifact). Dropped the VER artifact that introduced the only new non-xref ERROR; VCR-DEC-003 now carries the same coverage WARN as every sibling VCR-* sw-req (established CI-passing pattern). NON_XREF error count stays 0. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
… ir_to_arm Claim-honesty pass (advisor + repo claim-gate ethos): - eliminated-constant: move from 'covered' to 'wired in schema+emitter (correct join key) but not yet gate-exercised' — the reconciliation fixture exercises preserved/folded/split; fact-spec deletions today are pure condition slices + proven-dead if-regions, so a covered-branch-drop fixture is a v1 follow-up. - ir_to_arm: soften 'still sets source_line: None' (this fixture keeps it on both paths) to 'may drop on some op shapes; such functions are loud-declined' — what was actually verified. Roadmap + provenance.rs module doc. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
avrabe
added a commit
that referenced
this pull request
Jul 16, 2026
… WasmCert anchor + VCR-ISA 41→50, A64 7→50, 12× beat-LLVM, MC/DC provenance) (#775) Five oracle-gated lanes across semantics/capability/perf/assurance: - VCR-WASM-001 (#771): WasmCert-Coq source anchor (i32.add refinement, 474→476) - VCR-ISA-001 (#773): generate-not-mirror 41→50 ops (476→485 Qed) - #538 (#769): AArch64 milestone 2 — 7→50 integer ops, honest div/rem decline - #494 (#770): proof-carrying rem_u elision — 12× beat over clang -Os - #396 (#774): synth-provenance-v1 MC/DC source-to-object map (VCR-DEC-003) #757 stays OPEN (accepted residual — 7 reconstructions all green, needs reporter module; #772 lands them as regression guards). i64.trunc_f64 + #761 residuals noted. Claude-Session: https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
VCR-DEC-003 (#396, witness#130) —
synth-provenance-v1source-to-object branch-transformation mapsynth's lowering changes the branch structure between the WASM source and the ARM object (cmp→select fusion → IT-block predication, br_table splitting, wide-branch expansion). witness measures MC/DC on the WASM component; to certify the OBJECT it must reconcile each object-level branch/condition back to its source condition. Without a provenance map that reconciliation is impossible — the #396 / witness#130 source-to-object traceability gap. This PR ships the emitter + the non-vacuous reconciliation gate.
Deliverable
1. Emitter (
--emit-provenance) — writes asynth-provenance-v1JSON sidecar (<output>.provenance.json). Frozen-safe: the ELF is byte-identical with and without the flag (verified on control_step.wasm). Derived post-hoc at the CLI from the compiled op stream +op_offsets+ the ARMline_map+ a new object-branch side-tableBranchMap(crate::backend::BranchClass, captured at the ARM encode loop — the one datum post-hoc derivation couldn't recover: which emitted instruction IS a conditional branch vs a predicated move).2. Reconciliation gate (
provenance_reconciliation_396, CI jobprovenance-gate) — parses the sidecar as an independent consumer and asserts the two properties #396 exists to guarantee. Verified non-vacuous: mislabelingSelectMoveasCondBranchturns the gate RED.Schema
synth-provenance-v1kind ∈ preserved | folded-predication | split-into-object-branches | eliminated-constant.Fixture source→object correspondence (
provenance_branches_396.wat)br_if@47select@70br_table@81br@95object_cond_branches: all 3 real object conditional branches (0x12, 0x3c, 0x40) reconcile back to their source condition — clause (a) satisfied non-vacuously. On a real fixture (msgq_put) an uncovered trap-guard branch is surfacedresolved:falsewith a note, never hidden.Bounded v1 — named follow-ups
ir_to_armon some op shapes dropssource_line; such functions are loud-declined from the sidecar (warn + skip) rather than mislabeled.branch_map(ARM-Thumb only in v1).object-dispositionend-to-end compose.Verification
synth-core::provenance) + reconciliation gate; full workspace green (2278 tests). ELF byte-identity confirmed.rivet validatenon-xref error count unchanged (0). Roadmap VCR-DEC-003 →implemented.Coordinates conceptually with witness#130 (referenced); the map + parse-assert gate live entirely in synth.
🤖 Generated with Claude Code
https://claude.ai/code/session_01YJK5LZZEkV5smCY1jKn18L