diff --git a/skills/commander/SKILL.md b/skills/commander/SKILL.md index d4e5c88..98dd0f2 100644 --- a/skills/commander/SKILL.md +++ b/skills/commander/SKILL.md @@ -209,6 +209,50 @@ Four details the mechanics do not carry, each of which was learned by getting it - **The claim goes before the spawn, not inside the action.** If the action claims its own work, an action that dies before claiming has claimed nothing and will run again. +# Telling the owner, without a second channel + +A loop writes to its job panel, and nobody reads a job panel. So a watcher that fires while the owner is +asleep has done its work and told no one, which from their side is indistinguishable from not firing. + +Say two things in the CONVERSATION, and only two: + +- **When it fires.** One line: what appeared, and that you are handling it. Nothing else — the detail is + in the job panel by definition, and repeating it in chat means both places are half-read. +- **When the work ends.** A short report: what was done, what was skipped, what went wrong and what the + owner has to do about it. "Five servers, nothing to report" is a complete message. So is "four went, + one needs a console and here is why". + +Nothing in between. A progress commentary in chat is a notification per step, which is how somebody turns +notifications off. + +## How, with nothing new + +You cannot post into your own conversation from a shell loop — you only speak when a turn runs. But you can +cause a turn, and both halves of that already exist: + +1. **The child writes its report to a file**, named for its own session id, somewhere under your state + directory. Same machine, same user, no authentication to arrange. +2. **The loop inserts a row into `nudges`** for your own transcript id, over the local Postgres socket, with + a message telling you what happened and where the file is. The nudger ticks every 60 seconds, wakes this + conversation, and you read the file and write the report yourself. + +So the shape is: the loop knows the FACTS and puts them in a file; you provide the JUDGEMENT and put it in +the chat. It costs one turn per event, which is exactly what buys a summary rather than a pasted log tail. + +Three things about that mechanism, each of which will bite otherwise: + +- **`nudges` holds one row per (user, session), deliberately.** A second schedule for the same conversation + produces doubled prompts, so overwrite your pending nudge rather than queueing behind it. Two events in + the same minute become one turn covering both, which is the better message anyway. +- **The nudge message is a PROMPT you will be handed**, not a notification the owner sees. Write it to + yourself: what fired, where the file is, and that you are to report briefly. What the owner reads is + whatever you say on that turn. +- **Up to 60 seconds late**, because the nudger polls on a minute. Fine for anything a watcher does; if + something genuinely needs to be instant, it is not a watcher. + +Once you have spoken, the ordinary chat notification path takes it to the owner's devices — so the phone +tap lands in this conversation, with the job panel one step away. Nothing to build for that either. + # Things that are true and surprising - **Its cost line understates.** The recorded cost counts the commander's OWN turns — one row per `result`