the catalogue shapes a commander's words, not the commander

"it should always say Commander: <name>" was left to whether the commander
remembered to write it. that is not a structure, it is a hope — and the
producer's title reached the lock screen untouched, because both transports
built the alert from n.title rather than from the renderer.

so the code owns the shape and the producer only supplies values.
officer/core:commander is `Commander: {title}` / `{body}`; the commander
sends "Voice Memos", never the prefix. interpolation gains {title} and
{body} alongside {n} and {id}, for the same reason the others exist.

apns-payload and fcm now send the RENDERED text. that was the actual
delivery bug: the catalogue could say whatever it liked and neither
transport read it.

a placeholder that resolves to nothing takes its punctuation with it, or
`Commander: {title}` with no title ships `Commander: ` and every template
has to assume its values are always present.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043
This commit is contained in:
2026-08-24 15:24:17 +00:00
co-authored by Claude Opus 5
parent 478ddb13e9
commit 2d5e9835f5
7 changed files with 91 additions and 21 deletions
+6 -1
View File
@@ -138,7 +138,12 @@ const CORE_ENTRIES: Record<string, NotificationEntry> = {
than piling every commander into one stack.
*/
'officer/core:commander': {
title: 'Commander',
// `{title}` is the commander's NAME and `{body}` its sentence — the commander supplies both and this
// decides what they look like. It sends "Voice Memos", never "Commander: Voice Memos": the prefix is
// the platform's to add, so every commander reads the same on the lock screen whether or not it
// remembered to. A commander that sends no title of its own falls through to the bare word.
title: 'Commander: {title}',
body: '{body}',
target: 'mobile',
route: 'officer://command-hq/{id}',
thread: 'commander:{id}',