Skip to content

feat(repo): let import closure accept dry-run module evidence - #222

Merged
kiro-systemf[bot] merged 5 commits into
mainfrom
stryker/closure-evidence-closure
Oct 7, 2026
Merged

kiro-systemf[bot] merged 5 commits into
mainfrom
stryker/closure-evidence-closure

Conversation

@systemfsoftware-maker

@systemfsoftware-maker systemfsoftware-maker commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Layer 2 of 3. ImportClosure.analyzeImportClosure accepts optional observedModules: 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_modules files stay external leaves. A reached computed import() no longer opens the closure.

  • Still open:

    • an observed key that is not an absolute path to an existing file (for example a data: URL, or a deleted path);
    • a parse error;
    • an unresolved static specifier.

    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

  • Failing-before: "Observed modules from the dry run close the closure around the file they name". With the previous import-closure.cell.ts in a scratch worktree, it got { files: ['test/plugin.test.ts'], open: true, unreachedChangeMoved: true }, but expected src/plugin.ts listed, open: false, and unreachedChangeMoved: false. 1 of 19 failed. On the branch, 19 of 19 pass, including the no-evidence baseline, data: key and missing-path scenarios.
  • On the stack head: the full stryker-js suite passes (231 files, 1250 tests). Format, typecheck, lint, guard:projects (Verdict-Semantics: unchanged) and the changeset check exit 0.
  • Changeset: minor, because the exported function gains an input.

CI notes

  • The stack was rebased onto 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.
  • Run 37583869355 (pre-rebase): check failed on one 60 s timeout in incremental-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.
  • Run 37586283812: e2e (rest-1) stopped in its E2E lane step and hit the 30-minute job limit; the four other lanes and check passed. 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.

@systemfsoftware-maker
systemfsoftware-maker added this pull request to stack #224 October 7, 2026 06:51
@systemfsoftware-maker systemfsoftware-maker changed the title stryker/closure evidence closure feat(repo): let import closure accept dry-run module evidence Oct 7, 2026
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
systemfsoftware-maker force-pushed the stryker/closure-evidence-closure branch from ed78590 to 3bffb77 Compare October 7, 2026 07:16
Base automatically changed from stryker/closure-evidence-runner to main October 7, 2026 08:26

@kiro-systemf kiro-systemf Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Layer 2: optional observedModules; inert until layer 3; unresolvable evidence keeps the closure open.

@kiro-systemf
kiro-systemf Bot merged commit fa92d56 into main Oct 7, 2026
8 checks passed
@kiro-systemf
kiro-systemf Bot deleted the stryker/closure-evidence-closure branch October 7, 2026 09:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant