Repository navigation
feat(repo): let import closure accept dry-run module evidence - #222
Merged
Merged
Conversation
systemfsoftware-maker
added this pull request to stack #224
October 7, 2026 06:51
The vitest runner collects Vitest's per-worker module execution record at the end of each dry-run test file and returns it as testFileModules, keyed by the absolute test file path with node: builtins dropped. The complete DryRunResult now carries the optional field so an incremental run can close a test file's closure from the modules it actually evaluated Verdict-Semantics: unchanged
ImportClosureInput gains an optional observedModules record, and a computed dynamic import no longer leaves a test file's closure open once the runner reports the modules that test file actually evaluated. Observed modules that name existing files join the closure as extra roots scanned and hashed like statically reached files; a key that is not an absolute path to an existing file, a parse error, or an unresolved static specifier still opens it. Nothing supplies the evidence yet, so the layer is inert in production Verdict-Semantics: unchanged
systemfsoftware-maker
force-pushed
the
stryker/closure-evidence-closure
branch
from
October 7, 2026 07:16
ed78590 to
3bffb77
Compare
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.
Summary
Layer 2 of 3.
ImportClosure.analyzeImportClosureaccepts optionalobservedModules: for each test file, the modules a dry run saw it load. Nothing passes it until layer 3, so production behavior is unchanged.Rules
No evidence for a test file: exactly today's behavior.
With evidence: each observed key that names an existing file becomes a root of that test file's closure. Its sources are scanned and hashed like statically reached files, and
node_modulesfiles stay external leaves. A reached computedimport()no longer opens the closure.Still open:
data:URL, or a deleted path);The scanner now keeps dynamic-site openness separate from the other two kinds, so evidence can discharge only the first.
Digest: it covers names plus contents, so adding, removing or editing an observed file moves it.
Borrowed: depfile semantics. The recorded inputs are part of the key, so a stale observation can only cause a refusal, never a false reuse. Rejected: listing allowed specifiers in the scanner.
importModule's targets are user files, so no closed list exists.Validation
import-closure.cell.tsin a scratch worktree, it got{ files: ['test/plugin.test.ts'], open: true, unreachedChangeMoved: true }, but expectedsrc/plugin.tslisted,open: false, andunreachedChangeMoved: false. 1 of 19 failed. On the branch, 19 of 19 pass, including the no-evidence baseline,data:key and missing-path scenarios.Verdict-Semantics: unchanged) and the changeset check exit 0.minor, because the exported function gains an input.CI notes
780315fef(an @effect/tsgo bump). Locally, after the rebase: format, typecheck and lint exit 0; stryker-js passes 231 files / 1250 tests and the vitest-runner suite passes.checkfailed on one 60 s timeout inincremental-reuse"A refused re-run starts a mutant with its previous killing test". That scenario runs the engine three times inside one 60 s test. It passed on feat(repo): report each test file's evaluated modules on the dry run #221 and feat(repo): wire dry-run module evidence into closure analysis #223 (which contain this code), and in run 37586283812 after the rebase.e2e (rest-1)stopped in its E2E lane step and hit the 30-minute job limit; the four other lanes andcheckpassed. GitHub keeps no log for the cancelled job, and the timeout skipped the telemetry export, so there is no trace to read. This code passed rest-1 before the rebase (run 37583869355), and feat(repo): wire dry-run module evidence into closure analysis #223, which contains it, passed rest-1 on the same base (run 37586281318). It is the first lane to hit the 30-minute limit in any CI run since 2026-10-04. The token here cannot rerun jobs, so job 112677039983 needs a rerun by someone with Actions write access.