Repository navigation
conformance-smoke fails 8/8 shards: 12 real regressions, 10 newly-visible node_fail transitions, 1 fix the snapshot hasn't accepted #8117
Description
Summary
conformance-smoke is a required status context and it fails 8 of 8 shards on every recent PR. I pulled all eight shard logs from #8090's completed run and tallied the actual gate output. It is not flake, and it is not one cause — there are 23 status changes in four distinct categories.
CLAUDE.md warns that these shards are flaky and that a red shard should be re-run and A/B'd before being believed. Eight of eight is not the flake signature, which is why I went looking.
The tally
10 node_fail -> parity_fail
8 pass -> parity_fail
3 pass -> crash
1 pass -> compile_fail
1 parity_fail -> pass
10 × node_fail -> parity_fail — previously invisible, now exposed
test_gap_4510_enum_forward_ref test_gap_moment_methods
test_gap_backoff_options test_gap_prop_plan_cache_invalidation
test_gap_cron_cronjob test_gap_ratelimiter_memory
test_gap_dayjs_factory_arg test_gap_slugify_options
test_gap_derived_param_props test_gap_enum_in_function_body
This is exactly the #6364 pattern CLAUDE.md documents: when the oracle cannot run a test it exits non-zero, the harness classifies it node_fail, and the test is silently dropped from the gate rather than going red. These ten were in that hidden state and are now running — so these are not new breakage, they are newly visible breakage. The shard header says so itself: "STATUS CHANGES — including tests the oracle stopped covering".
That makes them the least urgent of the four groups and arguably good news, but they must be triaged and recorded rather than left to hold the gate red.
12 × genuine regressions from pass
pass -> crash test_gap_6386_dataview_concat_regex_fastpaths
test_gap_7238_i64_specialization_exactness
test_gap_buffer_own_props
pass -> compile_fail test_gap_zlib_4917_level
pass -> parity_fail test_gap_array_methods
test_gap_builtin_alias_construct_7524
test_gap_collection_foreach_member_receiver_thisarg
test_gap_dynamic_builtin_construct_dispatch
test_gap_new_globalthis_builtin_6726
test_gap_set_map_foreach_fused_receiver
test_gap_specabi_reassign
test_gap_sso_concat_string_index
These are the ones that matter. Three pass -> crash are the worst of them. test_gap_specabi_reassign is #8100, fixed by #8109 — so at least one of the twelve is already resolved, which suggests the rest are individually tractable.
I have not attributed these to a commit. They are red with similar counts on every PR I checked, so they are almost certainly main-side rather than any one PR's doing, but that is an inference and someone should bisect rather than trust it.
1 × parity_fail -> pass — a fix that fails the gate
test_gap_iterator_helpers_2874 now passes and the snapshot still lists it as failing. The snapshot gates divergence in either direction by design, so an improvement turns the gate red until the snapshot is regenerated. Working as intended, but worth naming: part of why this context is red is that something got better.
Why this matters beyond the tests themselves
conformance-smoke-complete is one of seven required contexts. With it red, no PR can merge without admin bypass, which is the "required and always red trains bypass" failure mode CLAUDE.md calls out — and it is how #8100 (a silent wrong-answer miscompile in the shipped default) sat unnoticed. Its shard was cancelled early on recent runs, so nothing surfaced it.
Tracking the required-context picture in #8092. The others: lint is fixed as of #8087; cargo-test fails on four ELF-only byte-identity tests; parity/compile-smoke report SKIPPED by design and are continue-on-error.
Suggested split
- Triage the 10
node_fail -> parity_failand record them intest-parity/gap_snapshot.jsonwith issue links — they were always broken and are cheap to classify. - Bisect the 12 genuine regressions. Three crashes first.
- Regenerate the snapshot for
test_gap_iterator_helpers_2874. - Only then is the gate meaningful enough to keep required.
Reproduce with ./scripts/run_gap_tests.sh --shard N/8.
Activity
proggeramlug commentedon Aug 14, 2026
Independent corroboration from a local gap run
An agent running the full gap suite locally (a different worktree, a different build, no CI involvement) hit the same set. Two of the twelve
pass ->regressions reproduced by name:and five of the ten
node_fail -> parity_failtransitions also reproduced (enum_forward_ref,backoff_options,cron_cronjob,dayjs_factory_arg,derived_param_props).That matters for the attribution I left open above. Two independent methods — CI's sharded run and a local full run on an unrelated branch — agreeing on the same names is much stronger evidence that these are main-side than my inference from "red on every PR I checked".
The local run also adds a control I could not get from CI logs: both regressions reproduce identically under
PERRY_SPECIALIZED_ABI=0, so they are not representation-selection or specialized-ABI effects.Two notes on the middle group: the agent characterised those five as environment drift rather than code — the snapshot recorded node refusing TS enums and failing to resolve
exponential-backoffwithoutnode_modules, and here node executes both. Consistent with the #6364 reading above, and it means a snapshot refresh clears them rather than a fix.One of the twelve now has an owner:
test_gap_array_methodsis thesort/with/toReversedfamily that #8090's changelog names as "same-class cases still open", tracked as #8096 with a fix in flight. That leaves eleven unowned, three of them crashes.proggeramlug commentedon Aug 15, 2026
Second corroboration, and a lead on two of the twelve
A full 559/559 local gap run (different host, different branch,
GAP_HARNESS_EXIT=1, no partial) reported seven regressions. All seven are in the twelve catalogued above, including both non-parity classes:It also independently confirmed the improvement:
test_gap_iterator_helpers_2874: parity_fail -> pass.The lead: two of them fail only in-suite
test_gap_7238_i64_specialization_exactnessandtest_gap_zlib_4917_leveldo not reproduce standalone. Run by hand they are byte-for-byte identical to node with exit 0.The first reading was host load — that run executed above load 100 with auto-optimize lock serialization, and the harness's own wording for the crash class is "died from a signal or timed out". But CI classified them the same way (
crash,compile_fail) on GitHub runners, which is a different host under different load. Two independent environments producing identical classifications is not the usual signature of a timeout artifact.So the better characterisation is "fails in-suite, passes standalone, on two independent hosts" — which points at test isolation or ordering rather than the code under test. That is a much cheaper thing to chase than a miscompile, and it should be checked before anyone bisects those two: if they are ordering-dependent, a bisect will produce a confident wrong answer.
Progress on the twelve
Three now have fixes on
main:specabi_reassignandsso_concat_string_index(#8109),array_methods(#8119, closing #8096). That leaves nine, of whichcollection_foreach_member_receiver_thisargandset_map_foreach_fused_receiverare the same empty-collection family and look like one bug rather than two.proggeramlug commentedon Aug 15, 2026
Status of the twelve after tonight's merges — measured, not inferred
A post-rebase retest on
83b6b8c69(which now carries #8106, #8109, #8118, #8119, #8120) re-ran the affected entries individually. Two are fixed; ten remain.6386_dataview_concat_regex_fastpaths7238_i64_specialization_exactnessarray_methodsbuffer_own_propsbuiltin_alias_construct_7524collection_foreach_member_receiver_thisargdynamic_builtin_construct_dispatchnew_globalthis_builtin_6726set_map_foreach_fused_receiverspecabi_reassignsso_concat_string_indexzlib_4917_levelsso_concat_string_indexwas predicted fixed and is notWorth recording because the reasoning failed in an instructive way. #8109's commit message says it re-tags "a heap string so it reaches the string arm rather than the ObjectHeader walk", which reads like general coverage of string indexing. It is not — that describes one arm of that change, and this case is outside it.
Reading a commit message is not reading the diff. The prediction was recorded in advance, which is the only reason the miss was visible at all; without it the observation would have been "three still red" with no signal that an expectation had been violated.
This one now looks like it wants an owner: it is red standalone, and the two fixes that landed in its neighbourhood did not touch it.
Remaining shape
6386_dataview_concat_regex_fastpaths,buffer_own_props) — most severe, unowned.7238_i64_specialization_exactness,zlib_4917_level) — do not bisect these before establishing isolation; an ordering-dependent failure will hand a bisect a confident wrong answer.collection_foreach_member_receiver_thisarg,set_map_foreach_fused_receiver) — plausibly one bug.So the ten split into roughly six investigations, not ten.
proggeramlug commentedon Aug 15, 2026
The two
pass -> crashentries: both are SIGSEGV, both are 12 days old, and they bisect to #7314 — nothing merged tonightTaking
6386_dataview_concat_regex_fastpathsandbuffer_own_props. Three things are measured below; one reading at the end is explicitly labelled inferred.1. They are signals, not timeouts
From the eight shard logs of #8090's run (31825115698), pulled with
gh api repos/:owner/:repo/actions/jobs/<id>/logs:The 13th/11th "line" is bash's own
Segmentation faultmessage, captured by the harness's2>&1. So the real counts are 12 and 10.For contrast, in that same run
7238_i64_specialization_exactnessisTIMEOUT (killed after 10s)— a genuinely different class, consistent with the "in-suite only" reading already in this thread.2. A zero-build bisect over the archived CI logs
For each historical PR run I downloaded its eight
conformance-smokeshard logs and read the PASS/CRASH verdict for these two names, then resolved each run's head sha to themaincommit it branched from (gh api repos/:owner/:repo/compare/main...<sha> --jq .merge_base_commit). No builds involved.Both tests PASS on every probed run from 2026-07-28 through 2026-08-03 13:49, and CRASH from 2026-08-03 15:41Z onward:
gc/7280-dep-corpusb50e857c2exp/stackmap-viabilityb50e857c2fix/7311-multi-operand-reload2fc383a6ffeat/gc-schedule-seed-fuzzing6bedb2574docs/7314-plan-status61a789f7cfix/node-module-node26-parity6fe493920gc/7314-followup-cross-function-match6fe493920fix/loop-safepoint-purity-knob93f5029e6git log 6bedb2574..6fe493920is exactly two commits and the later one is docs-only, so the window holds one code commit:Two rows make that airtight rather than circumstantial:
b50e857c2and differ only by Native-frame GC roots via LLVM statepoints, opt-in (#7173, #7174) #7314's diff —exp/stackmap-viabilityis Native-frame GC roots via LLVM statepoints, opt-in (#7173, #7174) #7314's development branch. Without the diff: pass. With it: crash.61a789f7c, and it crashes. Somainat that commit is bad, and no branch content is doing the work.Controls: the runner image is identical across the boundary (
ubuntu-24.04 / 20260720.247.2, provisioner20260707.563) on every row above, so this is not an image rotation.They are also intermittent. After 08-03 each test independently flips: buffer PASSes on 08-10, dataview PASSes on 08-08/08-09/08-13. Roughly 65–80% crash rate each. That is the signature CLAUDE.md gives for an unrooted register — "goes bad only when a collection lands in its window" — not a deterministic miscompile, and not an unrooted cache (which would be perfectly reproducible).
3. Where each one dies
The line counts are trustworthy:
js_console_logprints through Rust'sprintln!, and Rust'sStdoutis aLineWriter— it flushes on every newline whether or not stdout is a TTY — so nothing is lost in a buffer when the process dies.buffer_own_propsprinted all 10 of its lines, then faulted. That is the generated exit epilogue (codegen/entry.rsloop_exit):js_process_emit_before_exit→js_promise_run_microtasks_event_loop(an outermost microtask-pump GC safepoint) → timers →js_process_run_finalization_exit→ … →js_gc_release_current_thread_collection_side_allocations.6386_dataviewprinted 12 — throughdv shadowed: 43, the last statement of the DataView block — and faulted beforeconcat hot:. What follows is 200pushes and 500 ×[].concat(x, y)over 200 elements, the file's first heavy-allocation loop, i.e. the first loop back-edge poll / moving minor after that block.Shared shape: the first moving minor after an own property is stored onto a Buffer/DataView.
6386'sv3isconstinside a{ … }block, so by the concat loop it is dead whilebuffer_props[addr(v3)]still holds its entry (a closure) keyed by a dead address.buffer_own_propskeeps its Buffers module-level, so its entries stay live and its crash lands at the exit-boundary pump instead. Of the 559 gap fixtures, a grep for an own-property assignment onto a Buffer/DataView receiver matches essentially only these two.4. They do not reproduce on macOS/arm64
Release build at
83b6b8c69,PERRY_RUNTIME_DIRpinned,grep -c "Compiling perry-runtime v"= 1. Both fixtures are byte-identical to node v26.5.1 with exit 0, and stable across 30 consecutive runs each, with auto-optimize and without, and underPERRY_GC_ZEAL=1,PERRY_GC_ZEAL_ALLOC_KB=0,PERRY_GC_PROTECT_FROMSPACE=1 …_DEPTH=800,PERRY_GC_FORCE_EVACUATE=1,PERRY_GC_VERIFY_EVACUATION=1,PERRY_GC_FROMSPACE_SCAN=1,PERRY_GC_SCHEDULE_RATE=1across seeds, andPERRY_GEN_GC=0. The from-space scan reportsdangling=0 owners=0every time. This is not "statepoints are off locally" —otool -lshows a real__PERRY_GCMAP/__perry_gcmapsection in the compiled fixture, so the native-root backend is live here too.So the axis is Linux, not in-suite-vs-standalone — a different answer from the one #7238/#zlib got.
5. The mechanism — this part is inferred, not measured
Every behavioural change in #7314 is gated behind
statepoints_enabled()/rs4gc_enabled()/native_stack_roots_enabled()/gc_safepoint_only_contract_enabled()/stack_map_requested, all default-off at that commit. I read every hunk;function.rshas 4 removed lines and 1197 additive gated ones,module.rs's per-bucket global emission andlinker.rs's clang concurrency only fire for multi-unit modules (render_codegen_units(1) == to_ir(), and a one-file gap fixture is one unit), andcontract_scan_heal_guard()/visit_stack_map_root_slotsboth early-return when off.There is exactly one unconditional addition:
initialize_stack_maps()injs_gc_init. On macOS it resolves through_dyld_get_image_headerand allocates nothing. On Linux, at that commit, it is:So from
61a789f7con, every Perry binary on Linux reads its own 5–13 MB image into a heapVecat startup and frees it, before any user code runs, then returnsNonebecause a shadow-stack build has no such section. That moves every subsequent mmap and arena-block placement, it is Linux-only, and it lands exactly at the boundary. It is the best available explanation for "the diff is gated off and the tests flipped anyway, on Linux only" — i.e. #7314 most likely perturbed a latent bug rather than introducing a new code path, the same "allocator property, not a program property" class #7747 named for this exact test family.Two consequences if that reading holds: reverting #7314 is not the fix (it is the default root lowering now), and the real defect is older than 08-03 and still unnamed.
Worth a separate look regardless: current
mainhas expanded that startup read —loaded_stack_map_sections(#8075) nowstd::fs::reads everydl_iterate_phdrimage, the executable plus every shared object, on every Linux start.6. Two concrete defects in that neighbourhood, found by reading
Neither is proven to be the crash; both are real.
finalize_collected_dead_buffer(buffer/header.rs:675) never prunes the buffer own-property table. Its docstring is "Drop every registry/side-table entry keyed by a dead buffer's address" and it prunes ten of them —BUFFER_REGISTRY,ARRAY_BUFFER_REGISTRY,SHARED_ARRAY_BUFFER_REGISTRY,DATA_VIEW_REGISTRY,BUFFER_AB_ALIAS,CRYPTO_KEY_META_REGISTRY,SECRET_KEY_REGISTRY,UINT8ARRAY_FROM_CTOR, the threeexternal_*maps, plusdetach::andview::— but notown_props::clear_buffer_own_props. Its only caller isregister_buffer, so an entry is dropped only when the address is re-registered as a buffer. Result: an unbounded leak,scan_buffer_own_props_roots_mutretaining a dead buffer's closure forever, and an entry whose keyvisit_metadata_usize_slotkeeps re-resolving against whatever now owns that address.scan_buffer_own_props_roots_mutdiverges from the sibling it claims to mirror.own_props.rssays it mirrorsclosure::dynamic_props"(same locked side table + GC root scanner contract)". The closure version does two things it does not: it falls back toforwarded_heap_owner(owner)when the visitor did not rewrite the key, and it re-inserts throughmerge_closure_prop_mapso a post-rewrite key collision merges instead of clobbering. The buffer version does a bareprops.insert(new_owner, entries).Next
A Linux-side probe is running (
diag/8117-probe, a manual-dispatch-only workflow that hammers just these two fixtures on ubuntu-latest and takes agdbbacktrace on the first signal), plus the same thing in a local Linux aarch64 container. Whatever the backtrace says, the three facts above stand: SIGSEGV, dating to #7314 on 2026-08-03, intermittent, and Linux-only.proggeramlug commentedon Aug 15, 2026
Root cause found. Both
pass -> crashentries are one missing receiver arm — fix in #8141.Correcting my own earlier comment on two points, both because I now have a Linux reproduction rather than an inference.
1. They DO reproduce standalone. "Passes standalone" was a property of my host.
buffer_own_props6386_dataviewThe x86-64 row is a manual-dispatch job on a clean checkout of
fa83ecab2, compiling and running the fixture directly — no gap harness, no shard, notimeoutwrapper. So this is not test isolation or ordering, and it is not the7238/zlibclass.2. The bug
Faulting instruction
ldurb w9, [x20, #-8], thencmp w9, #0x9and a compare against0x4C5A5841—GC_TYPE_LAZY_ARRAYandLAZY_ARRAY_MAGIC.x0is not an address.obj_value_has_own_keyhas arms for a registry typed array, aGC_TYPE_ARRAY/GC_TYPE_LAZY_ARRAY, a closure and a native-module namespace — and none for a Buffer / ArrayBuffer / DataView. A buffer is aBufferHeader: noclass_id, nokeys_array. So the ordinary arm read(*obj).keys_arrayout of the bytes that follow a buffer header and handed it tojs_array_length, with nothing in between but a< 0x10000magnitude floor that payload bytes clear routinely.Four lines, 10/10 on Linux:
Same "ask the receiver question before the generic path claims it" shape as #8090 / #8109 / #8119 / #8120 — on the has-own-key /
[[Set]]path this time. #8130 and #8140 are the same family again, which is starting to look like a category worth a sweep rather than one arm at a time.3. Why the bisect landed on #7314, and why that was still worth doing
The defect is older than #7314. The garbage
keys_arrayhas to clear the floor and land unmapped; macOS's 2 TB heap floor makes it read as null, so the same call there silently answers "no own key" for a property the buffer really owns — wrong, but survivable.#7314's one unconditional addition is
initialize_stack_maps()injs_gc_init, whose Linux arm isstd::fs::read("/proc/self/exe")— the entire executable into a heapVec, before any user code, on every Perry binary. That moved the heap enough to turn a pre-existing wrong answer into a fault. So the bisect was correct about when it started landing and wrong about what is broken, which is exactly the failure mode a bisect on a layout-sensitive bug has. Reverting #7314 would not have fixed it.(Independently worth a look: current
mainhas widened that toloaded_stack_map_sections(#8075), which nowstd::fs::reads everydl_iterate_phdrimage — the executable plus every shared object — at every Linux start.)4. Fix and verification — #8141
A registered-buffer arm beside the typed-array arm, answering from the #6406 expando table. Prototype methods are inherited, not own, which is what lets
buf.readUInt8 = fninstall a shadowing own property; canonical integer indices are deliberately not folded in. Plus thekeys_arrayguard becomesaddr_class::is_plausible_heap_addrinstead of the bare floor, as defence in depth for the next missing arm.Linux container, before → after (
grep -c "Compiling perry-runtime v"= 1 on the rebuild):test_gap_6386_dataview_concat_regex_fastpathstest_gap_buffer_own_propsBoth gap fixtures are byte-identical to node v26.5.1 afterwards.
cargo test -p perry-runtime --lib→ 2390 passed, 0 failed, 4 ignored (baseline 2389 + the new test). The test asserts the answer, not "did not crash", so it fails on macOS too — watched fail with the arm removed: "a buffer's own expando property must be reported as an own key".Two side findings from the same read
finalize_collected_dead_bufferprunes eleven address-keyed side tables and misses the buffer own-property table, so a dead buffer's expando closure is retained by the GC forever. Separate PR, sabotage-verified, explicitly not claimed as a fix for this issue.js_class_method_bindsites still bind a movable heap string's interior (the siblings Fix a crash when reading a method off a Buffer without calling it #7747 missed: timer handles,TextDecoder.decode,TextEncoder.encode).That leaves eight of the original twelve, and no crashes among them.
fix(object): a Buffer/DataView receiver must not reach the ordinary o…
proggeramlug commentedon Aug 15, 2026
Recount against current
main(fb87d8923): 9 of the 12 now passRe-ran every one of the twelve
pass -> Xregressions on a fresh perry-dev build of currentmain,PERRY_NO_AUTO_OPTIMIZE=1,PERRY_RUNTIME_DIRpinned to that build's own.afiles, byte-compared against node 26.5.1 (.node-version).test_gap_6386_dataview_concat_regex_fastpathstest_gap_7238_i64_specialization_exactnesstest_gap_buffer_own_propstest_gap_zlib_4917_leveltest_gap_array_methodstest_gap_builtin_alias_construct_7524test_gap_dynamic_builtin_construct_dispatchtest_gap_new_globalthis_builtin_6726test_gap_specabi_reassigntest_gap_collection_foreach_member_receiver_thisargtest_gap_set_map_foreach_fused_receivertest_gap_sso_concat_string_indexAll three
pass -> crashentries are gone. Two of them (buffer_own_props,6386_dataview) were one bug — a missing Buffer/DataView arm inobj_value_has_own_key, fixed in #8141.specabi_reassignwas #8100/#8109 as this issue predicted. The rest were cleared by the #8090/#8109/#8119/#8120/#8134/#8135 run.This issue's own note that the twelve "are almost certainly main-side rather than any one PR's doing" was right, and it is the reason they cleared in a batch.
The three that remain
The first two are almost certainly one bug —
Set/MapforEachwith a member-expression callback or a fused receiver collects nothing. Note the second also loses whole output lines, so a callback is likely never invoked rather than merely returning empty.The third is separate and the worst of the three: indexing a string returns
undefinedafter an SSO concat. Silent wrong values, not a crash, and not confined to an exotic receiver.All three are in flight.
Caveat on this measurement
My harness is a direct compile-and-
cmpagainst node, not the gap runner. The real harness appliesnormalize_output, so a test I callparity_failcould normalize to a pass, and in principle the reverse. Treat the nine as "very likely clear" and confirm on the next fullconformance-smokerun rather than closing this issue on my numbers alone. I would rather state that than have someone close it and find the gate still red.The 10
node_fail -> parity_failentries are untouched by this recount — they were always broken and still need triaging intotest-parity/gap_snapshot.jsonwith issue links, as this issue's step 1 says.fix(object): an SSO string receiver is indexable, not unindexable (#8117
fix(array): route a Map/Set receiver before the array-only funnel in …
proggeramlug commentedon Aug 15, 2026
All 12 genuine regressions are now fixed
The last three landed:
test_gap_collection_foreach_member_receiver_thisargandtest_gap_set_map_foreach_fused_receiver. One cause, not two: fix(gc): install array growth forwarding for low-address arenas #8041 widenedclean_arr_ptrto reject every tracked non-array, which nullsGC_TYPE_SET/GC_TYPE_MAP, and nextjs: dynamic RSC render evaporates silently with a clean async graph after expected manifest ENOENTs (post-#5988 wall for 8/8) #5989's reroute sat below that early-out — so it had become dead code.test_gap_sso_concat_string_index.js_object_get_index_polymorphicasks the key's kind carefully (it has a dedicated SSO arm for an SSO key) and never asks the receiver's, soSHORT_STRING_TAGfell into the reject arm and every index read on an SSO string answeredundefined.Both are the same family as #8090/#8109/#8119/#8120/#8124/#8141/#8148: a receiver-specific path claiming an operation before the receiver-kind question is asked. That is now eight instances in two days, which is worth treating as a design signal rather than eight coincidences.
Verified on a build of
mainwith both merged — all three byte-identical to node 26.5.1, exit 0:cargo test -p perry-runtime --lib: 2399 passed, 0 failed, 4 ignored.Not closing this yet — two things remain
1. The
normalize_outputcaveat still applies. My verification compiles andcmps directly; the real gate normalizes. The next fullconformance-smokerun onmainis the authority, not my numbers. Leaving this open until one goes green.2. The 10
node_fail -> parity_failentries are untouched. They were always broken and only became visible; this issue's own step 1 asks for them to be triaged intotest-parity/gap_snapshot.jsonwith issue links. Nobody has done that, and they will hold the gate red on their own.A finding that changes what fixing this issue buys
Fixing
conformance-smokewill not stop merges needing admin bypass, so this issue is not the last obstacle to #8101.parityandcompile-smokeare in the required contexts but both are gated topush/workflow_dispatch/ arun-extended-testslabel. On an ordinary PR they never run, so they sit permanently at "Expected — waiting for status" and every PR is structurally BLOCKED no matter what else is green. Confirmed against the live required list and against PRs merged today: of the seven required contexts, only a couple ever report.That is CLAUDE.md's own hazard 2/4 aimed at the required list itself. Two ways out, and it is a maintainer decision:
parityandcompile-smokefrom the required contexts, since they are tag-gated by design; orWorth deciding deliberately rather than discovering it at #8101's promotion time.
fix(gc): prune the buffer own-property table when its buffer dies (#8136
proggeramlug commentedon Aug 16, 2026
All 23 status changes are now accounted for on
3be2016c1. Evidence is a full unshardedrun_parity_tests.sh --filter test_gap_run (562 tests, 01:26) —conformance-smokeruns./scripts/run_gap_tests.sh --shard N/8, i.e. this same suite, so a full run is a superset of all eight shards.The 12 genuine regressions — all 12 PASS
6386_dataview_concat_regex_fastpaths(was crash)buffer_own_props(was crash)collection_foreach_member_receiver_thisargset_map_foreach_fused_receiversso_concat_string_indexarray_methodsspecabi_reassignbuiltin_alias_construct_7524dynamic_builtin_construct_dispatchnew_globalthis_builtin_67267238_i64_specialization_exactness(was crash)zlib_4917_level(was compile_fail)The three indirect-builtin-construct tests were expected to need one shared fix; they now pass without one having been written for them specifically, so something landed in the last day that covers the family (#8153's
newname resolution and #8177's handle-method dispatch are the plausible candidates — neither is proven, and it no longer matters for this issue).7238_i64_specialization_exactnessandzlib_4917_levelwere the two flagged as in-suite red, standalone green on two independent hosts. Both are green in-suite now.The 1 ×
parity_fail -> passiterator_helpers_2874— confirmed passing. It is still listed ingap_snapshot.json, so it currently reads as animprovementdiff and holds the gate red. Fixed by the snapshot regeneration below.The 10 ×
node_fail -> parity_fail— root-caused, and worse than "newly visible"This issue read them as previously-hidden breakage now exposed. That is half right. The full mechanism:
run_parity_tests.shcannot emitnode_failfor a plainexit 1at all. The onlyrecord_result "$test_id" "node_fail"site (~:1344) is guarded byperry_abnormal_exit, which matches signals and timeout only (124, 132/134/136/138/139, >128). These tests fail with plain exit 1 —ERR_UNSUPPORTED_TYPESCRIPT_SYNTAXfor the enum/parameter-property tests (strip-only mode cannot run them, and Node 26 removed--experimental-transform-types), andMODULE_NOT_FOUNDfor the npm ones.So those ten snapshot entries record a status the harness is structurally incapable of producing. Every run yields
changed, and any diff makesgap_snapshot.pyreturn 1. The gap gate could never be green — the mirror of CLAUDE.md's "four ways a gate can be unable to fail". It survived becauseparityis tag-gated and invisible per-PR;conformance-smokerunning the same suite is what surfaced it.Fixes, verified individually through the real harness (9 PASS):
4510_enum_forward_ref,derived_param_props,enum_in_function_body) — node can never run these, so they gettest-parity/expected/<name>.txtfixtures, the channel thetest_decorators_*tests already use for the same reason. Oracle built withesbuild→ node; output matches each test's own documented expectations, and Perry is byte-identical to all three. Notederived_param_props's header already said "this is a perry-only expected-output test" — the fixture was simply never created.backoff_options,cron_cronjob,dayjs_factory_arg,moment_methods,ratelimiter_memory,slugify_options) — the packages were never declared inpackage.json, so the oracle could not run in any environment, CI included;npm ciwould not install them either..npmrcsays the root npm install exists precisely to "materialize the parity-test fixture deps". Declared them; all six now run under node with exit 0 and all six match Perry. Live parity, better than a frozen fixture.prop_plan_cache_invalidationis written for sloppy mode ("writes must be dropped") but runs as ESM, which is strict, so the frozen write throws. Node and Perry both correctly throw; they differ only in the message — node'#<H>', Perry'#<Object>'.js_throw_type_error_immutable_write(error.rs:1726) takes no receiver and hardcodesObject. 14 callers, all behind one wrapper, so it is fixable without a codegen ABI change. Being fixed separately.Also fixed while here:
SKIP_TESTSis exact-match and contains only legacytest_*names, so it can never match atest_gap_*test.What remains before this closes
The snapshot is being regenerated from a real run (
UPDATE_SNAPSHOT=1) rather than hand-edited — the_schemasays "do not hand-edit statuses", and hand-editing is almost certainly how ten impossible statuses got there. When that PR lands, all 23 changes are resolved.Two caveats recorded honestly:
conformance-smokeshards 8 ways, which changes test ordering. The two "in-suite red, standalone green" tests are exactly the shape that could be ordering-sensitive, so a sharded confirmation is worth doing before trusting the gate green.webcrypto_async_threadpoolfailed once in this run and is not a regression — the test asserts an async digest crosses a macrotask boundary, node printedfalseat load ~64, and 5/5 re-runs at load ~45 printtrue, matching Perry. The oracle flaked. It must not be parked in the regenerated snapshot; I will check the output before committing it.test(gap): make the gap gate capable of passing (#8198)
proggeramlug commentedon Aug 16, 2026
All 23 status changes are resolved on
main@6e05295ed. Closing.conformance-smokeruns./scripts/run_gap_tests.sh --shard N/8— the same gap suite — so a full unsharded 562-test run is a superset of all eight shards. That run reports 99.1% parity, 5 non-passing, 0 crashes, andgap_snapshot.py checkexits 0.12 × genuine regressions — all pass. Seven by named fixes (#8141 ×2 for the two crashes, #8130 ×2, #8151, #8119, #8109); the other five —
builtin_alias_construct_7524,dynamic_builtin_construct_dispatch,new_globalthis_builtin_6726, and both "in-suite red, standalone green" oddities (7238_i64_specialization_exactness,zlib_4917_level) — now pass without a fix aimed at them specifically. The three indirect-builtin-construct tests were expected to need one shared fix; something in the last day covers the family.1 ×
parity_fail -> pass(iterator_helpers_2874) — accepted by the regenerated snapshot.10 ×
node_fail -> parity_fail— this issue read them as previously-hidden breakage now exposed. That was half right, and the full mechanism was worse:run_parity_tests.shcannot emitnode_failfor a plainexit 1at all. The onlyrecord_result "node_fail"site is guarded byperry_abnormal_exit, which matches signals and timeout only (124, 132/134/136/138/139, >128). These tests fail with a plain exit 1 —ERR_UNSUPPORTED_TYPESCRIPT_SYNTAXfor the enum and parameter-property cases (strip-only mode cannot run them, and Node 26 removed--experimental-transform-types), andMODULE_NOT_FOUNDfor the npm ones.So ten snapshot entries recorded a status the harness is structurally incapable of producing.
diff()returnedchangedfor every one, and any diff makes the gate exit 1. The gap gate could never be green, on any tree — the mirror of CLAUDE.md's "four ways a gate can be unable to fail". It survived becauseparityis tag-gated and invisible per-PR; this issue's 8/8 red shards are what surfaced it.Fixed by category in #8198 (verified on main):
test-parity/expected/*.txtfixtures — the channel thetest_decorators_*tests already use for the same reason. Oracle built withesbuild→ node, cross-checked against the expectations in each test's own header; Perry byte-identical to all three.test_gap_derived_param_propsalready said "this is a perry-only expected-output test" — the fixture was simply never created, so it had verified nothing since May.package.json, so the oracle could not run in any environment, CI included —npm ciwould not have installed them either. All six now run under node with exit 0 and all six match Perry: live parity rather than a frozen fixture.prop_plan_cache_invalidationis written for sloppy mode but runs as ESM, which is strict, so its frozen-object writes throw. Node and Perry both correctly throw and differ only in the message — node names the constructor ('#<H>'), Perry hardcodes'#<Object>'aterror.rs:1726becausejs_throw_type_error_immutable_writetakes no receiver. Recorded with that root cause; 14 callers behind one wrapper, so a receiver-aware variant fixes it with no codegen ABI change.The snapshot was regenerated from a full run rather than hand-edited — the
_schemasays not to, and hand-editing is how ten impossible statuses got there. It now holds 5 entries, allparity_fail, zeronode_fail.Two things recorded rather than quietly done.
SKIP_TESTSis exact-match and holds only legacytest_*names, so it can never match atest_gap_*test — left alone because every current case is better served by the expected-output channel. Andtest_gap_webcrypto_async_threadpoolfailed once during verification at load ~64 and was deliberately not parked: it asserts an async digest crosses a macrotask boundary, node printedfalse, and 5/5 re-runs at load ~45 printtrue, matching Perry. The oracle flaked; parking it would have converted a load artifact into a permanently accepted failure.One caveat left open honestly: the verification run was unsharded, and
conformance-smokeshards 8 ways, which changes ordering. The two formerly-flaky tests are exactly the shape that could be ordering-sensitive, so a sharded confirmation is worth having before treating the gate as trustworthy — but nothing in this issue's tally remains unaccounted for.