fix(pty): IsolateCrumbFile creates its parent dir (soak crumb capture)

The T-436 soak run came back green but produced no conpty-kill-crumbs artifact:
IsolateCrumbFile opened its append handle without creating the parent dir, and
the standalone orphan probe points it at a fresh CLIDE_LOG_DIR that nothing
else had made — so openSync failed, the crumb file was disabled, and no crumbs
were written. In the app this was masked because FileLogSink already creates
logDirectory() at boot. Create the parent ourselves (no-op when it exists).
Verified by the bundle-smoke artifact, which DID capture a real watchdog sample
(threads=31, handles=25, rssMB=175) because the release app makes the dir.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-15 11:13:07 +02:00
co-authored by Claude Opus 4.8
parent 514feefccf
commit f8477816c4
2 changed files with 14 additions and 1 deletions
+6 -1
View File
@@ -65,7 +65,12 @@ class IsolateCrumbFile {
IsolateCrumbFile(String? path, this.source, {int capBytes = 256 * 1024}) : _capBytes = capBytes {
if (path == null) return;
try {
final raf = File(path).openSync(mode: FileMode.append);
final f = File(path);
// Create the parent dir ourselves — a standalone caller (the soak probe)
// may point us at a dir nothing else has made yet. In the app the
// FileLogSink already created logDirectory(), so this is a no-op there.
f.parent.createSync(recursive: true);
final raf = f.openSync(mode: FileMode.append);
_raf = raf;
_size = raf.lengthSync();
} catch (_) {
+8
View File
@@ -44,6 +44,14 @@ void main() {
c.close();
});
test('creates a missing parent directory (standalone soak probe case)', () {
final nested = '${dir.path}${Platform.pathSeparator}a${Platform.pathSeparator}b${Platform.pathSeparator}crumbs.log';
final c = IsolateCrumbFile(nested, 'conpty.reader')..crumb('ReadFile enter');
c.close();
expect(File(nested).existsSync(), isTrue);
expect(File(nested).readAsStringSync(), contains('ReadFile enter'));
});
test('writes one tagged, timestamped line per crumb', () {
final c = IsolateCrumbFile(path(), 'pty.reader');
expect(c.enabled, isTrue);