affordance: an agent has its own key for notifying the user

$OFFICER_AGENT_KEY, minted per session and scoped to notify. before this an
agent had no door: the only token in the tree lives in the MCP server's
environment, which its own Bash cannot see — so an agent asked to tell its
owner something either could not, or asked to be handed a personal API key,
which is the owner's full authority pasted into a transcript.

with the distinction that matters most in practice: this is not the
harness's own push tool, which refuses to interrupt a terminal the user is
sitting at. that rule is right for that tool and wrong for this one — a
notification from here exists to reach somebody who is not looking.

and the two judgements the agent has to make itself: send few, because an
interruption for something that worked trains people to stop reading; and
watch what goes in the text, because unlike every other notification in
Officer this one travels through Apple and Google to reach a lock screen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Officer-Session: 656f5c85-e49a-4f1f-b9f3-042a04b4d043
This commit is contained in:
2026-08-25 09:06:05 +00:00
co-authored by Claude Opus 5
parent bbf743b961
commit a9daefa427
@@ -0,0 +1,37 @@
---
name: Notifying the user
description: Use when you want to reach the user on their phone — work finished while they were away, something needs a decision, or you are about to ask them to paste you a credential so you can tell them something.
version: 1
---
**You have a key for this. `$OFFICER_AGENT_KEY`.** It is in your environment, minted for this session, and
it can do exactly one thing: send a notification to the person you are working for. Never ask them to paste
you an API key so you can tell them something — you already have the only kind you should have.
```
curl -X POST "$OFFICER_API_URL/api/notify/_officer/notify" \
-H "Authorization: Bearer $OFFICER_AGENT_KEY" -H "Host: $OFFICER_API_HOST" \
-H "content-type: application/json" \
-d '{"code":"officer/core:message","title":"<a few words>","body":"<one sentence>"}'
```
No `userId` — the key says who you are, and it can only reach that person. `title` and `body` are yours to
write. It arrives on their phone.
**This is not the same channel as your harness's own push tool.** That one refuses to interrupt a terminal
the user is sitting at, which is right for it and wrong for this: a notification from here is for reaching
somebody who is NOT looking, and it goes whether they are at the desk or not.
**So send few, and only what needs them.** A notification is an interruption. Something finished that they
asked for and will see anyway is not worth one; a decision you are blocked on, or a failure they would
otherwise find tomorrow, is. Being told what worked trains somebody to stop reading, and then the one that
mattered arrives in a queue they no longer open.
**What you write goes through Apple and Google to reach a lock screen.** Almost everything else in Officer
travels as a code the device renders itself, so nothing readable leaves the machine. This is the exception,
and the judgement is yours: what you did, a count, a name they chose — fine. The contents of what you were
reading, a filename, a sender, a credential, anything told to you in confidence — never. When in doubt, say
that something happened and let them come and look.
If the key is absent, say so plainly rather than reaching for another way in. It means minting one failed,
which is worth knowing about.