* fix: stabilize replay nightly fixture boundaries
* test: stabilize exit flush integration coverage
* chore: drop the deleted exit-naive fixture from fallow's entry list (#1610 review P3)
* fix: flush stdout/stderr before every CLI process.exit() (#1596)
Node only flushes process.stdout/stderr synchronously to a file or TTY;
on a pipe (the normal condition for this CLI when driven as a
subprocess) a write queued right before process.exit() can be silently
dropped. handleRunCliFailure's --debug daemon-log-tail dump made this
reachable from the exact path that renders a SESSION_NOT_FOUND error
right after a daemon replace, matching field reports of the driving
process going silent immediately after "Replacing daemon ... unreachable"
plus the SESSION_NOT_FOUND error.
Add exitAfterFlush() and route every process.exit() in src/cli.ts and
src/bin.ts through it, so a piped caller always receives the full
structured error (with its "run open first" hint) before the process
terminates. Also bound the --debug log-tail dump to a byte cap instead
of an unbounded 200 lines.
Verified directly against the real CLI (piped subprocess, pre-fix vs
post-fix): a live daemon with a seeded >64KB log truncates its --debug
error output before the fix and delivers it in full after.
* fix: satisfy CI gates on #1596 (format, fallow, coverage)
- oxfmt formatting on the new integration test file.
- Register the two exit-flush regression fixtures (support/exit-naive.ts,
support/exit-after-flush.ts) as fallow entry points: they're run as real
subprocesses via a string path (runCmdSync), which fallow's static
dependency analysis can't follow, same as the existing
test/contention-retry-fixtures/* entries. exit-payload.ts becomes
reachable transitively through their static imports. Also switched the
integration test's local PAYLOAD_MARKER duplicate to import the one
fallow flagged as unused from exit-payload.ts.
- Added real unit coverage for the new exitAfterFlush code paths, since
node --test integration files aren't measured by the vitest coverage
gate: src/utils/__tests__/process-exit.test.ts exercises the
already-drained, backlogged-then-drains, and never-drains/timeout
branches directly against a fake stream; src/__tests__/cli-exit-paths.test.ts
drives runCli() for --version, bare help, no-command, and web to cover
their exitAfterFlush call sites, plus a --debug case with a >64KB seeded
daemon.log proving printDaemonLogTailOnError's new byte cap actually
trims the oldest lines.
Changed-line coverage gate now passes at 92.59% (was 59.26%); the two
remaining uncovered lines are the bottom-of-file `isDirectRun` catch
handler, which only runs when cli.ts is executed as the literal entry
script and is not reachable by importing it as a module in a test (the
same shape as bin.ts's already-excluded top-level fast paths).