todo: backend turn delivery exists — correct three stale entries
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -79,6 +79,36 @@ hold a platform checkout, three run it, and it records how to reach each one.
|
||||
- The updater then does a checkout at that SHA, not a `pull` — same discipline the plugin-pinning
|
||||
item asks for: **verify `rev-parse HEAD` matches, or refuse.**
|
||||
|
||||
## Speaking into a session from the backend
|
||||
|
||||
**Correction, 2026-08-21: the door exists, and three entries in this file said it did not.** The claim
|
||||
that `pushTurn` has exactly one caller (the chat websocket) is **stale**. `api/chat/nudger.ts:102` calls
|
||||
`startClaudeTurn({ ws: null, … })` — a turn started server-side, with no browser attached, into a live
|
||||
session. Whoever is watching the chat sees it arrive the same way they would see a turn typed in another
|
||||
tab. `startNudger()` is wired at `server.tsx:182` and ticks once a minute against a `nudges` table.
|
||||
|
||||
So **both** "missing" pieces are built: a recurring trigger, and a way to put a prompt into a running
|
||||
session. What remains is narrower, and worth doing.
|
||||
|
||||
- [ ] **Generalise it: deliver a turn to a named session, from anywhere in the backend.** Wanted
|
||||
2026-08-21 — "ideal" is the owner's word for it. Today the only server-side caller is the nudger,
|
||||
and delivery is welded to its schedule: a row in `nudges`, one per (user, session), a fixed
|
||||
message, a tick. What the dispatcher, the file watchers and Command HQ all want instead is a plain
|
||||
verb — *here is some text, deliver it to session X* — with the schedule, if any, belonging to the
|
||||
caller.
|
||||
|
||||
Two things already established and worth not re-deriving. The nudger's `checkSafe` holds three
|
||||
refusals — not live, live but generating, another live session in the same directory — and the
|
||||
comments above it carry why each one is there. And "not live" is the case that differs by caller:
|
||||
the nudger refuses (nudging a dead session would CREATE an agent, which is not what nudge means),
|
||||
while a dispatcher handing over five todos does want it created.
|
||||
|
||||
- [ ] **The cost of resuming grows with the transcript.** Raised 2026-08-21 by the owner as a challenge
|
||||
worth taking rather than a limitation to live with. Every resume re-reads the whole conversation as
|
||||
input tokens, so a long-lived commander costs more per note than it did in week one, for identical
|
||||
work. Measurable today rather than theoretical: `command_hq_turns` already records input tokens and
|
||||
USD per turn, so the curve can be plotted before anyone argues about a fix.
|
||||
|
||||
## File watchers
|
||||
|
||||
- [ ] **Watch a directory, and attach actions to what lands in it.** Wanted 2026-08-21. The owner sets a
|
||||
@@ -91,10 +121,10 @@ hold a platform checkout, three run it, and it records how to reach each one.
|
||||
session open and no phone unlocked into the right screen.
|
||||
|
||||
What it needs, in rough order: a watcher registry (path + what to do), a trigger that fires on
|
||||
file arrival rather than on a clock, and a way to hand the file to an agent turn. Note the second
|
||||
and third are the **same two gaps the Nudger item names** — the platform has no periodic/event
|
||||
trigger, and `pushTurn` has one caller, so nothing server-side can speak into a session. Build
|
||||
them once.
|
||||
file arrival rather than on a clock, and a way to hand the file to an agent turn. **The third is
|
||||
no longer missing** — see "Speaking into a session from the backend"; the nudger already starts a
|
||||
server-side turn with no browser attached. What is missing here is arrival-triggered firing, since
|
||||
the existing scheduler is a clock tick.
|
||||
|
||||
Open, not decided: whether the watcher is a plugin or core; whether "action" is a task, a
|
||||
prompt from the prompt library, or a chat message; and how a file is marked consumed so it is not
|
||||
@@ -186,11 +216,11 @@ hold a platform checkout, three run it, and it records how to reach each one.
|
||||
- **Inferred.** Nothing is named, and the dispatcher works it out from the content. This is the
|
||||
one that makes the app worth using: the ideal is that most notes need no prefix at all.
|
||||
|
||||
What this implies, and it is the same missing piece named twice already: **destinations must be
|
||||
addressable and speakable.** "My todo guy" is a name for a standing agent session, so the
|
||||
dispatcher needs a registry of destinations with names a person would actually say, and a door to
|
||||
deliver into a live session — which is the `pushTurn`-has-one-caller gap in the Nudger and File
|
||||
watchers items. Three features now want it; it is the thing to build.
|
||||
What this implies: **destinations must be addressable and speakable.** "My todo guy" is a name for
|
||||
a standing agent session, so the dispatcher needs a registry of destinations with names a person
|
||||
would actually say. Command HQ is already most of that registry — `command_hq_sessions` names
|
||||
commanders and keys them on Claude's own transcript uuid. Delivery into a session exists too; see
|
||||
"Speaking into a session from the backend".
|
||||
|
||||
Fits with the rest rather than duplicating it: the **File watchers** split applies unchanged —
|
||||
a script transcribes on arrival, the dispatcher is the agent stage — and the **iPhone Action
|
||||
@@ -959,13 +989,11 @@ outside the example's new README:
|
||||
and speaks over the chat websocket, exactly as a browser does, so the platform needed no changes.
|
||||
That is the workaround, not the feature.
|
||||
|
||||
**Two things the platform genuinely lacks**, and they are the work:
|
||||
|
||||
1. **A recurring trigger.** The queue has retries and delays but nothing periodic, and
|
||||
`queue/handlers/index.ts` is empty. `officer-notify` is now a natural home for "fire this
|
||||
later" — it already runs as core and already fans out on a schedule-free signal.
|
||||
2. **A way to put a prompt into a live session.** `pushTurn` has exactly ONE caller, the chat
|
||||
websocket handler. Anything server-side that wants to speak to a session has no door.
|
||||
**Both things this said the platform lacked have since been built** (verified 2026-08-21): the
|
||||
recurring trigger is `startNudger()` at `server.tsx:182`, ticking once a minute over a `nudges`
|
||||
table; the door into a session is `startClaudeTurn({ ws: null })` at `nudger.ts:102`. What is left
|
||||
is the UI — a control in the chat composer, beside the background-job button — plus generalising
|
||||
delivery beyond the nudger's own schedule. See "Speaking into a session from the backend".
|
||||
|
||||
Design notes worth keeping:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user