fix(specs): explicit wrapping arithmetic in 4 saturating-add helpers + add to zig gate - #363
Merged
Merged
Conversation
…+ add to zig gate Four specs used plain '+'/'-' inside the classic wrap-detect saturating idiom (let sum = a + b; if (sum < a) return MAX;) and inside a counter-delta (t_end - t_start). C and Verilog wrap unsigned overflow silently, so the overflow check works and both backends pass -- but zig-safe arithmetic PANICS on the intermediate overflow before the guard runs, which is exactly why these four sat only in the C+Verilog gates. Switch those sites to the wrapping operators '+%'/'-%', which is a no-op for the C and Verilog backends (they already wrap by width) and makes the intent explicit for Zig: tri_compute_account : bal_add_sat, escrow_add_sat, outstanding_after_escrow tri_compute_pool : pool_after_deposit, balance_after_pool_settle tri_compute_bond : balance_after_resolve twr_timestamp : elapsed (wrapping counter delta) All four now pass under zig test (21/21, 13/13, 8/8, 6/6) with icarus and C still green. Committed their gen/zig and added them to the Zig drift diff. gen/c is byte-identical (the wrapping op lowers to plain +/- in C), so the C gates are unaffected. tri_settle is NOT included: it has a separate blocker -- reward_weighted does a u64->u32 narrowing cast that gen-zig lowers to a checked @intcast (panics on 2^32) instead of a truncating @truncate. That is a gen-zig codegen fix, tracked for a compiler wave. gen/zig files are a legitimate regeneration (no-gen-edits escape, LEFTHOOK=0); ascii-only (.rs/.t27/.v) verified on the specs manually. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
gHashTag
added a commit
that referenced
this pull request
Aug 9, 2026
…both (#373) The zig-test gate compiles and RUNS committed gens -- it is a real execution gate, not just a drift diff -- but it still iterated a hand-maintained list while gen/zig became the SSOT for drift in #365. The list had drifted: six specs had committed, drift-checked gens that were NEVER EXECUTED here -- rti_security, tri_compute_account, tri_compute_bond, tri_compute_pool, tri_settle, twr_timestamp precisely the specs closed in the execution-orphan series (#361, #363, #368). Their gens were verified locally at the time; CI never ran them. Iterate gen/zig directly, so a newly committed gen auto-joins execution the same way it auto-joins drift. Verified locally over the FULL committed set: zig test 107/107, zero failures. Also applies the #372 coverage-floor pattern to both execution gates (zig 107, C 75). A loop that silently matched zero files previously reported green having executed NOTHING; now it fails loudly. C-exec was already dynamic (#365) but had no floor. The stale 'gated to the passing set / tracked in t27#1928' header is corrected: the saturation idiom it referred to is fixed in-spec via '+%', and the whole committed set passes. Verified: zig 107/107 executed, C 75/75 executed, both exit 0; a zero-match loop correctly trips the floor. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: SSD DDD <ssdm4@MacBook-Pro.local>
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.
Four execution-orphan specs (from the wave-52/53 audit) used plain
+/-inside the classic wrap-detect saturating idiom (let sum = a + b; if (sum < a) return MAX;) and a counter delta (t_end - t_start). C and Verilog wrap unsigned overflow silently — so the overflow check works and both pass — but zig-safe arithmetic panics on the intermediate overflow before the guard runs. That is exactly why these 4 sat in the C+Verilog gates only.Switching those sites to the wrapping operators
+%/-%is a no-op for C and Verilog (they already wrap by width) and makes the intent explicit for Zig:All four now pass
zig test(21/21, 13/13, 8/8, 6/6) with icarus and C still green. Committed their gen/zig and added them to the Zig drift diff. gen/c is byte-identical (the wrapping op lowers to plain+/-in C), so the C gates are unaffected.tri_settleis NOT included: it has a separate blocker —reward_weighteddoes au64 -> u32narrowing cast that gen-zig lowers to a checked@intCast(panics on 2^32) instead of a truncating@truncate. That's a gen-zig codegen fix, tracked for a compiler wave.gen/zig files are a legitimate regeneration committed via the
no-gen-editsescape (LEFTHOOK=0); ascii-only (.rs/.t27/.v) verified manually.🤖 Generated with Claude Code