Skip to content

gc-stress gate is dark on main: #6925 left its gap file unregistered, and regressed repsel_ptr_shape_locals under PERRY_PTR_SHAPE_LOCALS=0 #6976

Description

@proggeramlug

Two problems, both from #6925 (perf(codegen): repsel Phase 5a — Ptr<Shape> proven this in methods, merged as 1a533a3a8). The second one hid the first.

1. The Phase 5a gap file was never registered, which breaks the whole matrix gate

#6925 added test-files/test_gap_repsel_proven_this_frozen.ts but did not add it to test-parity/gc_repsel_corpus.txt. That is the omission the manifest exists to catch, and scripts/gc_repsel_matrix.sh enforces it by exiting 3 before running anything:

UNREGISTERED test-files/test_gap_repsel_proven_this_frozen.ts is a representation-selection gap file but is not in test-parity/gc_repsel_corpus.txt
A NEW REPRESENTATION MUST REGISTER ITS GAP FILE in test-parity/gc_repsel_corpus.txt.

So gc-stress has been failing on main for every PR since #6925 merged — and because the script bails up front, it reported the registration error rather than running the corpus. The gate has been dark, not green.

(Registration is one line; it is included in #6975 so the gate starts running again.)

2. Phase 5a regressed its own OFF arm: repsel_ptr_shape_locals × rep_ptr_shape_off

With the gate running again, a genuine red cell appears — and it is Phase 5a's own escape hatch:

arm rep_ptr_shape_off   (compile: PERRY_PTR_SHAPE_LOCALS=0
                         run:     PERRY_GC_HEAP_LIMIT=8 PERRY_GC_FORCE_EVACUATE=1)
FAIL test_gap_repsel_ptr_shape_locals (exit=1 cycles=0 moved=0)
$ PERRY_PTR_SHAPE_LOCALS=0 perry test-files/test_gap_repsel_ptr_shape_locals.ts -o ps
$ PERRY_GC_HEAP_LIMIT=8 PERRY_GC_FORCE_EVACUATE=1 ./ps
...
TypeError: Cannot read properties of undefined (reading 'area')
    at <anonymous>

The program dies partway: the last five lines of expected output are missing.

  p5a-counter:2001.5:number
  p5a-chain:12500|0.08|0.24,0.32,0.08
  p5a-leak:99:true:2
  p5a-closure:20:20
  p5a-static:25:18:11

Bisect (all --profile perry-dev, macOS arm64, pinned Node 26.5.0)

commit result
8327ced52 (parent of #6925) rc=0, full output
1a533a3a8 (#6925) rc=1, TypeError … reading 'area'
760db2fd8 (current main) rc=1, identical

So it is #6925, and it is not #6972 — a full --arms all run on the #6972 branch (based on 8327ced52) was 361/361 byte-exact with FAIL=0, which included this exact cell.

Why this shape matters

PERRY_PTR_SHAPE_LOCALS=0 is the documented escape hatch for the Phase 3b / 5a representation. An arm that turns a representation off should be the safest configuration in the matrix; if the compiler only works with the optimization enabled, the escape hatch is not a bisection tool any more. The reading 'area' shape suggests a proven-this clone (or its dispatch) is still being selected, or a guard-free path is still being taken, when the gate says it should not be — i.e. the Phase 5a eligibility decision and the PERRY_PTR_SHAPE_LOCALS gate are not reading the same switch.

Triage note

#6975 registers the corpus file (so the gate runs at all) and adds a triage entry for this cell pointing at this issue, so the table is honest rather than dark. Please retriage/remove that entry once this is fixed — it is not meant to be permanent.

Related: #6954 (the matrix + its enforcement point), #6950, #6951.

Activity

  1. proggeramlug commented on Jul 29, 2026

    @proggeramlug
    ContributorAuthor

    Cross-ref: the second half of this issue (the PERRY_PTR_SHAPE_LOCALS=0 TypeError) is now tracked as #6984, filed independently by a concurrent investigation that bisected it to the same commit. Suggest this issue stays focused on the gate failure mode — unregistered corpus file ⇒ gc_repsel_matrix.sh exits 3 before evaluating any cell ⇒ gc-stress reports a registration error rather than running the corpus ⇒ continue-on-error: true (.github/workflows/test.yml:760) swallows it entirely.

    That combination is the more durable problem: it is why the regression survived three merges. Removing continue-on-error is the smallest fix that makes the next unregistered file loud instead of dark.

  2. proggeramlug commented on Aug 2, 2026

    @proggeramlug
    ContributorAuthor

    Re-verified on main = d4ac65f21 in the sweep #7262. Item 2 still reproduces; item 1 appears addressed.

    Item 1 (unregistered gap file). test_gap_repsel_proven_this_frozen.ts is now present in test-parity/gc_repsel_corpus.txt, so gc_repsel_matrix.sh no longer exits 3 before running anything. Fixed by #6975 as this issue anticipated.

    Item 2 (Phase 5a regressed its own OFF arm) — unchanged:

    PERRY_PTR_SHAPE_LOCALS=0 perry test-files/test_gap_repsel_ptr_shape_locals.ts -o ps
    ./ps
    → TypeError: Cannot read properties of undefined (reading 'area')   rc=1
    

    The last four lines of expected output are missing, exactly as reported. Full evidence on #6984, which is the same defect tracked separately.

    One thing this issue should know about its own subject. The gate it is about has had a further, independent darkness problem since: gc-stress reported skipped on 12/12 nightly main runs until #7253 fixed its if: two hours before this sweep. So between #6975 registering the file and #7253 fixing the trigger, the gate still was not running — item 1 was necessary but not sufficient.

    And per #7255, four of the six arms gc-stress runs on a PR currently execute zero copying minors corpus-wide, so even now the job cannot observe the relocating-minor class it was built for. rep_ptr_shape_off — this issue's own red cell — is not among the PR arms in the first place.

  3. proggeramlug commented on Aug 9, 2026

    @proggeramlug
    ContributorAuthor

    Closing — one item is fixed and the other is a duplicate, so there is nothing left that is uniquely this issue's.

    Item 1 (the dark gate — #6925 left its gap file unregistered) is fixed by #6975. The registration check now covers it.

    Item 2 (PERRY_PTR_SHAPE_LOCALS=0 regressing repsel_ptr_shape_locals) is the same defect as #6984, which describes it in more detail and was still reproducing at its last check. Tracking one defect in two places splits the evidence and guarantees one of them goes stale, so: #6984 is canonical, work continues there.

    Worth carrying forward to #6984, since it is the more useful half of this issue: the front-door eligibility gate is correctly wired, which means the root cause is most likely in the Phase 3b provenance logic not respecting the kill switch — not in the gate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions