Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -1,16 +1,17 @@
|
||||
diff --git a/packages/bus/README.md b/packages/bus/README.md
|
||||
index 5b57b7fc..a9517a1d 100644
|
||||
index 7fa51f92..82597eee 100644
|
||||
--- a/packages/bus/README.md
|
||||
+++ b/packages/bus/README.md
|
||||
@@ -127,6 +127,7 @@ an operator inspect content and delivery evidence after an uncertain result.
|
||||
@@ -127,6 +127,8 @@ an operator inspect content and delivery evidence after an uncertain result.
|
||||
| `launch.revoke`, `launch.restore` | No args; outside-agent human CLI only. |
|
||||
| `inbox`, `tasks`, `agents` | No args; plain JSON projections scoped to capability's business. |
|
||||
| `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. |
|
||||
|
||||
Unknown keys, roles, references, actions and verbs refuse. If writing refusal
|
||||
evidence fails, the caller receives the static `storage-unavailable` code. `human` is the reserved
|
||||
@@ -196,7 +197,7 @@ must not invoke the human CLI or work around its proof.
|
||||
@@ -196,7 +198,7 @@ must not invoke the human CLI or work around its proof.
|
||||
|
||||
Human resolutions and launch toggles append `human.input`. Agent capabilities
|
||||
and read-only WebUI capabilities cannot reach these operations. Reader
|
||||
@@ -19,7 +20,7 @@ index 5b57b7fc..a9517a1d 100644
|
||||
business; they do not confer mutation or resolution authority.
|
||||
|
||||
`decisions` (row 57, #1546) is for human and reader sessions only; a role
|
||||
@@ -208,6 +209,26 @@ each with `closed`, the closing `decision_events` row. Every row is the
|
||||
@@ -208,6 +210,30 @@ each with `closed`, the closing `decision_events` row. Every row is the
|
||||
decision as `trail` gives the same session for its id, so the lists add no
|
||||
data a reader couldn't already read one id at a time; they add the listing.
|
||||
|
||||
@@ -40,14 +41,18 @@ index 5b57b7fc..a9517a1d 100644
|
||||
+`credentials.use`, and the result passes the known-token check like every
|
||||
+other read. The rows match the Business view's credentials in the WebUI
|
||||
+(`packages/webui/src/reads.mjs`), which reads the business file instead: the
|
||||
+file says what the host should load, this read says what it did load, since
|
||||
+a token file rotated after startup isn't reread until restart.
|
||||
+file says what the host should load, this read says what it did load. The
|
||||
+host takes the dates and accounts from the business file at startup, and
|
||||
+only the state moves with the clock. So the two differ only when the
|
||||
+business file changes after startup: a date, an account, or a credential
|
||||
+added or removed. Rotating a token file without editing its date changes
|
||||
+neither.
|
||||
+
|
||||
## Shared reads and adapter boundary
|
||||
|
||||
```js
|
||||
diff --git a/packages/bus/src/broker.mjs b/packages/bus/src/broker.mjs
|
||||
index 84db8799..18c9bc0d 100644
|
||||
index 595ca232..d7319883 100644
|
||||
--- a/packages/bus/src/broker.mjs
|
||||
+++ b/packages/bus/src/broker.mjs
|
||||
@@ -86,12 +86,15 @@ export class Broker {
|
||||
@@ -67,7 +72,7 @@ index 84db8799..18c9bc0d 100644
|
||||
for (const table of [
|
||||
'events',
|
||||
'role_claims',
|
||||
@@ -468,7 +471,7 @@ export class Broker {
|
||||
@@ -489,7 +492,7 @@ export class Broker {
|
||||
if (!object(args)) fail('invalid-request');
|
||||
this.#secretCheck(args);
|
||||
return this.#store.transaction(() => {
|
||||
@@ -76,7 +81,7 @@ index 84db8799..18c9bc0d 100644
|
||||
fail('read-only');
|
||||
const result = this.#dispatch(s, request.verb, args);
|
||||
this.#secretCheck(result);
|
||||
@@ -857,6 +860,28 @@ export class Broker {
|
||||
@@ -875,6 +878,28 @@ export class Broker {
|
||||
.map((d) => ({ ...this.#decisionView(d), closed: this.#closed(d.id) }));
|
||||
fail('invalid-request');
|
||||
}
|
||||
@@ -353,10 +358,10 @@ index 00000000..f3f20142
|
||||
+ assert.deepEqual(clean(stored, words), []);
|
||||
+});
|
||||
diff --git a/packages/webui/README.md b/packages/webui/README.md
|
||||
index e43118d5..fedb9195 100644
|
||||
index bb7fc399..e2ffcb3b 100644
|
||||
--- a/packages/webui/README.md
|
||||
+++ b/packages/webui/README.md
|
||||
@@ -194,19 +194,23 @@ session reader or transport is implemented here. The session reader is
|
||||
@@ -264,19 +264,23 @@ session reader or transport is implemented here. The session reader is
|
||||
`packages/conversation`, served by the board.
|
||||
|
||||
GET `/api/bus/inbox`, `/api/bus/tasks`, `/api/bus/agents`,
|
||||
@@ -404,7 +409,7 @@ index 8fee21a6..ca1bab89 100644
|
||||
import { spawn } from 'node:child_process';
|
||||
import { HUMAN_CLI } from '../../cli/src/transport.mjs';
|
||||
diff --git a/packages/webui/src/serve.mjs b/packages/webui/src/serve.mjs
|
||||
index 4d51942a..c0f10275 100644
|
||||
index a1861d5d..89327c07 100644
|
||||
--- a/packages/webui/src/serve.mjs
|
||||
+++ b/packages/webui/src/serve.mjs
|
||||
@@ -46,8 +46,9 @@ async function body(req) {
|
||||
@@ -420,10 +425,10 @@ index 4d51942a..c0f10275 100644
|
||||
async function busRead(res, bus, verb, search) {
|
||||
let arg;
|
||||
diff --git a/packages/webui/tests/bus.test.mjs b/packages/webui/tests/bus.test.mjs
|
||||
index 2d9ca6ba..2b429352 100644
|
||||
index cf477052..be677a5b 100644
|
||||
--- a/packages/webui/tests/bus.test.mjs
|
||||
+++ b/packages/webui/tests/bus.test.mjs
|
||||
@@ -123,15 +123,38 @@ test('decisions route serves the roles and recent lists from the reader view', a
|
||||
@@ -126,15 +126,38 @@ test('decisions route serves the roles and recent lists from the reader view', a
|
||||
assert.equal(calls.length, before);
|
||||
});
|
||||
|
||||
@@ -463,7 +468,7 @@ index 2d9ca6ba..2b429352 100644
|
||||
}
|
||||
for (const path of ['/api/bus/decide', '/api/bus/seen', '/api/bus/', '/api/bus/inbox/x', '/api/bus/request', '/api/bus/raise']) {
|
||||
assert.equal((await fetch(base + path)).status, 404, path);
|
||||
@@ -216,6 +239,7 @@ test('busReader takes --business, else the live bus host, else refuses', async t
|
||||
@@ -219,6 +242,7 @@ test('busReader takes --business, else the live bus host, else refuses', async t
|
||||
const pinned = busReader({ dataRoot, socket: 'sock', business: 'pinned', cli });
|
||||
assert.equal((await pinned.inbox()).request.business, 'pinned');
|
||||
assert.deepEqual((await pinned.decisions('recent')).request, { business: 'pinned', verb: 'decisions', args: { list: 'recent' } });
|
||||
|
||||
Reference in New Issue
Block a user