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
The "reachability sweep's root/child allowlist fell behind the emitter" bug has recurred four times, each shipping uncompilable output caught only by manual review or downstream validation:
Each fix added one more entry to an allowlist that the next emitter change can outrun. This does not converge on its own — every one produced a dangling reference (Module.type or JsFn.t with no emitted declaration → ReScript compile error) or an orphan file.
Proposal
A single, allowlist-independent post-emit invariant check: after generation writes all .res files, scan each for Module.member references where Module is one of our generated modules (in the written set — stdlib/React skipped) plus bare JsFn.t, and assert each resolves to a declaration actually emitted in that module. Fail loudly (and/or fail the golden/bench suite) on any dangling ref.
That single guard would have caught all four bugs mechanically, regardless of which allowlist was incomplete — converting "the next reviewer finds it" into "CI finds it."
Rollout notes
Hard-fail in the test/golden suite (controlled output — must be clean).
Warn (non-fatal) at generation time for real packages, so a text-parse edge case can't break a user's build.
Acceptance bar: passes clean on all goldens + all benchmark packages (zero false positives on known-good output), and trips on a synthetic dangling ref.
The hard part is distinguishing type refs from value/external refs without false positives — validate against all existing output before making it hard-fail anywhere.
Why
The "reachability sweep's root/child allowlist fell behind the emitter" bug has recurred four times, each shipping uncompilable output caught only by manual review or downstream validation:
indexValue(@set_index) in the usesJsFn survivor scan (Fix #178: recompute usesJsFn after the reachability sweep (no orphan JsFn.res) #197)--variant-propsshadowed branch fields (Fix #178: recompute usesJsFn after the reachability sweep (no orphan JsFn.res) #197 review)Each fix added one more entry to an allowlist that the next emitter change can outrun. This does not converge on its own — every one produced a dangling reference (
Module.typeorJsFn.twith no emitted declaration → ReScript compile error) or an orphan file.Proposal
A single, allowlist-independent post-emit invariant check: after generation writes all
.resfiles, scan each forModule.memberreferences whereModuleis one of our generated modules (in thewrittenset — stdlib/React skipped) plus bareJsFn.t, and assert each resolves to a declaration actually emitted in that module. Fail loudly (and/or fail the golden/bench suite) on any dangling ref.That single guard would have caught all four bugs mechanically, regardless of which allowlist was incomplete — converting "the next reviewer finds it" into "CI finds it."
Rollout notes
externalrefs without false positives — validate against all existing output before making it hard-fail anywhere.Suggested during the reviews of #195 and #197.