Closes the observability loop: the log + breadcrumb + watchdog files are now
collected by CI so a wedged run leaves downloadable evidence instead of
nothing.
- logDirectory(): CLIDE_LOG_DIR overrides the per-platform default, so CI can
point the logs at an uploadable workspace dir (and tests at a temp dir).
Now takes an injectable env map; tested.
- test_app.dart: when CLIDE_LOG_DIR is set, the testmode harness tees its
logger to a FileLogSink + spawns the watchdog (off by default — normal
run-testmode keeps the stderr-only path, no isolate). _say breadcrumbs each
test into the file.
- conpty_orphan_probe.dart: with CLIDE_LOG_DIR set it passes a verbose PtyLog,
so when soak-conpty-kill.ps1 force-kills the parent, the reader/waiter
isolates' LAST crumb is fsynced to disk — naming what the wedged isolate was
doing at the instant of death.
- bundle-smoke job: runs the real release app with CLIDE_LOG=debug +
CLIDE_LOG_DIR, uploads clide-logs (watchdog heartbeat/sample + FileLogSink)
in an always() step.
- windows-soak kill-probe job: sets CLIDE_LOG_DIR, uploads the FFI crumbs.
Coverage gate 95.08%.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The clean-path soak found no leak on windows-latest — because orderly close()
reaps every host. That never exercises the freeze hypothesis (T-424), which is
the parent dying WITHOUT teardown while a child is live.
This probe does. conpty_orphan_probe.dart starts N real WindowsPty sessions on
long-lived children and blocks WITHOUT ever calling close(); soak-conpty-kill.ps1
force-kills only the dart.exe parent (taskkill /F, no /T) once the hosts are up
and counts the conhost/OpenConsole/cmd processes that SURVIVE. Absent a
kill-on-close Job Object, abrupt parent death should orphan them — a survivor
count that climbs across cycles is the leak signature. The same probe will prove
the T-424 fix: with the job, survivors should drop to ~0.
Wired as a second job in windows-soak.yml (workflow_dispatch + when the kit
changes). Diagnostic only, never a gate, always exits 0; publishes the verdict
to the job summary and uploads the CSV. Not part of the regular test suite.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>