diff --git a/src/servers/api/command-hq/directory.ts b/src/servers/api/command-hq/directory.ts index e88bccfa..95208196 100644 --- a/src/servers/api/command-hq/directory.ts +++ b/src/servers/api/command-hq/directory.ts @@ -185,9 +185,9 @@ export function commanderClaudeMd(params: CommanderClaudeMdParams): string { '', 'The four words have exact meanings here. Use them as defined, with the owner and with yourself:', '', - '- **Trigger** — the condition that says something has happened, evaluated on a schedule. It answers', - ' one question, always the same one: what has appeared that I have not handled? It decides nothing', - ' else and it never needs judgement.', + '- **Trigger** — the condition that says something has happened. It answers one question, always the', + ' same one: what has appeared that I have not handled? It decides nothing else and it never needs', + ' judgement. It can run on a schedule or fire the moment something lands — see below.', '- **Action** — the work done to ONE item because the trigger fired. It produces something. It is', ' usually a task the platform already has; sometimes a script you write. A commander may have exactly', ' one, and it may have none, in which case the trigger is the whole job.', @@ -201,7 +201,20 @@ export function commanderClaudeMd(params: CommanderClaudeMdParams): string { 'Storing the result is NOT dispatch. Every action keeps what it produced, here, by default — that is', 'the action finishing, not a decision anyone has to make.', '', - '**One trigger.** A schedule that asks a single question: what has appeared that I have not handled?', + '**Watching the filesystem beats polling, and it is safe here.** A trigger does not have to be a timer.', + '`inotifywait` on the reference path fires the moment a file appears, which is the answer whenever the', + 'owner wants it handled straight away rather than within some interval.', + '', + 'It is safe because of how files arrive: everything Officer writes into a folder is written as', + '`.part` and RENAMED into place, and a rename is atomic. So a file appearing under its real name', + 'is a file that is complete — a watcher never sees a half-written one. Ignore `.part` and act on the', + 'rename.', + '', + "That guarantee is Officer's, not the filesystem's. Something writing into that folder by another", + 'route — scp, a sync client, a script — makes no such promise, and there a poll that waits for the size', + 'to stop changing is the safer trigger. Ask which it is if you cannot tell.', + '', + '**One trigger.** Whichever kind, it asks a single question: what has appeared that I have not handled?', 'The trigger runs constantly, so it must never need judgement. If deciding whether something happened', 'takes thought, the condition is too vague — it will either never fire or fire constantly, and you will', 'find out days later.', @@ -303,8 +316,9 @@ export function commanderClaudeMd(params: CommanderClaudeMdParams): string { 'quietly does all of them is an expensive surprise, and one that skips them is a commander that looks', 'broken on its first day.', '', - 'Categories, dispatching and how often to look come later still, one at a time, and most commanders', - 'never need the first two.', + 'Then how often to look — and offer **as soon as it lands** alongside the intervals, because that is a', + 'real option here rather than a wish. Categories and dispatching come later still, one at a time, and', + 'most commanders never need either.', '', '**Never arm a watcher before the owner has agreed what it does.** Arming ahead of that is arming a', 'guess, and a wrong condition either never fires or fires constantly — either way it is found out days',