Skip to content

fix(oracle-gaps): supervise the check on win32; log each CLI run in the e2e driver - #79

Draft
KyleAMathews wants to merge 4 commits into
feat/gap-cli-stream-logfrom
fix/win32-supervisor
Draft

KyleAMathews wants to merge 4 commits into
feat/gap-cli-stream-logfrom
fix/win32-supervisor

Conversation

@KyleAMathews

@KyleAMathews KyleAMathews commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

Draft. Stacked on #57 (feat/gap-cli-stream-log); retarget to main once #57 merges.

What this changes

  • Win32 supervisor (commit 0b4297f, plus the fixes after it): every check runs as a supervised child on win32 too. The child is not detached; the supervisor watches its exit and writes the done line, and a stop ends the child's tree with taskkill /T /F (signalTree). The in-process unsupervised path is removed. A win32 out-of-memory abort or crash therefore ends with one done line on both streams and exit 3, as on POSIX (Windows: an unsupervised gap run can leave child processes running (no process tree kill) #74; register P10).
  • Abort witness: ORACLE_GAPS_TEST_ABORT_AT=check aborts the check's process after the session has begun. On win32 it calls process.abort(); on POSIX it sends SIGABRT to itself, because process.abort() prints a native backtrace, which is no line of the stream. The fixture's worker-thread kill is removed from the model.
  • Stream note names the log in forward slashes on every platform (the Windows paths rule). The expected note in the oracle uses forward slashes too.
  • Per-run log (test side only): GAP_RUN_LOG makes the e2e driver append one line per CLI run (its duration, status, signal, and whether the driver's kill timeout ended it).

Evidence

  • Law: a check run ends with one done line on both streams and an exit code the supervisor names (register P10; Windows: an unsupervised gap run can leave child processes running (no process tree kill) #74; the 2026-11-13 Windows fix(windows): Windows CI for the oracle framework and gap CLI, and the path rule #58 entry (e)). win32's abort line names the exit code, since no signal ends a win32 process.
  • Reach: the fixed-seed history "every outcome class" (its abort run) and "an edit sequence through the daemon".
  • POSIX (local, macOS): both histories pass (fixed seed 20261105).
  • Windows daemon history, before the supervisor (run 43601032589 and the earlier runs): 979 s wall, the 900 s test timeout hit with 39 checks; about 900 s spent outside any finished check.
  • Windows daemon history, with the supervisor (run 43617446527): 455 s wall; 224 CLI runs logged; 0 runs ended by the driver's kill timeout (the earlier 900 s went). The test still failed on the note line, which the next commit (678b643) fixes; the count includes shrinking after that failure.
  • Linux daemon history (run 43609191807): 56 CLI runs, 77 s total, all clean exits, 0 kill timeouts.
  • Mutant: no supervisor on win32; the abort run would have no done line (the pre-supervisor Windows runs, e.g. 43598121853).

Open

  • Windows e2e stop runs: the warm stop on win32 wrote no done line in run 43612786521 (the supervisor's stop path on win32). Not yet diagnosed.
  • Windows e2e names: some first lines still show a raw scratch path (the scratch names are not applied to every spelling); not yet fixed.
  • The per-run log and the daemon-history-runs CI job are diagnostics; remove before merge.
  • Limits: taskkill /T reaches the tree only while the child lives; an orphan a test started earlier is not reached (a Job Object would be the fix).

This pull request and its description were written by Isaac.

… the e2e driver

Test-side only: GAP_RUN_LOG names a file the driver appends one line to per
CLI run (runCli and runClisAtOnce): its duration, status, signal, and whether
the driver's 300 s kill timeout ended it. Measures where the daemon history's
time goes on Windows (about 900 s sits outside any finished check).
Diagnostic job daemon-history-runs prints the summary; remove before merge.

Co-authored-by: Isaac <no-reply@databricks.com>
@changeset-bot

changeset-bot Bot commented Nov 14, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 678b643

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@coderabbitai

coderabbitai Bot commented Nov 14, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

…ed path

On win32 the check runs as a supervised child too: the child is not
detached, the supervisor watches its exit and writes the done line, and a
stop ends the child's tree with taskkill /T /F (signalTree). An out-of-memory
abort or a crash on win32 therefore ends with one done error line on both
streams and exit 3, as on POSIX (it wrote none before: a silent failure).
The in-process unsupervised path (its stop line, its startLog, and the
ORACLE_GAPS_TEST_STOP handler outside the supervisor) is removed, since every
check is supervised now.

The abort witness is the CLI's own hook, ORACLE_GAPS_TEST_ABORT_AT=check,
which aborts the check's process after the session has begun (where a V8
out-of-memory abort would strike) instead of a test's kill in a worker thread:
process.abort() on win32, a SIGABRT to itself on POSIX (process.abort prints a
native backtrace, which is no line of the stream). The fixture's test that
killed its own process is removed from the model. win32's done line names the
exit code, since no signal can end a win32 process.

Law: a check run ends with one done line on both streams and an exit code
the supervisor names (register P10; #74). Reach: the 'every outcome class'
history's abort run, on both platforms. RED: the test-side commit's Windows
run (2b11e2b), where an abort gives no done line. GREEN (POSIX, local):
'every outcome class' and 'an edit sequence through the daemon' pass
(fixed seed 20261105). Mutant: no supervisor on win32 (the abort run has no
done line). Limits: taskkill /T reaches the tree only while the child lives
(a grandchild orphaned earlier is not reached; a Job Object would be the
fix); the win32 abort line names the exit code, not a signal.

Co-authored-by: Isaac <no-reply@databricks.com>
@pkg-pr-new

pkg-pr-new Bot commented Nov 14, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/TanStack/oracles/@tanstack/eslint-plugin-oracles@79
npm i https://pkg.pr.new/TanStack/oracles/@tanstack/oracles@79

commit: 9626f00

KyleAMathews and others added 2 commits November 14, 2026 09:46
…n win32

The first win32 run of the supervised check (run 43612786521) failed the
greppable-stream law: the note named the log as out\stream.log, where the
Windows paths rule spells it out/stream.log.

Co-authored-by: Isaac <no-reply@databricks.com>
…tory in forward slashes

Co-authored-by: Isaac <no-reply@databricks.com>
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