mirror of
https://github.com/garrytan/gstack.git
synced 2026-06-29 21:15:37 +02:00
fix(browse): identity-based terminal-agent kill replaces pkill regex
Commit 0 of the v1.44 long-lived-sidebar PR — foundation for the watchdog
and removes a latent cross-session footgun.
`pkill -f terminal-agent\.ts` (cli.ts spawn site + server.ts shutdown) matched
by argv regex and would kill ANY process whose argv contained the string —
sibling gstack sessions on the same host, an editor with the file open, a
second `$B connect` run. Identity-based PID kill via a new helper module
removes that whole class of bug.
* New `browse/src/terminal-agent-control.ts`: `readAgentRecord`,
`writeAgentRecord`, `clearAgentRecord`, `killAgentByRecord`. Validates
PID liveness via `isProcessAlive` before signaling (PID-reuse defense).
* `terminal-agent.ts` writes `<stateDir>/terminal-agent-pid` (JSON
`{pid, gen, startedAt}`) at boot; clears on SIGTERM/SIGINT.
* New per-boot `CURRENT_GEN` (16-byte random); `/internal/*` callers can
include `X-Browse-Gen` to defend against split-brain in the upcoming
watchdog. Absent header is accepted (backward compat); mismatch returns
409. New `checkInternalAuth` helper centralizes bearer + gen checks.
* New `/internal/healthz` route — agent liveness probe used by the
upcoming watchdog (returns pid/gen/sessions, no claude-binary lookup).
* `cli.ts` and `server.ts` both call `killAgentByRecord` instead of pkill.
* `ServerConfig.ownsTerminalAgent` JSDoc updated; the gated teardown now
runs 4 side effects (was 3) — adds the new agent-record unlink.
Test changes:
* New `browse/test/terminal-agent-pid-identity.test.ts` — static-grep
tripwire that fails CI if any source file re-introduces `pkill ...
terminal-agent` or `spawnSync('pkill', ...)`; round-trips
write/read/clear; verifies killAgentByRecord no-ops on dead PIDs.
* `browse/test/server-embedder-terminal-port.test.ts` rewritten to
intercept `process.kill` (not `child_process.spawnSync`); writes a
sentinel agent-record with a guaranteed-dead PID; asserts probe-only
(signal 0) calls, no termination signals; verifies all 3 discovery
files including the new terminal-agent-pid.
Closes TODOS.md P3 ("Identity-based terminal-agent kill").
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -2,34 +2,17 @@
|
||||
|
||||
## browse server: terminal-agent teardown follow-ups (filed v1.41 via /plan-eng-review)
|
||||
|
||||
### P3: Identity-based terminal-agent kill (replace pkill regex with PID)
|
||||
### ✅ DONE (v1.44.0.0): Identity-based terminal-agent kill (replace pkill regex with PID)
|
||||
|
||||
**What:** Record the spawned terminal-agent PID at `browse/src/cli.ts:1057` and
|
||||
replace `pkill -f terminal-agent\.ts` at both `cli.ts:1047` and
|
||||
`server.ts:1281` (now inside the `if (ownsTerminalAgent)` gate) with
|
||||
`process.kill(pid, signal)` against the recorded PID.
|
||||
|
||||
**Why:** `pkill -f terminal-agent\.ts` matches by command-line regex, so today
|
||||
it can kill ANY process whose argv contains `terminal-agent.ts` — sibling
|
||||
gstack sessions, editor processes that have the file open, a second gstack
|
||||
run on the same host. Latent footgun for the CLI path, not just embedders.
|
||||
|
||||
**Pros:** Removes a real cross-session foot-cannon. PID-based kill is the
|
||||
correct identity primitive. Lets us tighten `pkill -f`'s broad-match warning
|
||||
in the new `ownsTerminalAgent` JSDoc to "historical" rather than "current".
|
||||
|
||||
**Cons:** Requires threading the PID through the CLI-to-server state path
|
||||
(currently the parent server reads `terminal-port` to discover the agent; it
|
||||
would also need `terminal-agent-pid`). Touches `cli.ts`, `server.ts`, and
|
||||
`terminal-agent.ts` together — bigger surface than the v1.41 fix.
|
||||
|
||||
**Context:** Surfaced by both Codex and Claude subagent during /autoplan
|
||||
review of the `ownsTerminalAgent` gate. Currently documented as out-of-scope
|
||||
in `browse/src/server.ts` JSDoc for `ServerConfig.ownsTerminalAgent`. The
|
||||
embedder fix (ownsTerminalAgent: false) means embedders don't hit this; CLI
|
||||
users still do.
|
||||
|
||||
**Depends on:** None.
|
||||
**Resolved:** Bundled into the v1.44.0.0 long-lived-sidebar PR as Commit 0.
|
||||
`browse/src/terminal-agent-control.ts` is the new home for `readAgentRecord`,
|
||||
`writeAgentRecord`, `clearAgentRecord`, and `killAgentByRecord`. The agent
|
||||
writes `<stateDir>/terminal-agent-pid` (JSON `{pid, gen, startedAt}`) at boot
|
||||
and clears it on SIGTERM/SIGINT. `cli.ts` and `server.ts` both route through
|
||||
`killAgentByRecord` instead of `pkill -f terminal-agent\.ts`. The new
|
||||
`browse/test/terminal-agent-pid-identity.test.ts` is the static-grep tripwire
|
||||
that fails CI if `pkill ... terminal-agent` or `spawnSync('pkill', ...)`
|
||||
reappears in any source file.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user