chore(plan): T-9 — the mailbox answers by message number

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-19 19:08:02 +02:00
co-authored by Claude Opus 5.5
parent 87481a016a
commit 1c4cfc4f1b
2 changed files with 6 additions and 0 deletions
+1
View File
@@ -6,3 +6,4 @@ INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06GN8NBWVQ53ZX7WMZNE5GJJP4', 'T-6', '2026-10-19 13:24:11.102', '2026-10-19 13:24:11.102', NULL, 'f6351f2d6190ae5fbd9e55e6eadc04e5', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06GN8Z1FF1QDGR4QE4405AP8GC', 'T-7', '2026-10-19 14:06:27.193', '2026-10-19 14:06:27.193', NULL, '09267e8234ec21c6d75767d7cd21bb51', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06GN99CB552PSF82EE2P8PJZP0', 'T-8', '2026-10-19 14:51:37.641', '2026-10-19 14:51:37.641', NULL, 'd8c7f6122652cb1c3e448f1adedd54ab', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06GNA8JCWVP31DKSE7F4EMF6G4', 'T-9', '2026-10-19 17:07:53.702', '2026-10-19 17:07:53.702', NULL, 'f7caf295773331bd290e8f9fd196ce6d', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= ticket_idmap.updated_at;
+5
View File
@@ -114,3 +114,8 @@ Today a tenant is an unchecked string: the Office header or a JWT''s `tatlock_us
**Read API, for other services to conform to:** `GET /tenants/me` (the caller''s own tenant and its consumer''s grant); `GET /tenants` (service callers without a tenant see all; a tenant-bearing caller sees only its own — the hard boundary).
**Not in v1:** write routes for provisioning (T-195 on the workspace board adds them, or an operator verb); per-consumer verb classes (workspace T-184 — a column on `tenant_consumers` when it lands).', 'done', 'high', NULL, NULL, NULL, '2026-10-19 14:51:37.641', '2026-10-19 15:48:04.079', NULL, '4adf867d5e7e4424e6a2e97b53f958d1', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06GNA8JCWVP31DKSE7F4EMF6G4', 'task', NULL, 'The mailbox answers by message number, so no client pages to find an entry', '`GET /scribe/mailbox` sorts unread first, then by id descending, behind one `before_id` cursor — two sort keys, one cursor. No cursor choice is safe in every case: paging below the last row is correct whenever a page holds a read entry, but a page of only unread entries (more than 200 unread) skips read entries with higher ids. Both clients that turn a message number into a mailbox entry — the Office (`src/systems/scribe.py` `_resolve_entry_id`) and `toj scribe mark` — page the mailbox to do it.
**Fix:** a `message_id` query parameter on `GET /scribe/mailbox` that answers the caller''s own entry for that message (zero or one), so neither client pages. Optionally, a cursor that matches the sort (`before` over `(read, id)`) for the listing itself.
Done when: both clients drop their paging for a single call, and a test seeds an old unread entry ahead of more than a page of read ones and finds a read entry beyond the first page.', 'backlog', 'medium', NULL, NULL, NULL, '2026-10-19 17:07:53.702', '2026-10-19 17:07:53.702', NULL, 'c6599dbbb04302146398615a0caf9e2d', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at >= tickets.updated_at;