Files
stack/agents/darkwing/work/cohort-k1/trace.patch
T
jason.woltjeandClaude Opus 5.5 7478ee2c02 docs(conversation): row 46 cohort K1/K3/K10 diagnosis, receipts and candidate packet (darkwing)
The ignoreTerm tool child was TERMed before Node installed its handler
when the claim store sits on a fast disk. Candidate fixes the fixture;
the patch itself is not committed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-09 08:11:48 -05:00

44 lines
2.9 KiB
Diff

diff --git a/packages/conversation/src/shim.mjs b/packages/conversation/src/shim.mjs
index 2adbe48b..d51c4a1f 100644
--- a/packages/conversation/src/shim.mjs
+++ b/packages/conversation/src/shim.mjs
@@ -22,7 +22,7 @@
// `populated 0`. A missing or unreadable file is unavailable, never empty.
import { spawn } from "node:child_process";
-import { closeSync, mkdirSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
+import { appendFileSync, closeSync, mkdirSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
import { createServer } from "node:net";
import { join } from "node:path";
import { LineSplitter, encodeLine, parseLine } from "./framing.mjs";
@@ -136,6 +136,7 @@ async function handle(req) {
if (startOf(pid) !== startTicks) continue;
try {
process.kill(pid, "SIGTERM");
+ if (process.env.DW_TRACE) appendFileSync(process.env.DW_TRACE, JSON.stringify({ t: Date.now(), ev: 'term', pid }) + '\n');
signalled.push(pid);
} catch {
// gone already
diff --git a/packages/conversation/tests/fake-pi.mjs b/packages/conversation/tests/fake-pi.mjs
index b3014f86..f30f5a4c 100644
--- a/packages/conversation/tests/fake-pi.mjs
+++ b/packages/conversation/tests/fake-pi.mjs
@@ -615,13 +615,16 @@ const children = [];
// K2); `forkLoop` forks every 5 ms (K12); `ignoreTerm` survives SIGTERM, so
// only the kill phase ends it (K3, K10, K11). With `pidLog`, the fork loop
// appends each child's pid and a `term` line when it gets SIGTERM (K12).
+import * as __fs from 'node:fs';
+const require0 = () => __fs;
function spawnChild({ setsid = false, forkLoop = false, ignoreTerm = false, pidLog = null } = {}) {
const note = pidLog ? `const note=(s)=>require('node:fs').appendFileSync(${JSON.stringify(pidLog)},s+'\\n');` : "const note=()=>{};";
- const code = note + (ignoreTerm ? "process.on('SIGTERM',()=>note('term'));" : "") + (forkLoop
+ const code = note + (ignoreTerm ? "process.on('SIGTERM',()=>note('term'));" + (process.env.DW_TRACE ? `require('node:fs').appendFileSync(${JSON.stringify(process.env.DW_TRACE)},JSON.stringify({t:Date.now(),ev:'ready',pid:process.pid})+'\\n');` : "") : "") + (forkLoop
? "const {spawn}=require('node:child_process');setInterval(()=>{try{const c=spawn('sleep',['1000'],{stdio:'ignore'});if(c.pid)note(String(c.pid))}catch{}},5);setInterval(()=>{},1e9)"
: "setInterval(()=>{},1e9)");
const child = spawn(process.execPath, ["-e", code], { stdio: "ignore", detached: setsid });
children.push(child.pid);
+ if (process.env.DW_TRACE) { require0().appendFileSync(process.env.DW_TRACE, JSON.stringify({ t: Date.now(), ev: 'spawn', pid: child.pid, ignoreTerm, setsid }) + '\n'); child.on('exit', (code, sig) => require0().appendFileSync(process.env.DW_TRACE, JSON.stringify({ t: Date.now(), ev: 'child-exit', pid: child.pid, code, sig }) + '\n')); }
return child.pid;
}