Stop welding "delivered" onto "read"
The inbox projection used to call `markAgentInboxDelivered` after
appending each message to the agent's session shadow. That helper
sets `agent_messages.read_at = now()` for direct messages and
inserts into `agent_message_reads` for channel messages — the SAME
flags `listAgentInboxUnread` and the public `?unreadOnly=true` API
use to define "unread". So the moment we put a message into the
recipient's transcript, the recipient's own API call returned
nothing pending. The IC prompt told the agent to "respond to ALL
unread messages"; the API said zero unread; the agent posted a
status comment instead of replying. Every silent-employee report
traces back here.
Replay safety lives entirely on `agent_message_projections`
(installed in v46) — that ledger is keyed by `(message_id,
session_id)` and `claimProjection` already short-circuits a re-run
without touching `read_at` at all. The two concepts are now
properly separated:
- "delivered" (we put it in front of the agent) — tracked by
the projection ledger, owned by the runtime bridge;
- "read" (the agent acknowledged it) — tracked by `read_at` and
`agent_message_reads`, only flipped by the explicit POST
/messages/{id}/read endpoint the agent calls itself.
`markAgentInboxDelivered` is removed because there is no remaining
caller and its semantics were the bug — keeping it around would
just invite the same mistake again.
This commit is contained in:
1 parent
3a72c8aa39
commit
f30ec740d8
4 files changed
+22
-53
No files matched your search
@@ -20,7 +20,6 @@ export class AppDatabase extends AppDatabaseBase {
|
||||
searchMessages(companyId: string, query: string, opts?: { channel?: string; channelTargetId?: string | null; limit?: number }) { return this.messages.searchMessages(companyId, query, opts); }
|
||||
markMessageReadForReader(messageId: string, companyId: string, readerAgentId?: string | null) { return this.messages.markMessageReadForReader(messageId, companyId, readerAgentId); }
|
||||
listAgentInboxUnread(companyId: string, agentId: string) { return this.messages.listAgentInboxUnread(companyId, agentId); }
|
||||
markAgentInboxDelivered(agentId: string, messageIds: string[]) { return this.messages.markAgentInboxDelivered(agentId, messageIds); }
|
||||
|
||||
// ─── Social & Browser Actions ──────────────────────────────────────────────
|
||||
|
||||
|
||||
Reference in new issue
Block a user