Skip to content

feat(oracle-gaps): write the stream to <out>/stream.log and name it in the first line - #57

Open
KyleAMathews wants to merge 5 commits into
mainfrom
feat/gap-cli-stream-log
Open

KyleAMathews wants to merge 5 commits into
mainfrom
feat/gap-cli-stream-log

Conversation

@KyleAMathews

@KyleAMathews KyleAMathews commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The oracle-gaps run owns its stream log, <out>/stream.log. The supervisor opens the log and writes the note line before it starts the child, so a stop at any point after the note still leaves the log and both streams naming it. --out is resolved once and passed to the child and to the daemon request, so a run, its daemon check, and its stream log share one output directory. A second run on a live output directory is refused without writing into it (maintainer decision of 2026-11-13). A stream log that cannot be opened is refused before any check starts.

Review findings, and what this PR does with each:

  • F1 is refuted. The e2e missingSource fault is an owns entry in a test file that names a missing source (tests/b.test.ts: owns entry src/missing.ts#f0 names a missing file). The analysis refuses it after the check has started, so its stdout owes the note line; the model's [note, done] expectation is correct, and the history passes on the parent commit. The argument-stage case, a --source that is not a file of the package, is refused inside parseArgs and is the static oracle's absentSource, which already expects the done line alone. The model now carries a comment saying so.
  • F2 (default --out) fixed. RED: the stop and daemon histories with the default output directory fail on the parent commit.
  • F3 (unwritable log) fixed. RED: the pre-created directory history fails on the parent commit with an EISDIR line on stderr.
  • F4 (two runs on one --out) fixed, per the maintainer decision of 2026-11-13. RED: the second run exits 0 on the parent commit.
  • F5 (V8 FATAL block): the child's raw stderr is now teed to stream.log. Judged by inspection only; see Limits.
  • F6: the changeset and README now say cold runs stream to the log while they run, and a daemon run's lines arrive at the end of its check.
  • F7: fixed by design (the note is written before the child exists).
  • F8: argument refusals and pre-check refusals assert that no stream log exists (end-to-end and static oracles).
  • F9: the two stream-log calibrations are bound to a completing history and guard cli.exit !== 0.
  • F10: the stream-log comparison no longer drops blank lines.
  • F12: the README's inline code no longer wraps across lines.

Evidence

Law. A run that starts a check names its stream log in its first line on both streams. <out>/stream.log holds the stderr lines in order, and its last line equals stdout's done line. A completed run's results.json sits beside that log. A refusal of the arguments, or any refusal before the check starts, writes no stream log. A second run on a live output directory exits 2 with one refusal block naming the directory, writes nothing there, and leaves the first run's stream log equal to its stderr. Authority: the maintainer decisions of 2026-11-12 (stream log) and 2026-11-13 (live-directory refusal), and the refusal law (law 12) in the gap-report oracle.

Reach. Each new dimension is declared in required and reached by a constructed history: a stop with the default output directory, a daemon check with the default output directory, a stream log that cannot be written, and two runs on one output directory. Each is also run as a fixed-seed, random-seed, and determinism unit (12 units). Generated-campaign reach was not measured.

RED (parent commit 23b47d5, production unchanged; /tmp/gapwork/RED-batch.log):

  • stop, default output directory: stream.log is not its stderr, line for line
  • daemon, default output directory: the run completed, but its results.json is not beside its stream log
  • blocked stream log: an EISDIR line on stderr
  • two runs on one output directory: the second run on a live output directory exited 0, not refusing it

GREEN (with this change; /tmp/gapwork/batch-green.log, count-checked, BATCH PASS): the four histories and the two calibrations, 6 of 6. The timing run (/tmp/gapwork/measure12-r2.log) passes all 12 units: the stop unit takes about 3 s and the daemon unit about 5 s.

Mutant (each restored afterwards, each run against the same histories):

  • F2: the supervisor does not pass --out to the child or daemon. The stop and daemon histories fail.
  • F3: the stream log's open check is removed. The blocked-log history fails.
  • F4: the live-run refusal is disabled. The overlap history fails.

Suites. Gap fast suites (static, classify, probe-form, mutant-validity): 33891 of 33891 pass (/tmp/gapwork/fast-r2.log). e2e-shards check and pr-shards check both pass.

Limits

  • The full fixed-seed campaign was not run. Only the new units, the calibrations, and the fast suites were run.
  • The static oracle does not draw logBlocked or overlap, because it creates no stream log and runs no second CLI process. The end-to-end histories own those two dimensions. The clearing lives in one named function (staticResolve).
  • The stop history uses a stop-only witness (w_stop alone). The stop law and its observation are unchanged; the capture witness is not in that history.
  • F5: the V8 out-of-memory block is teed to the log by inspection. No history reproduces V8's FATAL output.
  • A stream.log that fails mid-run (removed, replaced, or disk full) is not judged. The supervisor's done-line append is guarded, but a failure in the raw-stderr tee is not handled, so the supervisor could print a stack trace in that case. Not tested.
  • A daemon-run's lines reach the file only at the end of its check.
  • The run.pid claim is by process id. A pid reused by an unrelated live process refuses a directory whose run has ended (a false refusal), and the claim is not atomic across two starts beyond the exclusive create. Not tested beyond the overlap history.
  • F10 (blank lines) has no separate RED. It is covered by the shared stream laws.
  • F7 is covered by design (the note is written before spawn), not by a dedicated stop-before-note history.
  • The two stream-log calibrations were bound first to a history whose clean trace is itself RED, a harness error; they are now bound to two authored mutants.
  • e2e-shards.mjs now calls pnpm --silent exec vitest list, because pnpm's workspace banner broke the JSON parse.
  • The pre-commit hook reformatted the staged files (prettier, eslint). The formatting is whitespace only; the tests were run before formatting.

This pull request and its description were written by Isaac.

KyleAMathews and others added 4 commits November 12, 2026 20:17
The maintainer's decision of 2026-11-12: an agent that runs a check in
the background learns where to read its stream from the run itself. A run
that starts a check names `<out>/stream.log` in its first line on both
streams (`oracle-gaps: note log <path>`), and that file holds the
stderr's lines, in order, cold, through the daemon, and after a stop or
an abort. The driver records each run's first lines and whether its log
equals its stderr; two calibrations give a log that misses a line and a
naming line after another line.

Co-authored-by: Isaac <no-reply@databricks.com>
…og first

The maintainer's decision of 2026-11-12 names the stream log first in
every run that starts a check, refusals in it included. The refusal law
(#46) owed stdout = the done line alone; it now owes [note log, done
line] when the check started, and [done line] for a refusal of the run's
arguments, which comes before any check (outsideSource, and the static
oracle's argument refusals). Law 15's log checks apply to runs that start
a check.

Co-authored-by: Isaac <no-reply@databricks.com>
…irst

A run that starts a check creates `<out>/stream.log`, writes
`oracle-gaps: note log <path>` as its first line on both streams, and
writes every stderr line to the log too: the cold check's lines, a daemon
reply's stderr, an internal error's or refusal's ending, the completed
done line, and the supervisor's own done line for a stopped or crashed
run.

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

changeset-bot Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 5a92a3e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@tanstack/oracles Patch

Not sure what this means? Click here to learn what changesets are.

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

@coderabbitai

coderabbitai Bot commented Nov 13, 2026 •

Copy link
Copy Markdown

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a65ce076-89de-496e-9500-7a64c3a51641
  • 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

@pkg-pr-new

pkg-pr-new Bot commented Nov 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

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

commit: 23b47d5

…nd run on a live --out

The supervisor opens <out>/stream.log and writes the note before it spawns
the child; it resolves --out once and passes it to the child and to the
daemon request; it tees the child's stderr, V8 lines included, to the log.
A run whose log cannot be opened is refused before any check (exit 2, one
done line), and a second run on a live output directory is refused without
writing into it (maintainer decision, 2026-11-13).

Oracle: out-mode (explicit or default) and log-blocked and overlap
histories, with the law that a completed run's results.json sits beside its
stream log and that a refused run writes nothing into a live directory.
Stop histories use the stop-only witness.

Co-authored-by: Isaac <no-reply@databricks.com>
KyleAMathews added a commit that referenced this pull request Nov 13, 2026
… 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>
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