You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
repsel-census red since v0.5.1613: a pre-existing unnamed ptr-shape residue became visible when #10774 consumed the workload's only named mechanism #10793
repsel-census has been red on main since v0.5.1613 (merge train 234). It was green on every sweep through v0.5.1612.
I landed that train, so this is mine.
Bisected with pinned release binaries, not inferred
candidate233r perry 0.5.1612 census --gate → rc=0
candidate234r perry 0.5.1613 census --gate → rc=1
Same command CI runs (python3 scripts/compiler_output_regression.py census --perry <bin> --keep-reports … --gate), same tree, only the compiler differs. CI agrees: success at v0.5.1611 and v0.5.1612, failure at v0.5.1614 and v0.5.1615; v0.5.1613's own run was cancelled, which is why the bracket needed closing locally.
The single hard failure
WASTED PROMOTION WITH NO NAMED MECHANISM:
batch: 1 selected ptr-shape promotion(s) were not consumed, and not one of them
names a mechanism. A wasted promotion with no rule attached is the state this
census was built to end: it reads exactly like an honest zero. Either a
mechanism recorder was removed, or a new way to drop a proof exists and needs one.
Everything else the census reports is an improvement, advisory only — and the shape of that list is the clue:
fixture_ptr_shape_elements: canonical-i32 promoted 2, floor is 1 (+1)
batch: ptr-shape promoted 3, floor is 2 (+1)
batch: ptr-shape-consumed promoted 2, floor is 1 (+1)
suite_02_loop_overhead / suite_11_prime_sieve / suite_15_mandelbrot: canonical-i32 (+1 each)
… 13 workloads, all up
Prime suspect, stated as a suspect
Train 234 carried four PRs: #10766 (literal-key member fold after const substitution), #10774 (stop disabling Ptr<Shape> in entry bodies), #10767 (string-coercion ladders), #10776 (toFixed cliff).
#10774 is the Ptr<Shape> change, the census counts ptr-shape promotions, and promotions went up across thirteen workloads — exactly what re-enabling a shape proof in entry bodies should do. The plausible mechanism is that a proof is now made in a position that previously refused it, and the path that drops it has no mechanism recorder because that path was unreachable before.
This is not commit-level bisected — I have per-train binaries, not per-commit ones, so #10774 is an attribution from the subsystem and the counter that moved, not from an A/B. Confirm before fixing.
Note #10774 is not obviously wrong here: more promotions is the point of that change, and the census's own message says the alternative reading is "a new way to drop a proof exists and needs one". The fix may well be to name the mechanism rather than to undo anything.
The process gap that let it through
My merge-train validation runs the nine cheap gates, cargo check --workspace --all-targets, the unit suites, lint, and a scoped gap sweep. repsel-census is a separate CI job and none of those invoke it, so a census regression is structurally invisible to the pre-merge check — which is why this landed in 234 and was still landing in 235, 236 and 237 before anyone looked. I am adding the census to the train driver so the next train cannot repeat it.
Worth noting the census did its job perfectly: it refused to treat a wasted promotion as an honest zero, and the message says exactly what to check. The gate is good; the thing that failed is that nobody was reading it.
Fixed — fix/10793-repsel-wasted-ptr-shape @ 653ec93266, queued for a merge train.
And my framing in the issue title was wrong: #10774 is the trigger, not the fault. It did not create the wasted promotion. Diffing the two reports, exactly one entry changed on batch:
v0.5.1612
v0.5.1613
acc @ totalsRow
consumed
consumed
totals @ module_init
unconsumed, mechanism module_init_context
consumed
row @ buildRows
selected, unconsumed, no mechanism
selected, unconsumed, no mechanism
v0.5.1612: wasted 2, mechanisms 1 → passes on the residue allowance. v0.5.1613: wasted 1, mechanisms 0 → red. #10774consumedtotals, which is it working as intended — and that removed the workload's only named mechanism, leaving a pre-existing unnamed residue as the only wasted promotion, and therefore the only one the check could see.
The attribution was not left as subsystem-matching either: reconstructing "today's main minus #10769" — restoring the literal allows_ptr_shape: false / ptr_shape_denial: Some(MODULE_INIT_CONTEXT) in the Entry arm and nothing else — turns the census green and reproduces the deleted v0.5.1612 report entry-for-entry. (Also worth knowing for anyone following the trail: #10774's squashed commit is titled with issue #10769. Same change, two numbers.)
What was actually wasted
row in buildRows (benchmarks/app-patterns/kernels/batch.ts:55). Its only use is rows.push(row) — a contained element push into an element-shape-proven array — which clears the containment rule while giving the local no property access anywhere in the body. The field reads happen later, through the array's own element-shape fact, on a different value. The proof is sound and there is nothing to spend it on. check_unconsumed_is_explained's own docstring already named this shape: "a promotion with no access site at all is dropped by nobody." Nobody is a mechanism; it just had no recorder.
The fix names the mechanism — no floor lowered, nothing reverted
PTR_SHAPE_NO_ACCESS_SITE joins module_init_context and scalar_replaced, recorded from the same loop iteration as the select() it annuls, reading the use walk's own containment bookkeeping rather than a second definition of "access site". Inferring the rule at render time from selected − consumed was explicitly rejected: that fabricates a mechanism for every gap and permanently disarms the check.
I verified it does not disarm the gate, from a different angle than the sabotage
The concern with any "make the red gate green" change is that the greenness comes from the config rather than from the thing being fixed. So:
fixed tree + FIXED compiler → rc=0, "Census OK." (9 workload lines, genuinely ran)
fixed tree + UNFIXED compiler → rc=1, "WASTED PROMOTION WITH NO NAMED MECHANISM"
The green requires the compiler emitting the new record. Nothing in the tree relaxes anything. That is independent of the three sabotages in the branch, the most important of which is worth restating: disabling the pre-existingscalar_replaced recorder still reds fixture_alloc_buckets, suite_07_object_create and suite_12_binary_trees — the new recorder does not paper over other mechanisms.
Still open, deliberately
The thirteen workloads whose promotion counts rose are advisory canonical-i32/spec-abi-entry improvements from train 234, and --update was deliberately not run. The floors are all satisfied, so this is not blocking — but somebody ratcheting those floors should do it as its own change with its own justification, not as a side effect of a fix.
The process failure, which was mine
repsel-census is a sweep-tier job and nothing in my merge-train validation invoked it, so this was structurally invisible for four trains. I have since derived the driver's coverage from scripts/ci_plan.py --table rather than from memory: of the 12 sweep-tier jobs, it ran 7. repsel-census and security-audit are now in, and the remaining gaps are named rather than assumed — gc-stress is a 90-minute fan-in over downloaded shard artifacts, and windows-build / windows-arm64-build / harmonyos-smoke are the wrong host.
The census itself did its job exactly right: it refused to treat a wasted promotion as an honest zero, and its message named both possible readings, one of which was correct.
changed the title [-]repsel-census red since v0.5.1613 (train 234): one wasted ptr-shape promotion with no named mechanism — bisected to the train, prime suspect #10774[/-][+]repsel-census red since v0.5.1613: a pre-existing unnamed ptr-shape residue became visible when #10774 consumed the workload's only named mechanism[/+]on Sep 20, 2026
Landed via merge train 239 (#10800) as v0.5.1618 — b9ba951ff8.
repsel-census is green for the first time since v0.5.1613, and #10787 travelled with the fix without adding a wasted promotion: repsel_census rc=0 wasted_promotion=False.
Holding #10787 back one train was only safe because the #10793-only census was verified green before assembly, so any wasted promotion in this train would have been unambiguously attributable. There was none.
I verified the green is not a disarm, independently of the branch's own sabotages:
fixed tree + FIXED compiler → rc=0, "Census OK." (9 workload lines — it genuinely ran)
fixed tree + UNFIXED compiler → rc=1, "WASTED PROMOTION WITH NO NAMED MECHANISM"
The green requires the compiler emitting the new no_access_site record; nothing in the config relaxes anything. And the landing gate now requiresrepsel_census rc=0 rather than carrying its old known-red tolerance forward — a baseline that still accepts the failure it just fixed is how a fix silently stops holding.
The corrected framing is in the train body: #10774 was the trigger, not the fault. It consumedtotals, which is it working as intended, and that removed the workload's only named mechanism — exposing a pre-existing unnamed residue as the only wasted promotion the check could see. My original issue title implied otherwise and has been retitled.
For #10787 specifically: the honesty about not reaching parity (2–7 instructions against node's 6.9–9.2) and about #7109 and the missing SlotRep::F64 being absences rather than zeros is preserved in the body. So is the o.a * 1 explanation — "Binary is a shape the predicate recognises, and the multiply normalises nothing" — which finally accounts for the + 0 versus - 0 split in #10777.
One transient is disclosed rather than buried: cor_native-abi-proof reported native_memory_fixture during the run and does not reproduce (standalone re-run rc=0, failed_workloads: []). It is the only fixture in the corpus that shells out to cargo build for a Rust staticlib mid-check, so it is uniquely exposed to concurrent cargo activity and disk pressure, and the box was at 19–24 GB with this train's own build and sweep running. The landing gate accepts that one workload and refuses any other compiler-output failure.
Activity
proggeramlug commentedon Sep 20, 2026
Fixed —
fix/10793-repsel-wasted-ptr-shape@653ec93266, queued for a merge train.And my framing in the issue title was wrong: #10774 is the trigger, not the fault. It did not create the wasted promotion. Diffing the two reports, exactly one entry changed on
batch:acc@totalsRowtotals@module_initmodule_init_contextrow@buildRowsv0.5.1612: wasted 2, mechanisms 1 → passes on the residue allowance. v0.5.1613: wasted 1, mechanisms 0 → red. #10774 consumed
totals, which is it working as intended — and that removed the workload's only named mechanism, leaving a pre-existing unnamed residue as the only wasted promotion, and therefore the only one the check could see.The attribution was not left as subsystem-matching either: reconstructing "today's
mainminus #10769" — restoring the literalallows_ptr_shape: false/ptr_shape_denial: Some(MODULE_INIT_CONTEXT)in theEntryarm and nothing else — turns the census green and reproduces the deleted v0.5.1612 report entry-for-entry. (Also worth knowing for anyone following the trail: #10774's squashed commit is titled with issue #10769. Same change, two numbers.)What was actually wasted
rowinbuildRows(benchmarks/app-patterns/kernels/batch.ts:55). Its only use isrows.push(row)— a contained element push into an element-shape-proven array — which clears the containment rule while giving the local no property access anywhere in the body. The field reads happen later, through the array's own element-shape fact, on a different value. The proof is sound and there is nothing to spend it on.check_unconsumed_is_explained's own docstring already named this shape: "a promotion with no access site at all is dropped by nobody." Nobody is a mechanism; it just had no recorder.The fix names the mechanism — no floor lowered, nothing reverted
PTR_SHAPE_NO_ACCESS_SITEjoinsmodule_init_contextandscalar_replaced, recorded from the same loop iteration as theselect()it annuls, reading the use walk's own containment bookkeeping rather than a second definition of "access site". Inferring the rule at render time fromselected − consumedwas explicitly rejected: that fabricates a mechanism for every gap and permanently disarms the check.I verified it does not disarm the gate, from a different angle than the sabotage
The concern with any "make the red gate green" change is that the greenness comes from the config rather than from the thing being fixed. So:
The green requires the compiler emitting the new record. Nothing in the tree relaxes anything. That is independent of the three sabotages in the branch, the most important of which is worth restating: disabling the pre-existing
scalar_replacedrecorder still redsfixture_alloc_buckets,suite_07_object_createandsuite_12_binary_trees— the new recorder does not paper over other mechanisms.Still open, deliberately
The thirteen workloads whose promotion counts rose are advisory
canonical-i32/spec-abi-entryimprovements from train 234, and--updatewas deliberately not run. The floors are all satisfied, so this is not blocking — but somebody ratcheting those floors should do it as its own change with its own justification, not as a side effect of a fix.The process failure, which was mine
repsel-censusis a sweep-tier job and nothing in my merge-train validation invoked it, so this was structurally invisible for four trains. I have since derived the driver's coverage fromscripts/ci_plan.py --tablerather than from memory: of the 12 sweep-tier jobs, it ran 7.repsel-censusandsecurity-auditare now in, and the remaining gaps are named rather than assumed —gc-stressis a 90-minute fan-in over downloaded shard artifacts, andwindows-build/windows-arm64-build/harmonyos-smokeare the wrong host.The census itself did its job exactly right: it refused to treat a wasted promotion as an honest zero, and its message named both possible readings, one of which was correct.
[-]repsel-census red since v0.5.1613 (train 234): one wasted ptr-shape promotion with no named mechanism — bisected to the train, prime suspect #10774[/-][+]repsel-census red since v0.5.1613: a pre-existing unnamed ptr-shape residue became visible when #10774 consumed the workload's only named mechanism[/+]fix(codegen): name the mechanism that drops an unspendable Ptr<Shape>…
proggeramlug commentedon Sep 20, 2026
Landed via merge train 239 (#10800) as v0.5.1618 —
b9ba951ff8.repsel-censusis green for the first time since v0.5.1613, and #10787 travelled with the fix without adding a wasted promotion:repsel_census rc=0 wasted_promotion=False.Holding #10787 back one train was only safe because the #10793-only census was verified green before assembly, so any wasted promotion in this train would have been unambiguously attributable. There was none.
I verified the green is not a disarm, independently of the branch's own sabotages:
The green requires the compiler emitting the new
no_access_siterecord; nothing in the config relaxes anything. And the landing gate now requiresrepsel_census rc=0rather than carrying its old known-red tolerance forward — a baseline that still accepts the failure it just fixed is how a fix silently stops holding.The corrected framing is in the train body: #10774 was the trigger, not the fault. It consumed
totals, which is it working as intended, and that removed the workload's only named mechanism — exposing a pre-existing unnamed residue as the only wasted promotion the check could see. My original issue title implied otherwise and has been retitled.For #10787 specifically: the honesty about not reaching parity (2–7 instructions against node's 6.9–9.2) and about #7109 and the missing
SlotRep::F64being absences rather than zeros is preserved in the body. So is theo.a * 1explanation — "Binaryis a shape the predicate recognises, and the multiply normalises nothing" — which finally accounts for the+ 0versus- 0split in #10777.One transient is disclosed rather than buried:
cor_native-abi-proofreportednative_memory_fixtureduring the run and does not reproduce (standalone re-runrc=0, failed_workloads: []). It is the only fixture in the corpus that shells out tocargo buildfor a Rust staticlib mid-check, so it is uniquely exposed to concurrent cargo activity and disk pressure, and the box was at 19–24 GB with this train's own build and sweep running. The landing gate accepts that one workload and refuses any other compiler-output failure.