diff --git a/agents/filbert/work/queue-59/build.md b/agents/filbert/work/queue-59/build.md index 653eb43ca..b81cb8cdc 100644 --- a/agents/filbert/work/queue-59/build.md +++ b/agents/filbert/work/queue-59/build.md @@ -1,3 +1,127 @@ +# Row 59 (#1548): bus read, agent state per role, round 2 + +Filbert, 2026-10-12. Brief: `docs/plans/2026-10-10_design-implementation.md`, +"Bus read: agent state per role" (blob a360554c). Darkwing and Dewey +review. Sage commits after the gate. Nothing in the candidate is committed, +staged or pushed. + +Base 3d298920, which is row 60's landing (1771bf98) plus Sage's queue and +log commits. `build.patch` applies there with `git apply --index`, and +`candidate-manifest.sha256` pins all 8 files after the patch. Round 1 was +manifest `90d5bddc…2f71` on f2f2861b. + +## Round 2: rebase only + +Sage set the scope at rev 571: rebase onto row 60's landing, a digest check, +and the merged hunks in `broker.mjs` and the bus README named here. Nothing +new goes in, so the round 1 questions and both reviewers' earlier reading +still apply. + +### What landed on the manifest paths + +Since f2f2861b, three rows changed 7 of the 8 files. Only +`packages/bus/tests/agents.test.mjs`, which is new, is untouched. + +- Row 74 (351464ce): `packages/webui/README.md`, the preview section. +- Row 58 (aaf87213): `broker.mjs` (`#taskRows` and the `tasks` branch), the + bus README, the webui README, `bus.css`, `bus.js` (the Tasks view), + `bus-browser.test.mjs` and `bus.test.mjs`. +- Row 60 (1771bf98): `broker.mjs` (the constructor option, the reader + allowlist and the `credentials` case), the bus README, the webui README and + `bus.test.mjs`. + +### Digest check + +Round 1's patch applies to 3d298920 with `git apply --3way`, with two +conflicts (below). I compared the round 1 and round 2 patches by their added +and removed lines. They're equal except for one line in `bus.css`. Each of +the 7 changed files has a new digest because its base changed. The digest of +`agents.test.mjs` is unchanged. + +### Merged hunks + +Line numbers are in the round 2 tree. + +`packages/bus/src/broker.mjs`: + +- The `agents` branch (lines 852–859) was a conflict. Round 1 replaced + `if (verb === 'agents') return …` with a block that maps each claim + through `#agentState` for human and reader sessions. Row 58 had replaced + the next statement, the inline `tasks` query, with + `if (verb === 'tasks') return this.#taskRows(s.business);`. Git saw the + two as one hunk. The fix keeps row 58's line as it is (line 860) and puts + round 1's block above it, unchanged. +- `#agentState` (lines 910–931) sits after the end of `#dispatch`, as in + round 1. Row 60's `credentials` case (lines 886–905) is inside the switch, + above `default:`. They share no lines. +- Row 58's `#taskRows` (line 313), and row 60's constructor option and + reader allowlist (line 495), are untouched. The allowlist already had + `agents`, so the reader route needs no change. + +`packages/bus/README.md` (applied with no conflict): + +- Verb table: round 1 split the `inbox`, `tasks`, `agents` row so that + `agents` has its own row (lines 128–129). Row 60's `decisions` and + `credentials` rows follow `trail` (lines 130–132). They share no lines + with round 1's edit. The table now reads `inbox, tasks`, `agents`, + `trail`, `decisions`, `credentials`. +- The "Agent state (row 59, #1548)" section sits after the table (lines + 134–160), as in round 1. Row 60's `credentials` text (from line 241) and + row 58's priority and requirement text (line 279) are further down and + untouched. + +The other files: + +- `bus.css`, line 28, was the second conflict. Row 58 raised + `table.s1-tasks` from `min-width:900px` to 1020px, and round 1 raised + `table.s1-agents` from 820px to 1000px on the same line. The line now has + both: 1020 and 1000. This is the one changed line that differs from round 1. +- `bus.js`: the Agents view hunk (lines 331–347) applied cleanly. Row 58's + Tasks view changes end above it, at line 324. +- `webui/README.md`: the "Agent state" section (lines 174–184) sits after + the slice 1 views text. Row 74's preview section, row 58's S5 bullet and + row 60's bus-read paragraph are elsewhere in the file. +- `bus-browser.test.mjs` (lines 39–42, 68–70, 230–249) and `bus.test.mjs` + (lines 76–77) applied cleanly, with no lines shared with row 58 or row 60. + +## Gate (my run on the round 2 candidate) + +I ran these in sequence in a worktree at 3d298920 with the patch, with +`TMPDIR` in my scratch and `DOCKER_HOST` pointed at a missing socket, from +2026-10-12T00:39:22Z to 00:43:55Z: + +| Suite | Result | +|---|---| +| packages/bus | 94/0 (88 on 3d298920; 6 new) | +| packages/control-board | 124/0 | +| packages/webui | 62/0, the browser and preview tests included (round 1 adds assertions, not tests) | +| packages/cli | 114/0, since it reads `agents` | +| scripts/test-*.sh | all nine exit 0: auth 15, conductor 17, config 24, discord 66, extension-package 18, foundation 44, queue 27, release 4, task 26 | + +`test-release` and `test-task` skipped their Docker cases because no daemon +was running. Sage's gate rerun covers those. No test calls a model. The logs +are in my scratch (`r59/gate2/`), not in the repository. + +## Mutants (round 2) + +I reran all 29 round 1 mutants on the round 2 tree from 00:43:56Z to +00:46:05Z, with the same runner and targets. Every target was found once. +28 were killed, as in round 1. The one survivor is again `b-msg-any-role`, +which round 1 explains as equivalent. Afterwards `git diff` was unchanged +and the tree checked against the manifest. + +Correction to round 1: that packet says the diff was unchanged after the +mutants. In fact the full round 1 run recorded a changed diff, and only the +rerun of the fixed mutants recorded it unchanged. The likely cause is that I +edited the tests for the four survivors during the full run, but I didn't +confirm it. This round's full run settles the point. + +--- + +The round 1 packet follows unchanged: the description, files, round 1 +mutants, round 1 gate and questions. Its base, line numbers and overlap +notes are round 1's. + # Row 59 (#1548): bus read, agent state per role, round 1 Filbert, 2026-10-11. Brief: `docs/plans/2026-10-10_design-implementation.md`, diff --git a/agents/filbert/work/queue-59/build.patch b/agents/filbert/work/queue-59/build.patch index a493dc659..810f8d16e 100644 --- a/agents/filbert/work/queue-59/build.patch +++ b/agents/filbert/work/queue-59/build.patch @@ -1,8 +1,8 @@ diff --git a/packages/bus/README.md b/packages/bus/README.md -index 5b57b7fc..30ed0ab5 100644 +index 82597eeedf85222d2abe8e4902321c41a85c064d..08be63070f3ad4e6367d1dcc4670a3db97ef377a 100644 --- a/packages/bus/README.md +++ b/packages/bus/README.md -@@ -125,9 +125,37 @@ an operator inspect content and delivery evidence after an uncertain result. +@@ -125,11 +125,39 @@ an operator inspect content and delivery evidence after an uncertain result. | `message.read` | `{id}`; recipient holder's acknowledgement; no new holder can acknowledge old holder's delivery. | | `event.emit` | `{kind:'action.allowed',body:{action:'routine',target?},subject?}`; routine observations only. | | `launch.revoke`, `launch.restore` | No args; outside-agent human CLI only. | @@ -10,6 +10,8 @@ index 5b57b7fc..30ed0ab5 100644 +| `inbox`, `tasks` | No args; plain JSON projections scoped to capability's business. | +| `agents` | No args; each held role's latest claim row in the capability's business. Human and reader sessions also get `state`, `working` and `inputNeeded` (Agent state, below); a role session gets the claim rows only. | | `trail` | `{subject}`: task ref, decision UUID or message UUID. Linked records in broker write order. | + | `decisions` | `{list}`: `roles` or `recent`; human and reader sessions only. Open decisions routed to a role, or the last 50 closed. | + | `credentials` | No args; human and reader sessions only. `[{service,account,role,dateKind,date,state}]` for the capability's business, never a token, file path or variable name. | +### Agent state (row 59, #1548) + @@ -42,10 +44,10 @@ index 5b57b7fc..30ed0ab5 100644 evidence fails, the caller receives the static `storage-unavailable` code. `human` is the reserved recipient. Message classes are REQUEST, ASSIGNMENT, REVIEW-REQUEST, REVIEW-RESULT, diff --git a/packages/bus/src/broker.mjs b/packages/bus/src/broker.mjs -index 84db8799..d471d600 100644 +index d731988331dcfa37a0f02c6c108595f10638fd08..5e86c60c75b9b92ad5467aa27b5a6bee2ab713ea 100644 --- a/packages/bus/src/broker.mjs +++ b/packages/bus/src/broker.mjs -@@ -825,11 +825,14 @@ export class Broker { +@@ -849,11 +849,14 @@ export class Broker { s.human || s.reader ? 'human' : s.role, ) .map((d) => this.#decisionView(d)); @@ -59,10 +61,10 @@ index 84db8799..d471d600 100644 + // A role session gets the claims only: another role's decisions aren't its to read. + return s.human || s.reader ? claims.map((c) => this.#agentState(c)) : claims; + } - if (verb === 'tasks') - return this.#store - .all('SELECT * FROM task_current WHERE business=? ORDER BY task_ref', s.business) -@@ -861,6 +864,28 @@ export class Broker { + if (verb === 'tasks') return this.#taskRows(s.business); + return this.#trail(s, identifier(a.subject)); + } +@@ -904,6 +907,28 @@ export class Broker { fail('unknown-verb'); } } @@ -93,7 +95,7 @@ index 84db8799..d471d600 100644 'INSERT INTO role_claims(at,business,role,op,holder_run,harness,address,by,decision) VALUES(?,?,?,?,?,?,?,?,?)', diff --git a/packages/bus/tests/agents.test.mjs b/packages/bus/tests/agents.test.mjs new file mode 100644 -index 00000000..23b5126b +index 0000000000000000000000000000000000000000..23b5126b32bd3964c30a52fbb48b50ce9a699553 --- /dev/null +++ b/packages/bus/tests/agents.test.mjs @@ -0,0 +1,159 @@ @@ -257,10 +259,10 @@ index 00000000..23b5126b + assert.deepEqual([there.state, there.working.messages, there.inputNeeded.length], ['working', 1, 1]); +}); diff --git a/packages/webui/README.md b/packages/webui/README.md -index e43118d5..092b6b0e 100644 +index e2ffcb3bb5b96a45d22fe7ad4c10fbc7990e07a6..c866804c61aab892a5d660436edf7b6f51a59bd8 100644 --- a/packages/webui/README.md +++ b/packages/webui/README.md -@@ -101,6 +101,17 @@ note is `agents/dewey/work/wui/SLICE1-VIEWS.md`. +@@ -171,6 +171,17 @@ note is `agents/dewey/work/wui/SLICE1-VIEWS.md`. example `human-required` from a Console started inside an agent run), "No bus to read" (no system config, or no bus host and no `--business`) or "The read failed". @@ -279,23 +281,23 @@ index e43118d5..092b6b0e 100644 The Console is restyled to `docs/design` (`IMPLEMENTING.md`). It is a restyle diff --git a/packages/webui/src/public/bus.css b/packages/webui/src/public/bus.css -index 39cf2991..54d2c736 100644 +index acf496a53a486ff7df8cdd33fa42ac19cf5d6d2a..fc8507e370868d3fcb9f69b428fbd744361e98ab 100644 --- a/packages/webui/src/public/bus.css +++ b/packages/webui/src/public/bus.css @@ -25,7 +25,7 @@ body.on-bus .frame,body.on-bus.has-inspector .frame{grid-template-columns:240px .s1-plain{list-style:none;padding:0;margin:0 0 10px;display:grid;gap:6px}.s1-plain li{overflow-wrap:anywhere} .chips .chip{gap:6px}.panel{margin-bottom:16px}.panel h3{font-size:1rem;margin:14px 0 6px} /* Tables */ --table.s1-table td,table.s1-table th{overflow-wrap:anywhere}table.s1-tasks{min-width:900px}table.s1-tasks .s1-title{min-width:220px;max-width:340px}table.s1-agents{min-width:820px} -+table.s1-table td,table.s1-table th{overflow-wrap:anywhere}table.s1-tasks{min-width:900px}table.s1-tasks .s1-title{min-width:220px;max-width:340px}table.s1-agents{min-width:1000px} +-table.s1-table td,table.s1-table th{overflow-wrap:anywhere}table.s1-tasks{min-width:1020px}table.s1-tasks .s1-title{min-width:220px;max-width:340px}table.s1-agents{min-width:820px} ++table.s1-table td,table.s1-table th{overflow-wrap:anywhere}table.s1-tasks{min-width:1020px}table.s1-tasks .s1-title{min-width:220px;max-width:340px}table.s1-agents{min-width:1000px} table.s1-table tbody th{font-weight:600;text-transform:none;letter-spacing:0;color:var(--text);font-size:.9rem;white-space:normal} .s1-done summary{list-style:none}.s1-done summary h2{display:inline}.s1-done summary::before{content:'▸ ';color:var(--muted)}.s1-done[open] summary::before{content:'▾ '}.s1-done{margin-bottom:20px} .s1-marker{text-decoration:none}.s1-launch{display:flex;gap:8px;align-items:center;flex-wrap:wrap} diff --git a/packages/webui/src/public/bus.js b/packages/webui/src/public/bus.js -index affb9b7b..8422a87a 100644 +index 3be22af5695511ce6f34948c77e49939bf5d95e9..b22bcf009cf8c93c2811e095ac84b5d83efad8df 100644 --- a/packages/webui/src/public/bus.js +++ b/packages/webui/src/public/bus.js -@@ -325,12 +325,23 @@ +@@ -328,12 +328,23 @@ } // Agents @@ -323,7 +325,7 @@ index affb9b7b..8422a87a 100644
Board seats stay on the control board. This view is about roles.
`; } diff --git a/packages/webui/tests/bus-browser.test.mjs b/packages/webui/tests/bus-browser.test.mjs -index aebd3c30..200f9428 100644 +index 9faa15eb47f10a804f766f7a9d7d1bfdba6b022b..9369de62f6d2fad6a9d991b60a7f32f9917bac61 100644 --- a/packages/webui/tests/bus-browser.test.mjs +++ b/packages/webui/tests/bus-browser.test.mjs @@ -36,7 +36,10 @@ function seed(root) { @@ -349,7 +351,7 @@ index aebd3c30..200f9428 100644 } test('S5 pages in a browser: real broker rows, inert text, Copy, routes, failures, layout and no writes', { timeout: 180000 }, async () => { -@@ -212,6 +217,26 @@ test('S5 pages in a browser: real broker rows, inert text, Copy, routes, failure +@@ -222,6 +227,26 @@ test('S5 pages in a browser: real broker rows, inert text, Copy, routes, failure await go('#/agents', 'Agents'); assert.deepEqual(await b.evaluate('[...document.querySelectorAll("#bus-view table.s1-agents tbody th")].map(e=>e.textContent)').then(r => r.sort()), ['coder', 'cto', 'pm']); assert.match(await b.evaluate('[...document.querySelectorAll("#bus-view table.s1-agents tbody tr")].find(r=>r.querySelector("th").textContent==="cto").textContent'), /cto-runclaude-codecto-thread/); @@ -377,10 +379,10 @@ index aebd3c30..200f9428 100644 assert.ok((await text('#bus-view')).includes(`${label}: not in the Q1 module`), label); await noOverflow('agents'); diff --git a/packages/webui/tests/bus.test.mjs b/packages/webui/tests/bus.test.mjs -index 2d9ca6ba..5b078168 100644 +index be677a5b2ef4d08d83cb918880a0c39efd3497a5..46d8016c3a2ef855a6041ba187f3ae4c9174c304 100644 --- a/packages/webui/tests/bus.test.mjs +++ b/packages/webui/tests/bus.test.mjs -@@ -70,6 +70,8 @@ test('bus routes serve the four reads from the reader view, unescaped JSON for t +@@ -73,6 +73,8 @@ test('bus routes serve the four reads from the reader view, unescaped JSON for t const agents = await read('/api/bus/agents'); assert.deepEqual(agents.body.rows.map(r => [r.role, r.op]), [['coder', 'claim']]); diff --git a/agents/filbert/work/queue-59/candidate-manifest.sha256 b/agents/filbert/work/queue-59/candidate-manifest.sha256 index e859eced3..baad3f5f9 100644 --- a/agents/filbert/work/queue-59/candidate-manifest.sha256 +++ b/agents/filbert/work/queue-59/candidate-manifest.sha256 @@ -1,8 +1,8 @@ -bc354048f0df93aefd8a58cae1f2421df066efce48beefc7f23fe46763fe43bd packages/bus/README.md -4701efe9d7edf5869ed011395d114b8156b99f735b841f6cab0255a635ae5bca packages/bus/src/broker.mjs +247c449632ec33e8840edc290f26a479274c7c45c060fd7045c352f6e83124c9 packages/bus/README.md +cedd7d0cc09f5792529b1c28897b19c9178fba1c4d8008e7fa6aae3ccd128c7d packages/bus/src/broker.mjs 4e5c3fe7793b9a026f274f0645c440907c467c9fdc11324f167bcb9bdd1fd31b packages/bus/tests/agents.test.mjs -f2b91ca5ffab6ae5ad19f66bc4d11cb6cf99777f1cf18a3c44449a0998ad664f packages/webui/README.md -cd0fa9e4a7fa00275aacf89eb73007baa193c6a08ea135b9bf48f596d32e418a packages/webui/src/public/bus.css -899ef3e3a27ba14100135dd92a71110556113feb2585db99648624e50400aab2 packages/webui/src/public/bus.js -acefab3ff732fa255b207cd3105589ee30f3f2c94a7ba651528f0f73fe4b0e53 packages/webui/tests/bus-browser.test.mjs -a3d33ee916598525d5e8ea86202b96fda9416dd798990ac39ee7b786cb68ee3a packages/webui/tests/bus.test.mjs +4e39f69de7394f89e364d782352b475e633f93b0cee543d0e862eea9b3bbbb84 packages/webui/README.md +15f3523f11eb50d7a87060c18dd1fa67c688353c641605dc8d3f540acfc6927e packages/webui/src/public/bus.css +9b42aef343e1a06432cab8a606c627e9101f40b6d2d274c6c6ae0e646edc60e5 packages/webui/src/public/bus.js +7fb9f7ea1253a7a8cb8949fd6eb8854c540ad772d7a1c70b1e667d943027438a packages/webui/tests/bus-browser.test.mjs +f7f19a906a273cd2bf58910e894f049bfe661932c510bd1506c08bd4194e0a46 packages/webui/tests/bus.test.mjs