Wait for module-import telemetry instead of hoping one tick was enough - #154
Merged
Conversation
The no-egress calibration failed on a two-core runner reporting zero attempts for exactly two of its nine probes: - "bare_package_import_attempts": 1, + "bare_package_import_attempts": 0, - "unreviewed_module_import_attempts": 1, + "unreviewed_module_import_attempts": 0, Those two are the only counters not incremented synchronously by the guard that denied the attempt. Module resolution is denied on the loader thread, which reports the attempt across a MessagePort, so the import can have already rejected while its telemetry is still in flight. The child then read the receipt after a single setImmediate, which assumed one turn of the main loop was enough for a cross-thread delivery. Usually it is. The consequence is worse than a red run. This test exists to prove every guard is live before it will accept the product's own score of zero, so losing this race means a security calibration quietly failing to calibrate. It failed in the safe direction, but it failed. The loader now answers a flush probe on the same port it reports on. A MessagePort delivers in order, so an ack posted when that handler runs necessarily follows every attempt message posted before it, whatever the latency. The child awaits the round trip rather than a tick. The port stays unreffed except while a round trip is outstanding, so it still cannot hold the process open, and a flush that never returns surfaces as the harness's existing forced-kill assertion rather than as a wrong count. Proved by modelling the real failure: defer every inbound message by 50 ms while preserving per-port order, which is what slow cross-thread delivery looks like from the main thread. Under that injection the old setImmediate reproduces the CI diff exactly, both counters zero; the round trip passes. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Node 22 failure on #153, which had nothing to do with #153.
The defect
The no-egress calibration failed on a two-core runner reporting zero attempts for exactly two of its nine probes:
Those two are the only counters not incremented synchronously by the guard that denied the attempt. Module resolution is denied on the loader thread, which reports the attempt across a MessagePort, so the import can have already rejected while its telemetry is still in flight. The child then read the receipt after a single
setImmediate— assuming one turn of the main loop is enough for a cross-thread delivery. Usually it is.Why it matters more than a red run
This test exists to prove every guard is live before it will accept the product's own score of zero attempts. Losing this race means a security calibration quietly failing to calibrate. It failed in the safe direction — it refused to certify — but a calibration that intermittently cannot calibrate trains people to hit rerun.
The fix
The loader answers a flush probe on the same port it reports on. A MessagePort delivers in order, so an ack posted when that handler runs necessarily follows every attempt message posted before it, whatever the latency. The child awaits the round trip rather than a tick.
The port stays unreffed except while a round trip is outstanding, so it still cannot hold the process open. A flush that never returns surfaces as the harness's existing forced-kill assertion rather than as a wrong count — loud, not silent.
Proof
Rather than rerunning until green, I modelled the real failure: defer every inbound message by 50 ms while preserving per-port order, which is what slow cross-thread delivery looks like from the main thread.
setImmediate: reproduces the CI diff exactly, both counters zero, deterministicallyThat is stronger evidence than a green rerun, which only shows the race went one way once.
Context
This is the fourth assertion found today that measures its environment rather than the product — after two wall-clock budgets calibrated to the maintainer's machine (#150) and a memory bound scaled off allocator noise (#153). Different subsystems, one habit: an assertion whose two sides are not independent.
🤖 Generated with Claude Code