diff --git a/affordances/officer/core/restarting-your-own-host.md b/affordances/officer/core/restarting-your-own-host.md new file mode 100644 index 0000000..d67114b --- /dev/null +++ b/affordances/officer/core/restarting-your-own-host.md @@ -0,0 +1,67 @@ +--- +name: Restarting your own host +description: Use before restarting, stopping or reloading any PM2 process, and whenever a change you made lives in a sidecar rather than in the main server. Names the one process that kills you, and what to do instead. +version: 1 +--- + +**You are a child of `officer-claude-code`.** Your process tree is: + +``` +zsh ← every Bash command you run +claude --output-format stream-json … +bun run src/servers/sidecar/claude/user-instance.ts ← officer-claude-code, a PM2 process +PM2 God Daemon +``` + +So **`pm2 restart officer-claude-code` kills you, mid-command.** PM2 tree-kills the sidecar, which takes +`claude` and your shell with it. The tool call never returns. What the user sees is the conversation +stopping dead — and what the harness records is an *interrupted* or *rejected* tool call, so the transcript +blames them for something they did not do. That misattribution is the worst part: it sends everyone +looking in the wrong place. + +The same applies to `pm2 stop`, `pm2 delete`, `pm2 reload` and `pm2 restart all` or +`ecosystem.config.cjs`, which include you. + +## What is safe + +**`pm2 restart officer` is safe.** The sidecars are PM2 PEERS of the main server, not its children, so +restarting `officer` costs you a socket reconnect and nothing else. Every other sidecar — +`officer-pty`, `officer-email`, `officer-notify` and the rest — is equally safe for the same reason. + +Only your own host is special. + +## The trap this actually sets + +A change under `src/servers/sidecar/claude/` — the session credential, the manager, the transcript +reader — **does not take effect when you restart `officer`.** It lives in the process you are running +inside. So the honest failure mode is not a crash, it is this: + +> You edit the file, restart `officer`, report the change as live, and it is not. The old code keeps +> running for hours while everything you say about it is wrong. + +That happened on 2026-08-25: a credential scope was widened, `officer` was restarted four times, and the +sidecar carried the previous build all day. The symptom was a legitimate refusal that read as a bug. + +**So check which process owns your change before you claim it is live.** `pm2 jlist` gives each process's +uptime; if the sidecar's start time predates your edit, your edit is not running. + +## What to do instead + +**Ask the user to run it.** One line, and they are already there: + +``` +pm2 restart officer-claude-code +``` + +Say why it is theirs to run rather than yours — that it ends this session — so it does not read as +helplessness. + +If it genuinely must happen without them, detaching it from your process group is the only form that +survives, and **it still ends this conversation** — the restart completes, you do not: + +``` +setsid nohup sh -c 'sleep 2; pm2 restart officer-claude-code' >/dev/null 2>&1 & +``` + +Never do that silently. Tell the user first that the session is about to end, or they will see exactly +what this affordance exists to explain.