Skip to content

Promote gc-ratchet to a required context now (precondition met); gc-stress after #8100 #8101

Description

@proggeramlug

Split out of #7737 item 4, which is closed as three-quarters done. This is the
remaining quarter, and the picture has moved twice since #7737 was filed —
in both directions — so it is worth stating the current one precisely.

What is true right now

gh api repos/PerryTS/perry/branches/main/protection --jq .required_status_checks.contexts

["lint","cargo-test","parity","compile-smoke","api-docs-drift","security-audit","conformance-smoke-complete"]

Neither gc-ratchet nor gc-stress is there. Both run, both can report red, neither
blocks a merge — CLAUDE.md's "four ways a gate can be unable to fail", hazard 2.

gc-ratchet: the precondition is now MET — promote it

CLAUDE.md's corollary is "a new gate has never been green, so promoting it to
required immediately blocks every open PR. Run it once, then promote." On
2026-08-12 that was the blocker: gc-ratchet had 0 successes in its last 30 main
runs. That is no longer the case. Its last four main runs are all green, on the
four consecutive main commits immediately preceding 0d7fe21b0:

run when (UTC+2) main sha conclusion
31766259491 2026-08-14 03:15 f9475fb9a success
31781155927 2026-08-14 07:45 78d0afa46 success
31805278312 2026-08-14 13:33 5c27d1ad9 success
31831865551 2026-08-14 19:07 506f4ab11 success

The flip is attributable: f9475fb9a is fix(gc): attribute deterministic ratchet shifts (#8069), the last touch of baseline/gc-ratchet-v1.json, and the first green
run is the one at that commit. #8051 — the attribution blocker the previous triage
named — is closed. So is #7966.

The green is not vacuous — the gate's subject ran. Run 31831865551 measured all
fourteen probes and ended gc-ratchet: OK; e.g.

14_grow_then_churn: correctness=pass heap_used_bytes=0% heap_total_bytes=0% rss_bytes=0.075594% peak_rss_bytes=0.080871% wall_ms=17.099233%
12_large_live_set:  correctness=pass heap_used_bytes=0% heap_total_bytes=0% rss_bytes=0.8705%   peak_rss_bytes=0.857633% wall_ms=19.992527%

12_large_live_set's heap_used_bytes / heap_total_bytes cells are the exact cells
#7737 said were advisory-only, and they are gating rows with a 0% delta today.

Admin action, once:

gh api -X PATCH repos/PerryTS/perry/branches/main/protection/required_status_checks \
  -f 'contexts[]=lint' -f 'contexts[]=cargo-test' -f 'contexts[]=parity' \
  -f 'contexts[]=compile-smoke' -f 'contexts[]=api-docs-drift' \
  -f 'contexts[]=security-audit' -f 'contexts[]=conformance-smoke-complete' \
  -f 'contexts[]=gc-ratchet'

Caveat worth weighing before pressing it: gc-ratchet.yml fires on schedule +
push, and this repo's push: on the test workflows is tags-only. Check that the
context actually reports on pull requests before making it required, or every PR
will sit forever on a check that never arrives — that is a different way to block
every open PR than the one CLAUDE.md warns about, with the same effect. Confirm on
one PR first.

gc-stress: still red, and for exactly ONE reason — see the linked bug

Eight consecutive nightly test.yml runs on main, 2026-08-07 through 2026-08-14,
all report gc-stress=failure (31150713440, 31240304595, 31295652054,
31358183869, 31460223673, 31566481914, 31670425699, 31772993217).

The most recent one narrows to a single row of scripts/gc_repsel_matrix.sh:

summary: PASS=1230 UNVER=310 XFAIL=0 FAIL=22
specabi_reassign   FAIL FAIL FAIL ... FAIL      <- 22 of 22 arms, INCLUDING shipped_default

Every other row is PASS or UNVER. It is not a GC-arm failure: it fails with
cycles=0 evacuated=0 scavenged=0 reclaimed=0 in several arms, it fails under
shipped_default requires=none, and every repsel kill switch leaves it broken.

Filed as #8100 with a five-line reproducer and a root cause: element reads on a
binding whose initializer was new Int32Array(...) lower to an unguarded
js_typed_array_get, and that helper answers 0.0 when clean_ta_ptr rejects the
receiver instead of falling back to the ordinary [[Get]]. Fixing #8100 is the whole
of what stands between gc-stress and a green main run.

There was also a SECOND, now-resolved cause worth recording so nobody re-derives it:
the 2026-08-08/09 runs (31240304595, 31295652054) had FAIL=0 in the matrix and
were red on the liveness gate instead — four arms (default, verify_evac,
cons_scan_off, cons_scan_off_force) flagged STALE-REGISTRY, listed in
scripts/gc_matrix_inert_arms.txt as known-inert while actually satisfying
requires=scavenge on 41/58 cells. That is gone in the 2026-08-14 run: every arm now
prints live.

Ordering

  1. Promote gc-ratchet now (precondition met), after confirming it reports on a PR.
  2. Fix Reassigning a new Int32Array binding to a plain array makes every element READ return 0 (silent miscompile; sole reason gc-stress is red) #8100 (specabi_reassign).
  3. Observe gc-stress green on main once.
  4. Promote gc-stress.

Note also #8092: lint and cargo-test are currently red for every PR, so the
required-context set is already being bypassed at merge time. Promoting a gate into a
set that is routinely bypassed buys less than it looks like it does; worth resolving
#8092 alongside.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugConfirmed defect or regression

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions