bus, cli, webui: every message to the human, read state, Messages page (#1588)

Row 94, round 2. Rocko built it, Dewey approved it (comment 28104) on
manifest 53b01ea9 (16 paths, base e918a915). The bus keeps a messages
view with read state, where delivered but not read stays read:false. The
CLI gains messages and follow, and inbox leaves out messages already
read while inbox --json stays byte-compatible. The Console gets a
Messages page and an unread count in the nav. Mos gave the go under
decision 123 (public/ files). Sage gate on 645489e4 plus the patch,
12:52:14Z to 12:55:44Z: bus 115, cli 129, webui 104, all fail 0. Every
scripts/test-*.sh exited 0 (auth 15, conductor 17, config 24, discord
66, extension-package 18, foundation 44, queue 27, release 14, task 98).
Manifest 16/16 before and after.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-13 07:58:36 -05:00
co-authored by Claude Opus 5.5
parent 645489e4cc
commit 2b2a9e14ee
16 changed files with 441 additions and 42 deletions
+28 -2
View File
@@ -276,7 +276,7 @@ delivery may be unknown: inspect the seat before sending again.
## Inbox, tasks, agents and trails (slice 1 S5, #1522)
The Console sidebar adds Inbox, Tasks and Agents next to the control board,
which stays at `#/`. Routes: `#/inbox`, `#/inbox/<decision>`, `#/tasks`,
which stays at `#/`. Routes: `#/inbox`, `#/inbox/<decision>`, `#/messages`, `#/tasks`,
`#/tasks/<vikunja:project/task>`, `#/agents`, `#/trail/task/<ref>`,
`#/trail/decision/<id>` and `#/trail/message/<id>` (row 76), with `?kind=` filters on a trail. The design
note is `agents/dewey/work/wui/SLICE1-VIEWS.md`.
@@ -466,7 +466,8 @@ session reader or transport is implemented here. The session reader is
GET `/api/bus/inbox`, `/api/bus/tasks`, `/api/bus/agents`,
`/api/bus/trail?subject=<id>`, `/api/bus/decisions?list=roles|recent`,
`/api/bus/credentials` and `/api/bus/replies?id=<message id>` are the bus
`/api/bus/credentials`, `/api/bus/replies?id=<message id>` and
`/api/bus/messages?limit=50&after=<message id>` are the bus
reads (`src/bus.mjs`). Any other method is 405. The subject and the id must
match the broker's identifier rule, and the list must be `roles` or
`recent`, else 400. `replies` (row 81, #1575) is the messages whose
@@ -633,3 +634,28 @@ say-so, not a test result. Keep #1507 open pending that ruling.
Rollback requires only stopping the WebUI and using the unchanged board at 7331.
Revert the scoped WebUI commit to remove it; there is no data migration to undo.
Seen and reply actions already taken belong to the board and are not rolled back.
## Messages (row 94, #1588)
The Messages page shows every message addressed to the human, newest first,
including unsolicited messages and late replies. Each lists sender, class,
time, read state, literal body and a trail link. It polls at the existing
10-second cadence; pause and refresh work as on the other pages. Older
messages and Newest messages links page through the history. The nav count
is the whole feed's unread count, including messages beyond the visible
page. If that count cannot be read, it is hidden; a bus refusal clears kept
data as on the other pages. Reading this page marks nothing delivered or
read. `mosaic follow` or `mosaic talk --follow` prints messages and marks
them read in the terminal. The Console does not consume them.
The messages HTTP read accepts only limit (1–200, default 50) and after
(a message id cursor); malformed, duplicate or unknown query keys refuse
400 invalid-request. It returns rows plus total, unread, next and the
Console read time at. Older read routes retain their rows/at response.
The broker owns business scoping and cursor authorization.
`messages.test.mjs` exercises the route's paging/refusals and existing
route response shapes, then the page against a temporary broker with
a scheduled poll accelerated in the browser test. It proves literal
content, late unsolicited arrival, pagination, full unread count and
unchanged delivery receipts. No live bus data or service is used.