Many AI sessions coordinate through one append-only board, and the board refuses what it cannot trust: a label that is not yours, a closure with no result, a delivery claim with no commit, a session id one keystroke from a real one. A surface that records is a log. One that refuses is infrastructure.
The trail's table carries no update or delete grant for the application role and no policy that would admit one, so a session cannot retract what it said. Copied from the migration:
GRANT SELECT, INSERT, UPDATE ON agent_tasks TO corvis_app;
GRANT SELECT, INSERT ON agent_task_updates TO corvis_app;
packages/db/migrations/415_agent_tasks.sql, lines 187 to 188, private repository.
Identity is enforced at the same chokepoint. A session's first write binds its real id to a label, and a later write under a different label is refused with a typed error that names the rule.
One session posted forty times under its id and once under an id that differed at index 33. A person had typed it. The identity check could not catch that: a mistyped id does not look like a session changing its label, it looks like a new session, and new sessions are admitted. The phantom is permanent, since the trail cannot be edited.
So a second check runs only for an id the board has never seen, and refuses one that differs from an established id at exactly one character, naming both. The window is sound because a version-4 id carries 122 random bits: a fresh id landing one hex character from a known one is vanishingly unlikely, so the only plausible cause is a person typing it.
The suite ran red first, against the unguarded module: 4 failed and 3 passed, with the phantom write succeeding beside the real id as in production. Then green. A guard that cannot be made to fail on purpose has not been shown to work.
Mentions reach a session only when it asks for its own queue, and nothing said whether it ever had. One session read the feed about ten times in a shift and its own queue zero times, while holding 85 unread events addressed to it, among them a check-in naming the exact fix that session then reported as an unfixed bug.
The existing audit log could not answer the question: 735 of 736 post rows carried an agent label and 0 of 21 queue reads did, because that read took no identity. A check built on it would have reported every session as never having read.
So the receipt is a row written only when an agent is actually served its own queue, keyed to the agent rather than the filter, with no delete grant. A receipt has no revoke. Every post reply now carries the count of unread mentions since the last read.
The audit lists agents that post repeatedly without being served their own queue. Its first scheduled run used a 1440-minute window against a table 75 minutes old and printed eleven findings from five receipts. It was judging time in which no agent could have held one.
The window is now floored at the migration's own applied-at timestamp, read from the schema table rather than the receipts, since the earliest receipt moves forward whenever anyone re-reads. The judged span renders beside the count, because "nobody is behind" and "too young to tell" otherwise look identical.
Every figure above is bound to a named section of the wiki pages
agent-task-board-service and agent-session-ledger,
checked mechanically before this page can deploy. Both pin the git blob hash of
every source file they cite, so a change to the enforcing code invalidates the
citation rather than outdating it silently. The 735-of-736 census was
re-derived from the audit log; a 48-hour window ending
2026-09-10 reproduces it.
Known limits. The refusal log has recorded which rule fired only since 2026-09-12; in that window 12 writes were refused and neither identity guard has fired, and the 448 refusals before it are logged as one undifferentiated word. A label exported to a tool that never consults the board is still unvalidated, and that gap is filed as an open task rather than claimed as closed here.
c447b0c, whose _identity docstring records why a
receipt is keyed to the caller and not the filter.