dispatch is anything that leaves, and the deeplink now goes somewhere
the definition was "doing something with a result beyond keeping it",
which does not obviously cover a notification ABOUT classification failing.
it should: classification decided where the item goes and it went to
unclassified/. telling somebody is a different step, and its rule belongs
in DISPATCHING.md. the test is never what the message is about — it is
whether anything left.
and the commander notification pointed at officer://command-hq/{id} where
{id} is the DIRECTORY name, while /command-hq/:sessionId addresses a
commander by its transcript id. so the tap landed nowhere.
the two want different ids and cannot be reconciled today: threading wants
the directory name, stable from creation; the route wants the transcript
id, which does not exist when the commander is created. rather than make a
commander fetch its own transcript id before it can speak — an errand it
would rightly skip, as the language rule already proved — the tap opens
Command HQ and the owner picks. one tap worse, and correct.
the honest fix is a route that accepts a directory name. noted where
whoever does the mobile deep-link work will find it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043
This commit is contained in:
@@ -228,9 +228,14 @@ export function commanderClaudeMd(params: CommanderClaudeMdParams): string {
|
|||||||
' subdirectory of `data/` named for that category. It changes where the item IS, never what it is.',
|
' subdirectory of `data/` named for that category. It changes where the item IS, never what it is.',
|
||||||
' Optional, and most commanders do not need it: it earns its place only when there are enough items',
|
' Optional, and most commanders do not need it: it earns its place only when there are enough items',
|
||||||
' that finding one matters. It is a STEP, not a place — the place is always `data/`.',
|
' that finding one matters. It is a STEP, not a place — the place is always `data/`.',
|
||||||
'- **Dispatch** — doing something with a result beyond keeping it. Telling the owner, handing it to',
|
'- **Dispatch** — anything that LEAVES this commander. Telling the owner, waking another conversation,',
|
||||||
' another agent, sending it somewhere. Optional, off until the owner arms it, and the only one of the',
|
' handing work to an agent, sending something somewhere. Optional, off until the owner arms it, and the',
|
||||||
' four that acts outside this directory.',
|
' only one of the four that acts outside this directory.',
|
||||||
|
'',
|
||||||
|
' Note what that includes: a notification saying classification could not place an item is DISPATCH,',
|
||||||
|
' not classification. Classification decided where the item goes and it went to `unclassified/`.',
|
||||||
|
' Telling somebody about it is a different step and its rule lives in `DISPATCHING.md`. The test is',
|
||||||
|
' never what the message is about — it is whether anything left.',
|
||||||
'',
|
'',
|
||||||
'Storing the result is NOT dispatch. Every action keeps what it produced, here, by default — that is',
|
'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.',
|
'the action finishing, not a decision anyone has to make.',
|
||||||
|
|||||||
@@ -127,8 +127,18 @@ const CORE_ENTRIES: Record<string, NotificationEntry> = {
|
|||||||
A commander with something to say.
|
A commander with something to say.
|
||||||
|
|
||||||
ONE entry rather than one per commander, and the commander travels as `{id}` — so arming a new
|
ONE entry rather than one per commander, and the commander travels as `{id}` — so arming a new
|
||||||
commander needs no catalogue change and no app resync. `{id}` is the commander's row id, which is what
|
commander needs no catalogue change and no app resync. `{id}` is the commander's DIRECTORY name, which
|
||||||
`officer://command-hq/{id}` opens.
|
is what threads its notifications together.
|
||||||
|
|
||||||
|
The route is the LIST, deliberately, and not `officer://command-hq/{id}`. That is what it was, and it
|
||||||
|
was wrong: `/command-hq/:sessionId` addresses a commander by its TRANSCRIPT id, so a deeplink built
|
||||||
|
from the directory name lands nowhere. Threading wants the directory name (stable from creation, before
|
||||||
|
any transcript exists); the route wants the transcript id (which does not exist yet when the commander
|
||||||
|
is created). Rather than make a commander fetch its own transcript id to send a notification, the tap
|
||||||
|
opens Command HQ and the owner picks — one tap worse, and correct.
|
||||||
|
|
||||||
|
Worth revisiting when the app handles deep links properly: the honest fix is a route that accepts a
|
||||||
|
directory name, not a commander doing a lookup before it can speak.
|
||||||
|
|
||||||
This entry is what a commander sees when it sends nothing but a code and an id: "Voice Memos" would be
|
This entry is what a commander sees when it sends nothing but a code and an id: "Voice Memos" would be
|
||||||
a lie without knowing which one, so the generic is honest and the deeplink does the rest. In practice a
|
a lie without knowing which one, so the generic is honest and the deeplink does the rest. In practice a
|
||||||
@@ -163,7 +173,7 @@ const CORE_ENTRIES: Record<string, NotificationEntry> = {
|
|||||||
title: 'Commander: {title}',
|
title: 'Commander: {title}',
|
||||||
body: '{body}',
|
body: '{body}',
|
||||||
target: 'mobile',
|
target: 'mobile',
|
||||||
route: 'officer://command-hq/{id}',
|
route: 'officer://command-hq',
|
||||||
thread: 'commander:{id}',
|
thread: 'commander:{id}',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user