@agfpd/iapeer 0.2.53 → 0.2.54
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/launch/canary.test.ts +16 -0
- package/src/launch/canary.ts +19 -0
package/package.json
CHANGED
|
@@ -79,6 +79,22 @@ describe('canary script (pure)', () => {
|
|
|
79
79
|
expect(s).toContain('/r/logs/iapeer/server-deaths/claude-bob') // forensics file
|
|
80
80
|
expect(s).toContain('vm_stat') // memory evidence (OOM hypothesis)
|
|
81
81
|
expect(s).toContain(`'/opt/homebrew/bin/tmux' -S '/tmp/x.sock'`) // abs tmux, quoted
|
|
82
|
+
expect(s).not.toContain('cmdlog-tail') // no cmdLogDir → no cmdlog capture line
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
test('with cmdLogDir → forensics tail the dead server cmdlog (client-COMMAND kill attribution)', () => {
|
|
86
|
+
const s = canaryScript({
|
|
87
|
+
identity: 'claude-bob',
|
|
88
|
+
sock: '/tmp/x.sock',
|
|
89
|
+
tmuxBin: '/opt/homebrew/bin/tmux',
|
|
90
|
+
exitLogFile: '/r/logs/iapeer/exits.log',
|
|
91
|
+
forensicsDir: '/r/logs/iapeer/server-deaths',
|
|
92
|
+
cmdLogDir: '/r/logs/iapeer/tmux-cmdlog/claude-bob',
|
|
93
|
+
})
|
|
94
|
+
expect(s).toContain('cmdlog-tail') // the kill-server/kill-session witness
|
|
95
|
+
// tails the dead server's own -v log by its captured pid, greps the command lines
|
|
96
|
+
expect(s).toContain(`'/r/logs/iapeer/tmux-cmdlog/claude-bob/tmux-server-'"$SPID"'.log'`)
|
|
97
|
+
expect(s).toContain(`grep -aE 'command:'`)
|
|
82
98
|
})
|
|
83
99
|
|
|
84
100
|
test('ensureServerCanary without exitLogDir → skipped (observability off)', () => {
|
package/src/launch/canary.ts
CHANGED
|
@@ -49,6 +49,7 @@ import { spawn, spawnSync } from 'child_process'
|
|
|
49
49
|
import { mkdirSync } from 'fs'
|
|
50
50
|
import { join } from 'path'
|
|
51
51
|
import { resolveExecutable } from './launchd.ts'
|
|
52
|
+
import { cmdLogDirFor } from './cmdlog.ts'
|
|
52
53
|
|
|
53
54
|
/** The exit-cause log file inside `exitLogDir` (sibling to lifecycle.log).
|
|
54
55
|
* Lives here (not index.ts) so canary ⇆ launch never import-cycle; index.ts
|
|
@@ -74,6 +75,12 @@ export interface CanaryScriptOptions {
|
|
|
74
75
|
tmuxBin: string
|
|
75
76
|
exitLogFile: string
|
|
76
77
|
forensicsDir: string
|
|
78
|
+
/** The identity's tmux-cmdlog dir (<exitLogDir>/tmux-cmdlog/<identity>). When set,
|
|
79
|
+
* the death forensics tail the dead server's `tmux-server-<SPID>.log` — the ONLY
|
|
80
|
+
* witness of a client-COMMAND kill (`kill-server`/`kill-session`), which leaves zero
|
|
81
|
+
* signals (so signal forensics see nothing) and is otherwise wiped by the respawn's
|
|
82
|
+
* prepareCmdLogDir before anyone reads it. Best-effort: absent log → grep no-ops. */
|
|
83
|
+
cmdLogDir?: string
|
|
77
84
|
}
|
|
78
85
|
|
|
79
86
|
/**
|
|
@@ -129,6 +136,17 @@ export function canaryScript(o: CanaryScriptOptions): string {
|
|
|
129
136
|
` echo '--- ps-top-rss'; ps axo pid,ppid,rss,etime,command | sort -rn -k3 | head -25`,
|
|
130
137
|
` echo '--- diagnosticreports-user'; ls -t "$HOME/Library/Logs/DiagnosticReports" 2>/dev/null | head`,
|
|
131
138
|
` echo '--- diagnosticreports-system'; ls -t /Library/Logs/DiagnosticReports 2>/dev/null | head`,
|
|
139
|
+
// The death-class discriminator signal-forensics structurally cannot see: a tmux
|
|
140
|
+
// server killed by a CLIENT COMMAND (`kill-server`/`kill-session`) leaves zero
|
|
141
|
+
// signals. Its only witness is the dead server's own -v cmdlog, which the respawn
|
|
142
|
+
// wipes seconds later — captured HERE (canary fires ~+2 s, respawn ~+7 s) so the
|
|
143
|
+
// killer's `client-<pid> command: …` survives into the forensics.
|
|
144
|
+
...(o.cmdLogDir
|
|
145
|
+
? [
|
|
146
|
+
` echo '--- cmdlog-tail (last client commands; a kill-server/kill-session here IS the killer)'`,
|
|
147
|
+
` tail -c 131072 '${o.cmdLogDir}/tmux-server-'"$SPID"'.log' 2>/dev/null | grep -aE 'command:' | tail -30`,
|
|
148
|
+
]
|
|
149
|
+
: []),
|
|
132
150
|
`} > "$f" 2>&1`,
|
|
133
151
|
`printf 'ts=%s ev=server-exit identity=${o.identity} server_pid=%s wait_rc=%s cause=%s forensics=%s\\n' "$ts" "$SPID" "$rc" "$cause" "$f" >> '${o.exitLogFile}'`,
|
|
134
152
|
].join('\n')
|
|
@@ -172,6 +190,7 @@ export function ensureServerCanary(o: EnsureCanaryOptions): CanaryEnsureState {
|
|
|
172
190
|
tmuxBin,
|
|
173
191
|
exitLogFile: exitLogPath(o.exitLogDir),
|
|
174
192
|
forensicsDir,
|
|
193
|
+
cmdLogDir: cmdLogDirFor(o.exitLogDir, o.identity),
|
|
175
194
|
})
|
|
176
195
|
const child = spawn('/bin/sh', ['-c', script], { detached: true, stdio: 'ignore', env })
|
|
177
196
|
child.unref()
|