Repository navigation
fix(windows): Windows CI for the oracle framework and gap CLI, and the path rule - #58
Merged
Merged
Conversation
The framework, the eslint plugin, and the gap CLI have never run on Windows, and users report path problems there. Two diagnostic jobs run on windows-latest: the unit suites (framework, eslint plugin, gap fast oracles) and the gap CLI end to end (a fixture package written at run time, the plain and daemon paths, and one fixed-seed e2e unit). Both are continue-on-error and each step continues on error, so the first failure does not hide later ones. Neither is a required check or a dependency of preview. Co-authored-by: Isaac <no-reply@databricks.com>
|
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars.
|
commit: |
Diagnostic only, not a fix. The first run showed the gap fast suites and the fixed-seed end-to-end unit hang on windows-latest (cancelled at the job timeout, with no output after the static oracle and the e2e calibrations started). The fast suites now run one file per step with a step timeout and verbose output for the static oracle, so the hang is located. The fixture gets the package.json it was missing (the CLI reported ENOENT for it). The job timeouts are raised to 45 minutes so the split steps can finish. Co-authored-by: Isaac <no-reply@databricks.com>
… run Diagnostic only. Adds a bash replay of the first failing static unit (its verdict is not printed by the run), a run of the fixture with the discovered config instead of --config, and a dump of the gap CLI's error.log files from the OS temp directory, which the daemon run's failure points to. Co-authored-by: Isaac <no-reply@databricks.com>
…ines Forward slashes at entry, native only at the file system. Paths enter the CLI as argv, as Vite and Vitest report them, and as realpath returns them; comparisons and keys use one spelling (oracle-gaps/paths.mjs). - The config wrapper imports the config by a POSIX specifier. A backslash in an ES module specifier is a character, so every run with a config was refused on Windows (check.mjs, wrapper). - Mutant copies are keyed and served in forward slashes, as Vite resolves and Vitest reports them. The copy map was keyed by native paths, so the copies were never served on Windows. - Module IDs are kept by isAbsolute, not by a leading slash: a Windows ID is `C:/...`. - The package root, the located packages, and the source names use the native real path on both sides (realPathOf). The JavaScript realpath kept 8.3 short names such as RUNNER~1 and refused every owns entry. - The daemon listens on a named pipe on win32 (no socket file to remove), keys by the same real path as the CLI, and its timeout names the end of its log. - A package with no package.json is refused, not an internal error. - Replay and rerun lines print PowerShell and cmd forms on Windows; the POSIX form is unchanged. Co-authored-by: Isaac <no-reply@databricks.com>
…e realpath - npm is an npm.cmd shim on Windows; spawnSync runs it through a shell there (package.test.ts, shipped-citations.test.js). - The probe-form oracle's model decides production by a directory named src, split on either separator, not by a substring with `/`. Production was right; the model was wrong on Windows. - The owns test uses the native real path, as the CLI does. Co-authored-by: Isaac <no-reply@databricks.com>
The diagnostic steps are gone. The Windows jobs mirror the Linux shards: the unit suites in one job, the static gap oracle and the fixed-seed end-to-end oracle in three shards each (pr-shards.mjs), and the gap CLI on a fixture, including the discovered config and the daemon. Each job has a 15-minute backstop. The jobs are still continue-on-error until every one is green; that line is removed then. Co-authored-by: Isaac <no-reply@databricks.com>
… path The owners and the instrumenter named files with the platform's separators, and TypeScript matches a file's name as given, so on Windows the owner map keyed `src\x.js` while the sources were `src/x.js`, and CommonJS sites lost their functions. The compiler now gets forward-slash names, and owner keys are forward-slash (schemata.mjs, owners.mjs, analysis.mjs). A path's drive letter is capitalised in the one spelling (paths.mjs), so a drive's case never decides a path. New oracle: gap-report-path-spelling (a metamorphic check). Law 1: the instrumenter gives the same mutant ids for a source under any spelling of its path. Law 2: relativeWithin answers from the segments alone. Evidence block - Law: a path's separators and a drive letter's case do not change what the gap CLI decides (paths.mjs, Windows support, 2026-11-13). - Reach: 200 generated histories (fixed seed 20261113 and random), over four module forms, drives in both cases, mixed separators, short and spaced names. Reach is not declared (states: []); the histories are not measured as reaching a state. - RED: on the parent commit (72b9495), the Windows jobs of #58 failed: the config wrapper import (check.mjs), the copy map, the owner keys (owners.mjs), and the 8.3 short names. On Linux the enumeration law does NOT reproduce the Windows failure: the instrumenter gave the same ids on the parent. The Windows failure is a platform path.relative difference, which Linux cannot produce. The RED for those classes is the Windows CI run. - GREEN: the Windows jobs (see the PR). Local, on macOS: the new oracle 5 of 5, the framework 114 of 114, the eslint plugin 7335 of 7335. - Mutant: relativeWithin as it was before (raw string comparison) fails the relation checkpoint; dropping the drive capitalisation fails it too. Both run on the parent tree with the oracle and both fail (exit 1). - Limits: no declared reach; Law 1 uses the forward-slash spelling as its reference, so it claims only that the spelling changes nothing; owners, realpath, and OS short names are judged by the Windows end-to-end run, not by this oracle. Co-authored-by: Isaac <no-reply@databricks.com>
… witnesses - P10: the Windows CLI runs assert the done line on both streams, and that it matches the exit code (scripts/windows-witness.mjs done). - A package with no package.json is refused with exit 2 and a done line that names it (Windows witness). - One early stop: SIGINT once the CLI prints its first line; the run must end with the stop's done line on both streams, or with no output (#57). - Per-shell replay (framework, accepted by the coordinator): a failing property's PowerShell and cmd lines each reproduce the failure in their own shell. The POSIX line is run in PowerShell and must not reproduce (the RED). A run that printed only the POSIX line fails here (the mutant). - The tsc link lookup in package.test.ts reads npm's Windows shim, not a symlink. - The eslint plugin suite runs even when the framework suite fails. - Job timeouts are 20 minutes, as high backstops (2026-11-12). Co-authored-by: Isaac <no-reply@databricks.com>
…ch packages have a manifest Windows CI failed the classify oracle's baseline law: the CLI prints a PowerShell and a cmd replay line there, and the law read only the POSIX `replay:` line (Difference: "the replay of tests/f0.test.ts is undefined"). The law is unchanged: each replay line the platform prints must read as `vitest run <file> -t <pattern>` in its own shell, and the owed test is the one it selects. On win32 the law owes both per-shell lines; elsewhere the POSIX line (replayLinesOf, powerShellWords, cmdWords). The static oracle's scratch packages had no package.json, which the CLI now refuses (args.mjs). Each fixture now writes a minimal manifest; its content and its histories are unchanged. Evidence block - Law: the replay line of each shell reads as the owed command (Law 9, baseline; the CLI's replay lines, stream.mjs). - Reach: the existing classify histories (276 tests); no new histories. - RED: Windows run 43478073715, classify shard 3 (baseline law, 11 violations) and the static shard 1 refusal (the missing manifest). - GREEN: local POSIX classify 276 of 276. The win32 branch runs in the Windows job (see the PR). - Mutant: not run; the win32 branch is exercised only by the Windows job. - Limits: the win32 branch is checked on Windows only, not by the oracle's own generated histories. Co-authored-by: Isaac <no-reply@databricks.com>
… shipped citations Run 43483101749 (Windows, the first with the witnesses) showed: - The CLI printed `report <pkg>\out\summary.md` and `tests\a.test.ts` in the done line and in the heartbeat. Report paths and display paths are now forward-slash (posix, check.mjs, ending.mjs), as the register's keys rule requires; the file system still gets native paths. - The classify oracle's cmd reader rejected `\"` inside a double-quoted argument, which Node's argument parser reads as a quote. It now reads it so. - The static and classify oracles' second scratch package had no manifest. - Shipped citations joined paths with backslashes, and npm names files with forward slashes. The comparison now uses forward slashes. - The refusal witness searches both streams (a refusal prints to stderr). - The static and fixed-seed e2e took 3 to 6 times their Linux time on Windows, and the Linux shards hit the limit. Windows runs six shards of each (pr-shards.mjs `oracle-gaps-static-windows`, `oracle-gaps-fixed-seed-windows`, checked by `pr-shards.mjs check`: each test in exactly one shard). The classify, probe-form, mutant-validity, and path-spelling oracles run in their own job. Evidence block - Law: report and display paths are forward-slash; a cmd line reads its quoted quotes as Node does (register: deterministic replay; the CLI's keys rule). - Reach: the existing e2e and static histories, unchanged. - RED: run 43483101749, which printed backslash report paths and failed classify on `\"`. - GREEN: pending the next Windows run; local POSIX suites pass (classify 276, shipped citations 2). - Mutant: not run for this commit. - Limits: the Windows e2e and static shard timings are measured on the next run before the budget claim (P12) is made. Co-authored-by: Isaac <no-reply@databricks.com>
…and its models Run 43493431349 (Windows) failed the static and e2e oracles on report paths: the done line names its report in forward slashes (the register's Windows paths rule), but the model built the expected line from the native output directory, and the declared oracle files were keyed by native relative paths (`tests\a.test.ts`), so a heartbeat's file was not an owner. - analysis.mjs, check.mjs: declared oracle files and copies are keyed by their forward-slash relative path (relativeWithin). - gap-report-model-oracle.mjs: the model's expected done line is forward-slash (inline, the model does not import production). - shipped-citations.test.js: the rejection test's strings are forward-slash. Evidence block - Law: keys and report paths use forward slashes on every OS (register, Windows paths, #58); filesystem calls get native paths. - Reach: the existing static and e2e histories; no new histories. - RED: run 43493431349: static 40 refusal-ending violations, e2e 17 baseline lead, 12 report-shaped ending, 4 streaming, 3 greppable stream. - GREEN: pending the next Windows run. Local POSIX: shipped citations 2 of 2, CLI lints clean; the Linux keys are unchanged. - Mutant: not run. - Limits: the Windows e2e and static timings are measured on the next run. Co-authored-by: Isaac <no-reply@databricks.com>
The early-stop step failed on Windows (SIGINT ends the process through TerminateProcess, so the CLI's stop handler never runs; the run ended with a null exit code after its done line), which skipped the replay witness behind it. The replay witness now runs regardless, so each witness reports. Co-authored-by: Isaac <no-reply@databricks.com>
The replay witness found no per-shell lines in the fixture's failing output. This prints the first lines of that output in the same step, so the next run shows what vitest printed. Diagnostic, to be removed with the witness fix. Co-authored-by: Isaac <no-reply@databricks.com>
The replay fixture failed to load (TypeError reading fixedSeeds[0]), so the witness saw no failure. It now declares fixedSeeds: [1]. Co-authored-by: Isaac <no-reply@databricks.com>
… forward-slash done lines - Stop (#57, all-or-nothing) on the unsupervised win32 path: a stop of a run that has started now writes its `oracle-gaps: done stopped (<signal>)` line on both streams and exits 128 + signal, as the supervisor does. A stop before the run starts still prints nothing (index.mjs, runStarted). - Test-only stop hook: when the file ORACLE_GAPS_TEST_STOP names appears, the CLI takes the same stop as a SIGINT (index.mjs). The Windows stop witness uses it (a non-console parent cannot deliver Ctrl+C there; child.kill on win32 is TerminateProcess, which is a SIGKILL-like limit, so no line is owed). - Static oracle: the `unknown` long-argument case uses 30,000 characters on win32. Windows caps a command line at 32,767 characters; a longer one never starts (status null). Narrowing, recorded in the PR: the POSIX runs keep 100,000. - e2e and static model: the expected done line's report path is forward-slash (inline in the model; the e2e corruption check likewise). - The diagnostic Get-Content line is removed. Evidence block - Law: the all-or-nothing stop law (#57) on every platform; keys and report paths forward-slash (register: Windows paths; stop window on every platform). - Reach: the existing static and e2e histories; the stop witness is one run. - RED: run 43498457502, stop witness `stop was not all-or-nothing (signal SIGINT, exit null)`; static `with unknown arguments, the refusal exited null`; e2e `the last stdout line is ... report D:/...`, not `...\out\summary.md`. - GREEN: pending the next Windows run. Local: the CLI lints and loads; the stop witness is queued on the e2e lock for a fixture run. - Mutant: pending (the replay witness, on a throwaway branch). - Limits: OS delivery of Ctrl+C is not exercised on Windows; TerminateProcess is treated like SIGKILL; the win32 argv cap narrows the long-argument case. Co-authored-by: Isaac <no-reply@databricks.com>
…et, and logs The default output directory is under the OS temporary directory, which on windows-latest is `C:\Users\RUNNER~1\...` (an 8.3 short name). The model's expected done line names the package by its real path, so the report path never matched (e2e: `the last stdout line is ... report C:/Users/RUNNER~1/...`). The temporary directory is now taken by its real path (realPathOf) for the state directory, the socket, and the error log. Evidence block - Law: keys and report paths use one spelling; a real path on both sides (register: Windows paths; the realpath rule). - Reach: the existing e2e histories (the done-line law). - RED: e2e run 43515364499, done line with RUNNER~1 vs the package path. - GREEN: pending the next Windows run. - Mutant: pending; the replay witness mutant runs on the throwaway PR. - Limits: the stdout gap-count mismatch (`2 gap lines for 0 gaps`) and the cold internal error in the incremental law are not yet explained. Co-authored-by: Isaac <no-reply@databricks.com>
… real path The e2e oracle realpaths the OS temporary directory with the JavaScript realpath, which keeps the 8.3 name (C:\Users\RUNNER~1). The CLI prints the native real path, so the expected report line never matched. Use realpathSync.native, as the CLI does. Evidence block - Law: one real path on both sides (the realpath rule; Windows paths). - Reach: the existing e2e histories. - RED: run 43515364499 and ee1a5fd: the done line names RUNNER~1. - GREEN: pending the next Windows run. - Limits: the static `output namespace` violations (82 in the last run) are not yet traced. Co-authored-by: Isaac <no-reply@databricks.com>
…es; fix the tsc lookup type - Blocking now: the Windows unit suites, the classify, probe-form, mutant-validity, and path-spelling job, and the gap CLI fixture job with its witnesses (done line, refusal, stop, replay). Their continue-on-error is removed. - Non-blocking, stated in the workflow: the Windows static and e2e jobs, which fail on Windows (tracked in the follow-up PR's body by class). - Linux `Test` failed the typecheck on package.test.ts (the tsc lookup's optional capture). Fixed; tsc --noEmit passes locally. Co-authored-by: Isaac <no-reply@databricks.com>
KyleAMathews
marked this pull request as ready for review
November 13, 2026 23:36
This was referenced Nov 13, 2026
…d review items F1-F8 Review of #58 at ebc39e6 (NOT READY). This commit fixes: - F1 (stop never stops): the witness's stop file is absolute (the CLI's cwd is the package), a stop requires the stopped line on both streams with exit 130, and the stop lands 400 ms after the run starts (the fixture's output is written in one burst near its end, so the first output line is no clock). - F2/F3 (replay quoting): PowerShell reads U+2018 to U+201B as quotes, so every such character is doubled inside single quotes. cmd toggles quoting on every `"` and expands `%`; a name with either has no cmd form, and its cmd line says `use the PowerShell line for this name` (stream.mjs, src/oracle-property.ts). The classify oracle reads each shell's line by that shell's grammar (the PowerShell quote set; cmd's quote toggling, `^`, and `%`), checks the win32 printer on every host, and generates adversarial names (curly quotes, `& | < > ( ) ^ % !`, quotes, backslashes), drawn as the last field of the test record (the fixed seeds' later draws shift; recorded here). - F(f) (POSIX hook): the test-only stop hook lives in the supervisor and goes through its stop, which forwards to the child; a hooked stop gives `done stopped (SIGINT)`, exit 130 (local run: outcome (a)). Unsupervised runs keep the hook in the process. - F5: posix() acts only on win32; on POSIX a backslash is a name's character. - F6: check.mjs realpath of workspace links, report.mjs results path, and ending.mjs error log path are forward-slash and use the native real path. - F7: the blocking Windows jobs are in preview's needs. - F8: the non-blocking jobs point at #72. - The Windows replay witness runs each printed PowerShell line and its cmd line, for two fixtures with hostile names (curly quote and metacharacters; a double quote and `%`). Evidence block - Law: the printed replay line replays in the shell it names (register: deterministic replay across shells; each printed line must replay on Windows); a hooked stop is a stopped line with exit 130 (register: stop window on every platform). - Reach: the classify oracle's 276 generated histories (new adversarial name dimension, drawn last); the Windows replay fixtures; one stop per run. - RED: the parent printer (ebc39e6, with only the platform parameter added) fails the new classify oracle on two names: `"vitest run tests/f0.test.ts -t '^’ t0$'"` (the PowerShell line ends its quote at U+2019) and the cmd line for `q"t` (`which the shell does not read as plain words`). Run locally, exit 1. - GREEN: classify 276/276 on Linux (current code); POSIX stop witness outcome (a), exit 130 (local, under the e2e lock). Windows: pending CI on this head. - Mutant: the parent printer is the mutant (the curly-quote and cmd forms before this commit); the RED run above is its rejection. - Limits: - the stop timing (400 ms after spawn) is an assumption about the fixture's length; a run that ends first is reported as a failure, not passed; - cmd's `!` is literal (delayed expansion off), an assumption; - the classify fixed seeds' later draws shift (the new field is drawn last); - the win32 argv cap, the pipe name's machine scope, the POSIX state paths moving to the temporary directory's real path (an older daemon is found only after its idle timeout), and the unsupervised win32 process-tree exemption (#74) are recorded in the PR body. Co-authored-by: Isaac <no-reply@databricks.com>
… drives only on win32 The Linux run of 50b4ab5 failed gap-report-path-spelling: posix() acts only on win32 (review F5), so on POSIX a backslash is a name's character and a drive letter's case is a different name. The oracle now generates backslash joints and mixed drive letters only on win32; on POSIX it generates `/` joints and `C`. This narrows the law on POSIX (recorded): the POSIX law is the forward-slash spelling, and the separator and drive-case laws are judged on win32 (the Windows classify job runs the oracle there). Evidence block - Law: a path's separators and a drive's case change nothing the gap CLI decides on win32; on POSIX they are name characters (paths.mjs, F5). - Reach: the same 200 histories, with the separator and drive alphabets by platform. - RED: Linux shard 3 of 50b4ab5: "observed value differs" on the path-spelling oracle (2 of 5 tests). - GREEN: local POSIX 5/5. - Mutant: the win32 mutants run in the Windows classify job; not re-run on POSIX. - Limits: on POSIX the separator and drive laws are not generated. Co-authored-by: Isaac <no-reply@databricks.com>
…e POSIX F5 witness Coordinator rulings, applied: 1. Stop trigger: an event, not a clock. The witness writes the stop file on the CLI's first stderr line. Measured (2026-11-14): on a pipe the CLI streams its progress on stderr and prints the done summary (stdout) only at the end, so stdout is no start marker. No stream.log exists on this branch; the stderr line is the event. The 400 ms timer is gone. 2. Classify generator: the hostile names are derived from the test's own fields (HOSTILE[(ms+ti) % 7] for one test in four), not drawn. A drawn field would shift every later draw of the fixed seeds. Proof: `git diff origin/main` on the classify oracle changes no `fc.` line (zero), so the generator is unchanged. 3. Path spelling on POSIX: the oracle generates backslash joints and `x:` drives on every platform. The model splits the spelled strings per platform (win32: both separators, case-insensitive drive; POSIX: `/` only, a backslash is a name's character). On POSIX a disk witness creates the backslash name and asserts it exists, realPathOf keeps it native, and posix() leaves it unchanged (F5). This removes the earlier POSIX narrowing. Evidence block - Law: the stop is delivered at a run event and ends stopped (register: stop window on every platform); a backslash name on POSIX is kept native (review F5). - Reach: the path-spelling oracle's 200 histories, now with backslash and `x:` names on POSIX (disk-backed); the classify oracle's existing histories, with hostile names on one test in four. - RED: ebc39e6 with this oracle: 2 of 5 tests fail, "the observed value differs from the owed value" (the relation and disk checks). - GREEN: POSIX local 5/5 (path-spelling); stop witness local POSIX outcome (a), exit 130 (event trigger). Windows: pending CI on this head. - Mutant: the parent (ebc39e6) is the mutant for F5 (posix() rewrites backslashes on POSIX); its RED is above. - Limits: the stdout summary arrives only at the end on pipes (a finding, not a fix here); the stop trigger assumes the CLI prints a stderr line before its work completes (measured on the fixture only). Co-authored-by: Isaac <no-reply@databricks.com>
The derived hostile names reached constructed tests too (ms 0 at index 0), which
broke the name-relationship reach of two constructed histories ("a failing
baseline test whose name another test's contains" and "... ends another
test's"). A hostile name now applies to generated tests only (ms >= 1).
Evidence block
- Law: the constructed histories reach their declared states (the oracle's own
reach rule).
- RED: de8a373 run: "constructed history ... did not enter a baseline test whose
name another test's contains" (Linux shard 3 and the Windows classify job).
- GREEN: local classify 276/276.
- Mutant: not run.
- Limits: as recorded in the previous commit.
Co-authored-by: Isaac <no-reply@databricks.com>
…prefix rule, witness Round-2 review of #58 (NOT READY). Items addressed: 1. Rerun (cmd) fell back on win32 every time: an absent command was passed as undefined and read as "no cmd form". An absent command is now nothing; only a value that cannot be represented has no form (oracle-property.ts commandOf). The witness runs the Rerun lines (as `vitest run` plus the line) in pwsh, Windows PowerShell 5.1, and cmd. 2. `!` is in the cmd no-form set (framework and printer; DelayedExpansion expands it silently). The classify oracle's fallback test follows. 3. The path-spelling generator's original drive and joint domains are restored (the win32 form at b904d57); the POSIX spelling's backslash names and `x:` drives are an appended `wide` record, used on POSIX only. 4. The witness header, the stop failure text, and the replay comments describe the code (event trigger on the first stderr line; the no-form set). 5. isOutside, the owners' node_modules split, and the capture-setup machinery regex split on `\` only on win32; on POSIX a backslash is a name's character. 6. (see 4) 7. Windows PowerShell 5.1 (`powershell.exe`) runs each PowerShell line, as well as pwsh. 8. configureOracles rejects an envPrefix that is not `[A-Z][A-Z0-9_]*`, with a message (the prefix is printed in replay lines). The unit test follows. Evidence block - Law: the printed command replays in the shell it names, or says it has no form (register: deterministic replay across shells); a Rerun line replays too; `!` is a no-form character (coordinator ruling); a POSIX backslash is a name's character (register: Windows paths, as amended). - Reach: the same histories (the win32 domains are unchanged; POSIX uses the appended wide record). - RED (item 1): round-2 review: plain Rerun lines printed "use the PowerShell line" on win32. - GREEN: classify 276/276, path-spelling 5/5, framework 114/114 (locally, POSIX); Windows: CI on this head. - Mutant: the round-2 Rerun behaviour is the mutant (rerunOf passed an absent command as no form). - Limits: U+2019 is not reached by the seeds in the path-spelling or replay histories; the hostile names are exercised by the witness's fixture names. Co-authored-by: Isaac <no-reply@databricks.com>
…an argument Run 43548823073 (head 2b7b7f3): the Windows CLI job failed on Windows PowerShell 5.1 ("Replay 3 did not reproduce in powershell", a parse exception on the fixture with a double-quoted name). The witness passed the line as a -Command argument, so Node's argument quoting turned the double quote into \" and 5.1 does not read that as an escape. A typed line never passes through an argv: the witness now pipes the line to `-Command -` on stdin, for pwsh and powershell.exe alike. Evidence block - Law: each printed line replays in the shell it names, as a user types it (the register's per-shell rule). - RED: run 43548823073, witness step: "Replay 3 did not reproduce in powershell" (the Windows PowerShell 5.1 parse exception). - GREEN: pending the next Windows run. - Mutant: the argument passing is the mutant (the run above). - Limits: a cmd line is still passed verbatim as an argument (cmd has no stdin command mode here). Co-authored-by: Isaac <no-reply@databricks.com>
…ne that does not reproduce Run 43551132190 (abc8b45): "Replay 3 did not reproduce in powershell" with no reason. The failure now carries the shell's exit code and output, so the Windows PowerShell 5.1 error for the double-quoted name is visible. Diagnostic; the witness's pass and fail rules are unchanged. Co-authored-by: Isaac <no-reply@databricks.com>
… (option c) PowerShell 5.1 passes an embedded double quote in a native .cmd argument wrongly (run 43553461458: a `"`-named fixture selected no test, exit 0). The coordinator's ruling (option c): `-t` is a coarse regular-expression filter, and the exact test is carried by ORACLE_UNIT where a line sets it. - The `-t` pattern (CLI baseline and framework Rerun) replaces each character a shell reads unsafely (`"`, `%`, `!`, the curly quotes) with `.`: still anchored, only slightly broader. - Framework environment values: PowerShell (5.1 and 7) doubles the single and curly quotes, which works for any name; cmd's `set "NAME=value"` tolerates a double quote, and `%` and `!` have no cmd form (environment values only). - Classify oracle: a CLI line has no environment values, so a cmd fallback line is a breach; the -t argument must carry no shell-hostile character. - Witness: each PowerShell Replay line's ORACLE_UNIT and ORACLE_PROPERTY decode to the printed text (round-trip), in addition to the reproduction in pwsh, Windows PowerShell 5.1, and cmd. Evidence block - Law: a printed command replays exactly the unit it names, in each shell (register: deterministic replay across shells; the coordinator's option c). - Reach: the classify oracle's 276 histories (the adversarial names, derived); the Windows fixtures (`’`, `"`, `%`). - RED: run 43553461458: "Replay 3 did not reproduce in powershell", exit 0, PowerShell 5.1 with an embedded double quote in the -t argument. - GREEN: classify 276/276 and framework 114/114 locally (POSIX); the Windows witness runs on this head. - Mutant: the pre-fix pattern (a raw double quote in -t) is the mutant; the RED above is its rejection. - Limits: the -t pattern is slightly broader for names with a hostile character (the wildcard may select a test whose name differs in that position, which the classify oracle's names cannot produce). Co-authored-by: Isaac <no-reply@databricks.com>
…for a line that does not reproduce" This reverts commit 69c82eb.
… fixtures (round-3 review) - F1: a cmd environment value containing `"`, `%`, or `!` has no form (the register's rule); `set "VAR=value" &&` is only emitted for a plain value (oracle-property.ts commandOf). Fixtures: one with a curly-quote property and no `"%!` (a cmd set line runs); one with a single `"` in its property (its cmd line points to PowerShell). - F2: the PowerShell decoder's offset is the value's own position, and decoded values are compared exactly with a failing unit's property and unit, as vitest prints them (`FAIL <file> > <property> > <unit>`). cmd `set` lines decode too and must agree with the PowerShell line. - F3 (partial): Rerun lines carry no ORACLE_UNIT: the framework reads ORACLE_UNIT only for a random unit during a path replay, so a fixed-seed Rerun cannot be selected exactly. Reported to the coordinator. - F6: the path-spelling comment states what it means (no history to keep). - F7: the classify readers reject `!` and judge `set … &&` prefixes; the fallback is allowed wherever the printer uses it (a file path with a hostile character). - F9: control characters in rerunPatternOf are escaped as stream.mjs does (by code point, not a control-character regex). - The witness fails when a failing unit prints no per-shell line (FAIL lines are counted per unit). Evidence block - Law: a printed command replays the failing unit it names, in each shell (register: deterministic replay across shells; the set rule). - Reach: the classify oracle's 276 histories; the Windows fixtures. - RED: run 43555531142 and the coordinator's round-3 review at ae44184 (a `"` in a set value broke `&&`). - GREEN: classify 276/276, framework 114/114, locally (POSIX). Windows: this head. - Mutant: the pre-fix env rule (a `"` in a set value) is the mutant. - Limits: Rerun lines are not exact (see F3). Co-authored-by: Isaac <no-reply@databricks.com>
…uns on the package's PATH Run 43561333340 (9698922), Windows CLI job: "2 random units failed, but 4 Replay lines printed" (vitest repeats a failing unit's error text, so its replay lines repeat), and every line failed with "'vitest' is not recognized" (the rewritten runIn dropped the PATH that adds the package's node_modules/.bin). - Each distinct printed line counts once, in first-occurrence order. - Every shell runs with the package's binaries on PATH. Evidence block - Law: a printed command replays in each shell it names (the register's per-shell rule); each failing unit prints one line (witness rule). - RED: run 43561333340, the witness: "4 Replay lines printed" for 2 random units; "'vitest' is not recognized". - GREEN: pending the next Windows run. - Mutant: not run. - Limits: as in the previous commit (Rerun lines are not exact). Co-authored-by: Isaac <no-reply@databricks.com>
… line and checks coverage Run 43563021693 (257a5b0): "2 random units failed, but 4 Replay lines printed" and "Replay 4 has no cmd line": a failing fixed unit prints its replay under the random unit's name, so one failing unit can have more than one replay line, and index pairing breaks. A random unit's violation also prints its replay under the Rerun label, so a Rerun line can carry ORACLE_ variables, and running it with `vitest run` in front broke it. - Each distinct PowerShell line pairs with the cmd line printed after it. - A line that carries ORACLE_ variables is a replay and runs as printed; a bare -t line is a rerun and runs as `vitest run` plus its arguments. - Coverage: every failing unit is matched by a replay whose ORACLE_PROPERTY and ORACLE_UNIT decode to its names (a fixed unit by the random unit it replays). Evidence block - Law: every failing unit prints a replay that names it exactly, and each printed command replays in each shell it names (register: deterministic replay; the witness rule). - RED: run 43563021693: "2 random units failed, but 4 Replay lines printed"; "Replay 4 has no cmd line"; "Rerun 2 did not reproduce in cmd". - GREEN: pending the next Windows run. - Mutant: not run. - Limits: a bare Rerun line is not exact (see F3). Co-authored-by: Isaac <no-reply@databricks.com>
…ewrite removed Run 0c42c33 (the Windows CLI job): "ReferenceError: decodePs is not defined". The pairing rewrite replaced the block that held the FAIL map, the PowerShell and cmd decoders, and the no-form constant. They are restored, and a local smoke run of the replay branch on a fabricated output reaches the report (pwsh is absent on this Mac, so its runs fail as expected; no reference error). Evidence block - Law: the replay witness reports a failing unit's printed commands (witness rule). - RED: run 0c42c33: ReferenceError in the replay step. - GREEN: pending the next Windows run. - Mutant: not run. - Limits: as before. Co-authored-by: Isaac <no-reply@databricks.com>
… (F3 ruling b) The coordinator's ruling: Rerun lines stay coarse -t filters (a sibling whose name the anchored pattern matches also runs). The witness now counts a Rerun line only when the failing fixed unit whose exact name it selects shows its own FAIL line in its output, so a sibling's failure cannot satisfy it. An exact selector is tracked in #78; Replay lines select exactly, through ORACLE_PROPERTY and ORACLE_UNIT. Evidence block - Law: a Rerun line runs the failing unit it names, and only it counts (register amendment: Replay lines select exactly; Rerun lines are anchored, coarse filters). - Reach: the Windows fixtures (the `Q"1` unit has no Rerun line in CI; the sibling case is the Limit's example). - RED: none in CI yet; the sibling case is not exercised by the fixtures. - GREEN: pending the next Windows run. - Mutant: not run. - Limits: a sibling case is not in the CI fixtures (recorded in the PR body). Co-authored-by: Isaac <no-reply@databricks.com>
… 1: <name>`) Run 43569602268 (bd208ac): "Rerun 1 selects no failing fixed unit" for both fixtures. The FAIL regex expected `fixed seed: ` with no number, but vitest prints `fixed seed 1: <name>`, so no fixed unit was recorded. (The earlier fix attempt did not apply; this commit applies it and checks the match.) Evidence block - Law: a Rerun line counts only for the failing fixed unit whose exact name it selects (witness rule; register: Rerun lines are anchored coarse filters). - RED: run 43569602268: "Rerun 1 selects no failing fixed unit". - GREEN: pending the next Windows run. - Mutant: not run. - Limits: as recorded in the PR body (sibling case, #78). Co-authored-by: Isaac <no-reply@databricks.com>
Run 43571581118 (3b97795): each Rerun line reproduced (exit 1, "Failed Tests 1"), but the check that the failing unit's exact name appears in its output failed: vitest colors the output, so the name is split by color codes. The witness now strips the color codes before it matches a unit's name. Evidence block - Law: a Rerun line counts for the failing fixed unit whose exact name it selects and whose FAIL line its output shows (witness rule). - RED: run 43571581118: "Rerun 1 did not reproduce in pwsh (exit 1 ... Failed Tests 1)" with the name check failing. - GREEN: pending the next Windows run. - Mutant: not run. - Limits: as recorded in the PR body (sibling case, #78). Co-authored-by: Isaac <no-reply@databricks.com>
… control-name oracle case (F3, F9, L2, L3)
- F3: a Rerun line counts only when its target's whole FAIL line appears,
anchored to the end of the line, after the color codes are removed. `generated2`
does not satisfy `generated`. The comment now says so.
- F9: the classify oracle's hostile names include a control character (U+0001).
The printed `-t` pattern escapes it as `\u0001` (stream.mjs escapeControls).
The register says controls become `.`; the code escapes them, and the code is
right (the coordinator's correction).
- L2: the CI step prints replay-out.txt before the witness reads it.
- L3: a third fixture, `fixture 100% done!`, witnesses the cmd env no-form branch.
Evidence block
- Law: a printed pattern carries no raw control character (the printer's escape
rule); a Rerun line counts only for its exact target (witness rule).
- RED (F9): dropping escapeControls from the CLI printer fails 4 classify tests
("the stdout has a line that is not a line of the stream"), exit 1, locally.
- GREEN (F9): classify 276/276 with the U+0001 name, locally (POSIX).
- GREEN (F3): the exact-match regex accepts `generated` and rejects `generated2`
(checked locally); Windows: the next run.
- Mutant: dropping escapeControls (above).
- Limits: the framework's own Rerun escaping has no oracle; the Windows fixtures are
the only witness for it (L6 and L1 are filed).
Co-authored-by: Isaac <no-reply@databricks.com>
KyleAMathews
added a commit
that referenced
this pull request
Nov 14, 2026
Both sides kept: #58's path rule (isAbsolute for module ids, posix keys only on win32) and #55's fs inputs. The fs recorder now keys a read by the same rule (paths.mjs, which the copied capture setup cannot import): forward slashes and a capital drive letter on win32, the path as it is on POSIX, and the native path for the file system. #55's fixed-seed units take places in the Windows e2e shards (pr-shards.mjs). Co-authored-by: Isaac <no-reply@databricks.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.
Summary
Makes Windows a blocking part of CI for the oracle framework and the gap CLI, and fixes what broke there. The Windows static and e2e gap oracles are not blocking yet: they still fail on windows-latest and are tracked by class in #72 (and in the follow-up PR #73).
This revision also answers the independent review at ebc39e6 (NOT READY): the stop witness that never stopped (F1), replay quoting by the shells' real grammars with adversarial names (F2, F3), the POSIX stop hook through the supervisor (F(f)), forward-slash only on win32 (F5), the native-path misses (F6), preview's needs (F7), the #72 links (F8), and the pipe-scope limit (F9).
Changes
realpathSync.nativeon both sides, including the temporary directory), the report, done-line, and error-log paths.oracle-gaps: done stopped (<signal>)on both streams when a stop lands after it has started. The test-only hookORACLE_GAPS_TEST_STOP=<file>takes the stop path of SIGINT: in a supervised run, the supervisor's stop, which forwards to the child (a hooked stop isdone stopped, exit 130).\\.\pipe\oracle-gaps-<key>), keyed by the same real path as the CLI; a timeout names the end of the daemon's log.-targument never carries a shell-hostile character (",%,!, curly quotes): each becomes the pattern's.(option c, a coordinator ruling). The exact test is inORACLE_UNIT/ORACLE_PROPERTY: the witness decodes each PowerShell and cmdsetvalue and compares it exactly with the failing unit's names as vitest prints them. cmd has no form for an environment value with",%, or!(the register's rule, corrected in round 3): its line says so and points to the PowerShell line. The-tsubstitution applies on every platform, so POSIX-toutput also differs (a.where a hostile character was). PowerShell's quotes include U+2018 to U+201B, and each is doubled inside a single-quoted value.package.jsonis refused (exit 2, named in the refusal).gap-report-path-spelling(new, metamorphic); the classify oracle reads each shell's replay line by its grammar on every host, and generates adversarial names; the models' expected done lines are forward-slash; the static scratch packages have a manifest.srcdirectory segment; the owns test uses the native real path; the tsc link is read from npm's Windows shim; shipped citations are forward-slash.previewneeds the blocking jobs. Non-blocking,continue-on-error, pointing at Windows static and e2e gap oracles: remaining failures by class (non-blocking on #58) #72: the static and e2e jobs (six shards each).Decisions
Register entries (
~/.cache/oracle-grammar/decisions-register.md) this PR touches:child.kill('SIGINT')on win32 is TerminateProcess, treated as SIGKILL.package.jsonis a refusal (C): user-file errors are refusals; the POSIX static oracle covers it.src/oracle-property.tsships inside@tanstack/oracles; test-time packages do not count against it.Evidence
fc.lines differ from main); the path-spelling oracle's POSIX spellings are an appendedwiderecord (drawn last), and its win32 fields keep their original domains (restored in round 3; the POSIX spellings are an appendedwiderecord);gap-report-path-spellingruns 200 histories.^’ t0(the PowerShell line ends its quote at U+2019, which a PowerShell reader does not read as plain words), and the cmd line forq"t t0(which the shell does not read as plain words). Since the names are derived, the current seeds reach a double quote but not U+2019; the U+2019 PowerShell case is covered by the Windows witness's fixture (fixture ’ & | < > ( ) ^ ! replay), not by the oracle's seeds. Local, exit 1.cmd has no formline, as designed (that run predates the round-3 cmd rule and the option-c-trule).stop outcome (a), exit 130. Windows (run 43535601236):stop outcome (a): stopped line on both streams, exit 130.Publish preview, which needs the blocking Windows jobs); blocking Windows jobs green (unit suites, classify/probe-form/mutant-validity/path-spelling, CLI fixture job with its witnesses). Non-blocking Windows static (6) and e2e (6) shards fail (Windows static and e2e gap oracles: remaining failures by class (non-blocking on #58) #72).x:drive are generated and kept native, with a disk-backed witness (realPathOf keeps the name; posix() leaves it; RED on ebc39e6: 2 of 5 tests).tsc --noEmitpasses; classify 276/276; shipped citations 2/2.src/oracle-property.ts(the shipped runtime) +204 bytes at ebc39e6; the cmd and PowerShell helpers of this revision are not re-measured here. Test-time CLI modules add about 880 bytes in total;paths.mjs345 (not counted against zero shipped bytes).Limits
unknownlong-argument case uses 30,000 characters on win32 (100,000 on POSIX).-tfilters (coordinator ruling, F3): a fixed-seed unit has no exact selector, so its Rerun line can also run a sibling whose name the anchored pattern matches. Example: a unitfixture Q"1 replayand a siblingfixture Q21 replay. The witness counts a Rerun line only when its own failing unit's exactFAILline appears in its output, so a sibling's failure cannot satisfy it. An exact selector is tracked in Framework: an exact selector for a fixed-seed unit (Rerun lines are coarse -t filters today) #78 (a framework feature, not part of this PR). Replay lines select exactly, through ORACLE_PROPERTY and ORACLE_UNIT.!is a no-form character for environment values (a coordinator ruling, conservative: DelayedExpansion would expand it silently).Follow-up
The static and e2e Windows failures, and the re-shard under 9 minutes, are tracked in #72 and continue in #73.
This pull request and its description were written by Isaac.
Final check (head 7d46701)
!in their names except where the cmd branch is checked:fixture 100% done!(L3) exercises the cmd env no-form branch, and the replay output is printed in the CI log (L2).-tpattern escapes control characters as\uXXXX, so the register's "controls become." is wrong and the code is right (coordinator's correction). Evidence: the classify oracle's control-name case (U+0001); droppingescapeControlsfrom the printer fails 4 classify tests.src/oracle-property.ts(minified, gzipped, esbuild, against origin/main): 29,070 -> 29,921 minified bytes (+851); 11,059 -> 11,445 gzipped (+386).&&inside quotes, so thesetprefix branch is not reached) and L6 (compare Rerun pairs across shells).