review(filbert): row 59 round 2 packet, rebased on 3d298920 after rows 74, 58 and 60 (#1548)

Rebase only, per rev 571. Two conflicts resolved: the agents branch in
broker.mjs next to row 58's tasks line, and the bus.css widths line.
Merged hunks in broker.mjs and the bus README are named in build.md.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-11 19:46:40 -05:00
co-authored by Claude Opus 5.5
parent 3d298920bd
commit 93fc00e4a9
3 changed files with 153 additions and 27 deletions
+22 -20
View File
@@ -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
<p class="small muted">Board seats stay on the <a href="#/">control board</a>. This view is about roles.</p>`;
}
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']]);