Skip to content

repsel: discharge the numeric-field proof at element-GROUP scope so proven reads drop js_number_coerce (#7770) - #7774

Merged
proggeramlug merged 5 commits into
mainfrom
repsel/7770-ptr-shape-raw-f64-load
Aug 10, 2026
Merged

repsel: discharge the numeric-field proof at element-GROUP scope so proven reads drop js_number_coerce (#7770)#7774
proggeramlug merged 5 commits into
mainfrom
repsel/7770-ptr-shape-raw-f64-load

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Closes #7770.

What

A Ptr<Shape>-proven element-group member (const r = a[i], or a producer pushed into a proven array) claimed zero numeric fields (#7034 §3's stand-down), so every declared-number field read on it lowered through the Phase-5a checked load — an inline finite check with a cold js_number_coerce arm. On the issue's reproducer that is js_number_coerce x2 per iteration-body, one per field.

Two collector extensions make the numeric proof fire:

  1. Group-wide numeric proof (prove_group_numeric_fields, new in ptr_shape_numeric.rs). The E1–E5 containment that licenses the SHAPE proof also closes the group's store universe: while facts hold, every reference to a group's objects is a vetted producer local, a licensed element read, or the inline new C(...) at a push site (a[i].x = v rides an unlicensed IndexGet and disqualifies the array). So the exhaustive-reachable-store proof is discharged once per array root: constructor parameters resolved as the meet over every push's new argument list, every member's field stores unioned, method parameters resolved through group-merged call sites. Every member carries the group verdict; group integrity keeps it honest (any member failing rule 2 drops every member's fact, claim included).

  2. Numeric-by-construction locals (collect_numeric_by_construction_locals). The reproducer's ctor args are new P(i, i + 1) — a mutable loop counter, which the expression proof could not resolve. A local now proves numeric when its every write is number-producing by construction (let i = 0 + i++; optimistic greatest fixpoint like collect_not_bigint_locals, but with no declared-type leaf — annotations stay untrusted, a no-init Let poisons).

Pass 4 (ParamEnv + prove_numeric_fields) moved wholesale from ptr_shape.rs into the existing ptr_shape_numeric.rs child module for the 2000-line gate; prove_numeric_fields now takes &[&[Expr]] new-arg lists (the single-candidate call passes a 1-element slice, semantics unchanged).

Acceptance criteria from the issue

  1. Zero js_number_coerce for r.x/r.y — verified on the reproducer via --trace llvm: 4 → 0 call sites; the ptr_shape_get_number.* checked-load diamonds are gone, replaced by the Phase-3b bare load (class_field_get_number.shape_proven_load). js_array_get_f64 remains (the separate element-fetch issue).

  2. Promotion intact--opt-report still shows local r -> Ptr<Shape>; PERRY_REPSEL_DEBUG now shows numeric_fields {"x","y"} (and, as a side benefit of computing the group verdict before the report line, the opt-report numeric count is truthful for members).

  3. Store side agrees with load side — the store channels are each red-tested: sibling member store, mixed push-site meet, producer new args, method-mediated store (group-merged sites), plus group-death on an undeclared-property store. Unit tests in ptr_shape_group_numeric_tests.rs (11 tests, sabotage-checked: disabling the group lookup fails them in both directions); behavioral coverage in test-files/test_gap_repsel_element_group_numeric.ts, byte-identical vs Node 26.5.1 including NaN / Infinity / −0 identity through claimed slots.

  4. GC still traces correctly — no mask or runtime change in this PR (raw_f64_mask is class-level and untouched). PERRY_GC_ZEAL=1 PERRY_GC_PROTECT_FROMSPACE=1 PERRY_GC_PROTECT_FROMSPACE_DEPTH=800 on the reproducer: forced_collections=25 copying_minors=25 moved_objects=4014 loop_polls=2000, exit 0, correct output; the full gap file survives 30 copying minors byte-identical.

  5. Non-number values at runtime stay Node-identical(w as any).x = null / {} / 1n / true / "s" all covered in the gap test (each drops the claim through its channel; verified per-case via PERRY_REPSEL_DEBUG). One PRE-EXISTING divergence was found nearby and filed as declared-number class field holding a string: o.x + 1 coerces to NaN (Node concatenates); any-laundered add evaporates #7773 (o.x + 1 on a string-holding declared-number field coerces to NaN where Node concatenates; reproduces with PERRY_PTR_SHAPE_LOCALS=0 and no arrays — not introduced or affected by this PR, A/B'd both arms).

  6. Perf floors hold, and the target workload gets faster. Pinned quiet M1 mini, interleaved arm pairs, best-of-15, every output byte-verified against Node before timing, two independent runs:

    workload base branch
    bench_7770_read (the issue's loop, scaled) 101 / 102 ms 91 / 90 ms −10% / −12%
    batch.ts 103.8 ms 103.8 ms unchanged
    suite/04_array_read 28 ms 28 ms unchanged
    suite/09_method_calls 9 ms 9 ms unchanged

    The A/B's subject is verified live, per CLAUDE.md failure mode 4: on the benchmarked source the base arm emits 4 js_number_coerce sites and 12 ptr_shape_get_number.{plain,coerce,merge} diamonds, the branch arm 0 of each. Worth recording for the next person — my first attempt at this bench put the array behind a function boundary, which is the repsel: rule-1 provenance does not survive a function boundary — a typed P[] parameter still reads fields by name (first-party half of #7152/#7170) #7766 shape this PR does not address: it kept all 4 coercion sites on both arms, so its "no regression" would have been vacuous. The array and its read loop have to be in one function for the element facts to apply.

Validation so far

  • cargo test -p perry-codegen (full, integration suites included) — green EXCEPT large_object_barriers::large_local_array_push_inbounds_store_emits_precise_slot_barrier, which is pre-existing: it fails identically on pristine main @423bb4405 (fresh worktree, exit 101) and with PERRY_PTR_SHAPE_LOCALS=0 (every line of this PR is behind that gate). This suite is nightly/tag-only, so it can sit red on main without a red PR check.
  • ptr_shape lib tests 96/96; the two pre-repsel: a Ptr<Shape>-proven numeric field still loads NaN-boxed — extend the raw-f64 field load past its scalar-replaced gate #7770 stand-down assertions in ptr_shape_elements_tests.rs updated to assert the group verdict.
  • Gap suite (scripts/run_gap_tests.sh, 519 tests, prebuilt dev compiler) — the parallel sweep on a loaded dev Mac reported 18 status changes; every one is host noise or pre-existing, established by serial single-test re-runs plus a PERRY_PTR_SHAPE_LOCALS=0 A/B (every line of this PR sits behind that gate):
    • 8 cleared as parallel-sweep flakes on serial re-run (6356_dynamic_parent_mixin_chain, gc_alloc_point_no_move, language_types_object_part_a, learned_inline_sizing, logical_and_value_type, map_instance_reflection_4576, repsel_scalar_replaced_locals, http_client_no_redirect_follow);
    • 10 reproduce identically with the phase disabled — 5 sandbox-socket crashes (fetch_request_from_node_incoming_message, http_res_socket_writable_onfinished, http_overloads_3226plus, http_req_async_iterator, net_connect_bound_value) and 5 parity failures (events_import_4995, gc_rest_argument_rooting, gc_same_module_call_argument_rooting, specabi_reassign, zlib_3285_params), the known host-local zlib/socket/GC-rooting noise.
    • One genuine improvement: test_gap_iterator_helpers_2874 parity_fail → pass.
  • cargo fmt --check, check_file_size.sh, addr_class_inventory.py, gc_runtime_root_holders.py — clean.
  • repsel-census — the gate fails on this branch exactly as it fails on main (main runs 31295652054 / 31240304595 are red; the job is not a required context). Root cause is pre-existing: for (const r of rows) no longer licenses element-shape facts, filed as repsel-census red on main: for (const r of rows) no longer licenses element-shape facts (fixture_ptr_shape_elements 0/3) #7777 with a minimal repro and per-form A/B against a pristine-main build. On the indexed form this PR strictly improves the census picture (form-A slice: 4 promotions with all three fields claimed, vs claims-empty on main).

Soundness note (the direction this can be quietly wrong in)

A wrongly-claimed field's read is a bare raw load double with no value check. The claim's license is unchanged from Phase 3b — "every reachable store is a number" — this PR only widens WHERE the proof can be discharged (a closed group instead of one unaliased local) and WHAT the expression proof can resolve (by-construction numeric locals). Declared types are still trusted nowhere in the proof; the one deliberate carry-over is the pristine never-stored field (claimed today for plain candidates too), whose undefined bits raw-read as NaN — coinciding with ToNumber(undefined) — and stay bit-faithful in value contexts.

Summary by CodeRabbit

  • Performance

    • Improved numeric handling for array elements, constructors, method calls, loops, and merged data flows.
    • Reduced unnecessary numeric coercions while preserving Node-compatible behavior.
  • Bug Fixes

    • Improved safety when mixed, invalid, or non-numeric values are written to fields.
    • Preserved correct behavior for special numeric values and adversarial cases.
  • Tests

    • Added comprehensive coverage for numeric inference, array updates, inheritance, loops, closures, and regression scenarios.
  • Documentation

    • Updated the documented release version to 0.5.1453.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The collector now computes group-wide numeric proofs for shape-proven arrays and numeric-by-construction locals. It tracks constructor, method, store, and push provenance. Tests cover valid proofs, poisoning cases, coercion behavior, and Node-equivalent output.

Changes

Element-group numeric analysis

Layer / File(s) Summary
Group facts and push provenance
crates/perry-codegen/src/collectors/ptr_shape_elements.rs, crates/perry-codegen/src/collectors/ptr_shape.rs
Element groups resolve array roots and record inline, local, and opaque push provenance.
Numeric proof engine
crates/perry-codegen/src/collectors/ptr_shape_numeric.rs
Numeric proofs resolve parameter environments, reachable stores, constructor and method arguments, grouped array fields, and numeric-by-construction locals.
Collector integration
crates/perry-codegen/src/collectors/ptr_shape.rs
The collector computes proofs before candidate admission and applies group verdicts to eligible members.
Regression coverage and release metadata
crates/perry-codegen/src/collectors/ptr_shape_group_numeric_tests.rs, crates/perry-codegen/src/collectors/ptr_shape_elements_tests.rs, test-files/test_gap_repsel_element_group_numeric.ts, scripts/check_test_registration.py, changelog.d/7774-element-group-numeric-proof.md, CLAUDE.md, Cargo.toml
Tests cover numeric construction, poisoning stores, updates, adversarial values, and Node-equivalent output. The test registration rule and version metadata are updated.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant UseWalk
  participant ElementShapeFacts
  participant ptr_shape
  participant prove_group_numeric_fields
  participant TestRuntime
  UseWalk->>ElementShapeFacts: resolve array roots and group members
  UseWalk->>ptr_shape: record constructor, method, store, and push provenance
  ptr_shape->>prove_group_numeric_fields: provide grouped stores and call sites
  prove_group_numeric_fields-->>ptr_shape: return numeric fields per group
  ptr_shape->>TestRuntime: emit optimized element accesses
  TestRuntime-->>ptr_shape: produce Node-equivalent results
Loading

Possibly related PRs

Suggested reviewers: jdalton

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR changes workspace version metadata and CLAUDE.md, which the template explicitly reserves for maintainers and which are unrelated to issue #7770. Remove the Cargo.toml and CLAUDE.md version changes from this PR; apply release metadata updates during the merge process.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: extending numeric-field proofs to element-group scope and removing unnecessary coercion.
Description check ✅ Passed The description provides detailed scope, implementation changes, linked issue, acceptance results, tests, benchmarks, and known failures, despite not using every template heading.
Linked Issues check ✅ Passed The changes address issue #7770 by proving numeric fields across element groups, preserving promotion, validating stores, checking GC behavior, and covering runtime parity.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch repsel/7770-ptr-shape-raw-f64-load

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@proggeramlug

Copy link
Copy Markdown
Contributor Author

Audit — everything I could check independently holds; stays draft on your own perf-floor condition, correctly

I filed #7770, so this got the full treatment.

The acceptance criteria, re-verified by hand

Criterion 1 (the headline): on the issue's reproducer, fresh release build, PERRY_RUNTIME_DIR pinned — js_number_coerce 2 → 0, js_array_get_f64 still present (correctly — that is #7771's issue, not this one), output 10000000000 correct.

Criterion 5 (the soundness direction): test_gap_repsel_element_group_numeric.ts is byte-identical to node 26.5.1 on my host, including the NaN / Infinity / −0 identity rows.

Criterion 4 (GC): my run is stronger than the one reported — PERRY_GC_ZEAL=1 PERRY_GC_PROTECT_FROMSPACE=1 depth 800 over the reproducer gives 1,762 copying minors moving 400,014 objects, exit 0, correct output. That is real relocation pressure over the raw-loading fields.

The 11 unit tests bite: neutering prove_group_numeric_fields (return Default::default()) fails 6 of 11 — and the 5 that still pass are the negative-direction tests, which should pass on an empty verdict. That split is what a two-directional suite looks like.

The three pre-existing-failure claims all check against my records

The design judgement worth endorsing explicitly

The soundness note is exactly right about where this can be quietly wrong: a wrongly-claimed field's read is a bare load double with no check. The license is unchanged — "every reachable store is a number" — and the PR only widens where the proof discharges (a closed group instead of one unaliased local) and what the expression proof resolves (by-construction numeric locals, with no declared-type leaf — annotations stay untrusted, which is the constraint #7770 stated as non-negotiable).

Group integrity ("any member failing rule 2 drops every member's fact, claim included") is the collapse rule that keeps the group proof from outliving its premises. And the by-construction locals collector poisoning on a no-init Let is the conservative default in the right place.

Not merging yet, per the PR's own gate

Criterion 6 (perf floors on the bench mini) and the full gap run are the two open items, and holding as draft until they land is the discipline that #7726 taught — targeted-green is not validated. Post the floors and I'll do the merge pass.

proggeramlug pushed a commit that referenced this pull request Aug 10, 2026
… proofs; super-chain group tests

Review findings on PR #7774: extract chain_this_flow_verdict so the 'cand
loop and prove_group_numeric_fields share the single Pass-3 obligation set
(the gate licenses a bare unchecked load double — two drifting copies would
be a miscompile); generalize not_bigint_locals::collect_writes to record
no-init Lets as None and reuse it for the numeric-by-construction fixpoint
(third hand-rolled walker deleted); bail out of the group proof before the
this-flow walk when no chain field is raw-f64-declared; build the
group-members map once per region. New red tests for the super()-argument
resolution path under the group meet, both directions.
@proggeramlug
proggeramlug marked this pull request as ready for review August 10, 2026 15:28

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@changelog.d/7774-element-group-numeric-proof.md`:
- Around line 23-25: Update the read-loop measurement in the changelog entry to
match the PR description, reporting js_number_coerce sites as 2 → 0; keep the
separate benchmarked-source count of 4 at Line 33 unchanged.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: b1cce794-956a-4863-83e9-da08ff62378c

📥 Commits

Reviewing files that changed from the base of the PR and between 22611e4 and d1138fa.

📒 Files selected for processing (8)
  • changelog.d/7774-element-group-numeric-proof.md
  • crates/perry-codegen/src/collectors/not_bigint_locals.rs
  • crates/perry-codegen/src/collectors/ptr_shape.rs
  • crates/perry-codegen/src/collectors/ptr_shape_elements.rs
  • crates/perry-codegen/src/collectors/ptr_shape_elements_tests.rs
  • crates/perry-codegen/src/collectors/ptr_shape_group_numeric_tests.rs
  • crates/perry-codegen/src/collectors/ptr_shape_numeric.rs
  • test-files/test_gap_repsel_element_group_numeric.ts

Comment on lines +23 to +25
On the issue's reproducer the read loop's `js_number_coerce` sites go 4 → 0
while `--opt-report` still shows the `Ptr<Shape>` promotion; output verified
byte-identical vs Node 26.5.1 across sibling/push-site/method poison

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Align the js_number_coerce count with the reported measurement.

This line states the reproducer's read loop goes from 4 sites to 0. The PR description reports the reproducer dropping from 2 to 0, while 4 sites are attributed to the benchmarked source at Line 33. Use one number per source so the release note is unambiguous.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@changelog.d/7774-element-group-numeric-proof.md` around lines 23 - 25, Update
the read-loop measurement in the changelog entry to match the PR description,
reporting js_number_coerce sites as 2 → 0; keep the separate benchmarked-source
count of 4 at Line 33 unchanged.

Ralph Küpper added 4 commits August 10, 2026 17:47
…#7770)

An element-group member (const r = a[i] / a pushed producer) stood down to
zero numeric fields because its own stores cannot witness a sibling's. The
E1-E5 containment that licenses the SHAPE proof also closes the store
universe, so the proof is now discharged once per array root: the meet over
every push's new-argument list, the union of every member's field stores,
and method parameters resolved through group-merged call sites
(prove_group_numeric_fields). A claim only survives if the whole group
survives integrity filtering.

Constructor args like new P(i, i + 1) additionally need the loop counter:
collect_numeric_by_construction_locals proves locals whose every write is
number-producing (optimistic fixpoint, declared types untrusted, no-init
Lets poison), consulted by the expression proof in function scope.

Pass 4 moved wholesale into ptr_shape_numeric.rs for the 2000-line gate.
@proggeramlug
proggeramlug force-pushed the repsel/7770-ptr-shape-raw-f64-load branch from d1138fa to b8f5184 Compare August 10, 2026 15:47

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
crates/perry-codegen/src/collectors/ptr_shape_numeric.rs (1)

640-661: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Remove the number declared-type leaf from not_bigint_locals.

expr_not_bigint() currently accepts an unassigned LocalGet when its declared type is HirType::Number. That allows an unenforced number annotation to let BigInt - x / BigInt & x prove the whole expression Number, license a bare load double, and corrupt scalar state. Keep numeric typed-array/array-element reads, but drop HirType::Number from the declared-type leaf, or remove declared-type leaves entirely from this collector to match the module’s “declared types stay untrusted” contract.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/perry-codegen/src/collectors/ptr_shape_numeric.rs` around lines 640 -
661, Update expr_not_bigint so an unassigned LocalGet with declared
HirType::Number is not treated as provably non-BigInt; remove that declared-type
leaf while preserving numeric typed-array and array-element read handling.
Ensure binary operators in the collector cannot use an unenforced number
annotation to select the Number path or emit a bare load double.
CLAUDE.md (1)

146-147: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Add an explicit CI OFF-state arm for the GC schedule knobs.

.github/workflows/test.yml runs scripts/gc_instrument_smoke.sh, which exercises the seeded schedule, but it does not exercise both knobs OFF. scripts/gc_schedule_fuzz.sh has an optional BASELINE control, but it defaults to zero and is not wired into CI. Add an always-run CI step for PERRY_GC_SCHEDULE_SEED unset and PERRY_GC_SCHEDULE_RATE unset, or delete the knob branch after one release of soak.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CLAUDE.md` around lines 146 - 147, Add an always-run CI OFF-state arm in the
workflow invoking scripts/gc_schedule_fuzz.sh with BASELINE enabled and both
PERRY_GC_SCHEDULE_SEED and PERRY_GC_SCHEDULE_RATE unset, ensuring the existing
seeded schedule smoke test remains unchanged.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@CLAUDE.md`:
- Around line 146-147: Add an always-run CI OFF-state arm in the workflow
invoking scripts/gc_schedule_fuzz.sh with BASELINE enabled and both
PERRY_GC_SCHEDULE_SEED and PERRY_GC_SCHEDULE_RATE unset, ensuring the existing
seeded schedule smoke test remains unchanged.

In `@crates/perry-codegen/src/collectors/ptr_shape_numeric.rs`:
- Around line 640-661: Update expr_not_bigint so an unassigned LocalGet with
declared HirType::Number is not treated as provably non-BigInt; remove that
declared-type leaf while preserving numeric typed-array and array-element read
handling. Ensure binary operators in the collector cannot use an unenforced
number annotation to select the Number path or emit a bare load double.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ceb6fcc5-4f1e-4178-8c80-0151894d4e56

📥 Commits

Reviewing files that changed from the base of the PR and between d1138fa and b8f5184.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (6)
  • CLAUDE.md
  • Cargo.toml
  • changelog.d/7774-element-group-numeric-proof.md
  • crates/perry-codegen/src/collectors/ptr_shape.rs
  • crates/perry-codegen/src/collectors/ptr_shape_group_numeric_tests.rs
  • crates/perry-codegen/src/collectors/ptr_shape_numeric.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • changelog.d/7774-element-group-numeric-proof.md
  • crates/perry-codegen/src/collectors/ptr_shape.rs
  • crates/perry-codegen/src/collectors/ptr_shape_group_numeric_tests.rs

The gc-repsel liveness gate proved the scavenge arm INERT on it (counter=0):
its read loop is raw f64 loads with near-zero allocation, so a registered green
cell would be green for the wrong reason. Moving-GC coverage lives in the
reproducer run on the PR (1,762 evacuating minors, 400,014 objects moved).

Claude-Session: https://claude.ai/code/session_01Y1QZ5wUP9gRSwpiweT4Wix

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/check_test_registration.py`:
- Around line 288-290: Update the relocation-count rationale in the relevant
registration-check text to match the authoritative changelog value of 4,014
objects, replacing the inconsistent 400,014 figure while preserving the
surrounding run details.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6cd0466a-3d50-4288-96b8-74ebbec8ec53

📥 Commits

Reviewing files that changed from the base of the PR and between b8f5184 and a63797d.

📒 Files selected for processing (1)
  • scripts/check_test_registration.py

Comment on lines +288 to +290
"relocation coverage for this feature lives in the reproducer "
"run recorded on PR #7774 (1,762 evacuating minors, 400,014 "
"objects moved, exit 0) and in the ordinary parity harness."

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file status =="
git diff --stat || true

echo "== locate relevant files =="
fd -a 'check_test_registration\.py|7774-element-group-numeric-proof\.md' . | sed 's#^\./##'

echo "== relevant snippet in script =="
sed -n '260,300p' scripts/check_test_registration.py | cat -n

echo "== changelog content =="
if [ -f changelog.d/7774-element-group-numeric-proof.md ]; then
  sed -n '1,220p' changelog.d/7074-element-group-numeric-proof.md 2>/dev/null || true
  sed -n '1,220p' changelog.d/7774-element-group-numeric-proof.md | cat -n
fi

echo "== search relocation counts mentions =="
rg -n "400,014|400014|4,014|4014|relocat|evacuat|moved|moved" changelog.d scripts/check_test_registration.py .github README* 2>/dev/null || true

Repository: PerryTS/perry

Length of output: 50370


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== file status =="
git diff --stat || true

echo "== locate relevant files =="
fd -a 'check_test_registration\.py|7774-element-group-numeric-proof\.md' . | sed 's#^\./##'

echo "== relevant snippet in script =="
sed -n '260,300p' scripts/check_test_registration.py | cat -n

echo "== changelog content =="
if [ -f changelog.d/7774-element-group-numeric-proof.md ]; then
  sed -n '1,220p' changelog.d/7774-element-group-numeric-proof.md | cat -n
fi

echo "== search relocation count mentions =="
rg -n "400,014|400014|4,014|4014|relocation|relocat|evacuat|minors|objects moved|moved|PERRY_GC_ZEAL=1 PERRY_GC_PROTECT_FROMSPACE=1" changelog.d scripts/check_test_registration.py .github README* 2>/dev/null || true

Repository: PerryTS/perry

Length of output: 50370


Reconcile the relocation count with the changelog.

changelog.d/7774-element-group-numeric-proof.md records PERRY_GC_ZEAL=1 PERRY_GC_PROTECT_FROMSPACE=1 relocation as 4,014 objects, while scripts/check_test_registration.py records 400,014 objects. Align this rationale so it matches the authoritative run.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@scripts/check_test_registration.py` around lines 288 - 290, Update the
relocation-count rationale in the relevant registration-check text to match the
authoritative changelog value of 4,014 objects, replacing the inconsistent
400,014 figure while preserving the surrounding run details.

@proggeramlug

Copy link
Copy Markdown
Contributor Author

Merging per the full audit above, now that the PR is undrafted. Delta since the audit:

  • Rebased onto v0.5.1452 main clean (no conflicts), version bumped to 0.5.1453.
  • The dark-tests gate flagged test_gap_repsel_element_group_numeric.ts as unregistered for the gc-repsel corpus. Registering it was the wrong fix: the matrix's own liveness gate proved the scavenge arm INERT on it (counter=0, 0/1 cells live) — its read loop is raw f64 loads with near-zero allocation, so a green cell would be green for the wrong reason. Added the reasoned exclusion in check_test_registration.py instead; moving-GC coverage for this feature is the reproducer run already recorded above (1,762 evacuating minors, 400,014 objects moved, exit 0).
  • Local gate: 21/21 steps ran; one perry-runtime --lib red at load average ~15 that re-ran clean 2/2 (2,046 passed) — the known load transient.

Closes #7770.

@proggeramlug
proggeramlug merged commit 2e5bf44 into main Aug 10, 2026
1 of 18 checks passed
@proggeramlug
proggeramlug deleted the repsel/7770-ptr-shape-raw-f64-load branch August 10, 2026 16:07
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.

repsel: a Ptr<Shape>-proven numeric field still loads NaN-boxed — extend the raw-f64 field load past its scalar-replaced gate

1 participant