Files
platform/COMMS
pastilhasandClaude Opus 5 7ad64445ee command hq: POST /commanders/new, for a client that cannot open the websocket
mobile's need, decided with the owner in COMMS/command-hq/mobile.md, now
built: { prompt (required), categoryId? } -> { sessionId, cwd }, sessionId
being claude's REAL transcript id, not a placeholder.

the owner confirmed prompt is required and described why: a commander
usually starts as an ordinary back-and-forth before a background job is ever
armed via the existing dialog, sometimes it's just "you know what to do" —
either way there's always a real first message, same as any conversation.
no empty-commander case to design around.

getting a real transcript id costs actually starting the turn, since claude
assigns one only once system.init has been reported. extracted the
turn-starting half of handleClaudeCodeChat into startClaudeTurn(ws: ... |
null, ..., onOutcome?) so both the websocket path and this endpoint drive
one spawn function instead of two that drift — handleClaudeCodeChat is now
a thin wrapper with an unchanged signature. onOutcome mirrors every
sendToClient(ws, {type:'error',...}) refusal point (member not signed in,
claude not installed, spawn failure) plus the session:claude success case,
so an http caller gets the real reason instead of a generic 30s timeout.

the category-write race: fileAsCommander (same hook the web path uses,
since context: 'command-hq' is set either way) always files with no
category. the endpoint's own createCommandHqSession is upsert-safe
regardless of which insert wins, and an unconditional setCommandHqSessionCategory
UPDATE runs after — always last, always wins, so the requested category is
what's left standing no matter the race.

said plainly in COMMS/command-hq/platform.md: this refactor of live spawn
machinery did not get the second-pair-of-eyes review i said i wanted before
touching it. bunx tsgo clean, suite at the same 7 pre-existing baseline
failures. not exercised against a running server on either side yet.

docs/command-hq.md updated throughout — API table, "how a commander is
created", "still open" now empty of blockers.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-18 07:29:57 +00:00
..

COMMS

Notes between the people and agents working on Officer, kept in the repository rather than in a directory on one machine.

Why here: a note on a server is invisible to whoever picks the work up next, has no history, and cannot be reviewed alongside the change it argues about. In git it is diffable, it arrives with git pull, and the commit that answers a note sits next to the note.

One directory per subject — command-hq/ — and one file per side of the conversation, so a reply is a new file or an edit with a visible diff, never an overwrite that loses what was asked.

Write plainly. These are read by someone who was not in the conversation that produced them.