launchpad: row 294 round 2 (#1800): browser.test pin gains /federation.js at index 2 (Mos mos-1412 (a)), G5 pins one action.refused {code: access-refused} per refused verb and every other table unchanged (sage-3194); manifest round 2 (18 paths), ASSERTION-PRESERVATION.json, run 1 receipts; unrun
This commit is contained in:
1 parent
685ff053b6
commit
66c1817176
11 files changed
+139
-18
No files matched your search
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"row": 294,
|
||||||
|
"round": 2,
|
||||||
|
"ruling": "mos-1412 (through sage-3195): option (a) approved, (b) rejected",
|
||||||
|
"changes": [
|
||||||
|
{
|
||||||
|
"file": "packages/webui/tests/browser.test.mjs",
|
||||||
|
"line": 21,
|
||||||
|
"kind": "comment",
|
||||||
|
"old": " // Rows 129, 154, 191 and 194: chat.js, editor.js, processing.js and agents.js are the scripts added, same origin; the list is the pin, so another script is a visible change.",
|
||||||
|
"new": " // Rows 129, 154, 191, 194 and 294: chat.js, editor.js, processing.js, agents.js and federation.js are the scripts added, same origin; the list is the pin, so another script is a visible change."
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"file": "packages/webui/tests/browser.test.mjs",
|
||||||
|
"line": 22,
|
||||||
|
"kind": "assertion",
|
||||||
|
"old": " assert.deepEqual(await b.evaluate('[...document.querySelectorAll(\"script\")].map(s => s.getAttribute(\"src\"))'), ['/editor.js', '/processing.js', '/brand.js', '/app.js', '/markdown-preview.js', '/chat.js', '/agents.js', '/bus.js']);",
|
||||||
|
"new": " assert.deepEqual(await b.evaluate('[...document.querySelectorAll(\"script\")].map(s => s.getAttribute(\"src\"))'), ['/editor.js', '/processing.js', '/federation.js', '/brand.js', '/app.js', '/markdown-preview.js', '/chat.js', '/agents.js', '/bus.js']);"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"unchanged": "every other line of browser.test.mjs is byte-identical to c902a767d"
|
||||||
|
}
|
||||||
@@ -204,7 +204,12 @@ and an in-process Broker with an access function, like bus/tests/user-principal.
|
|||||||
routes, agents, processing, project files, /api/bus/message, /api/board), a user session gets
|
routes, agents, processing, project files, /api/bus/message, /api/board), a user session gets
|
||||||
403 `owner-only` and the transport ran zero times.
|
403 `owner-only` and the transport ran zero times.
|
||||||
- G5 the bus refusal stands alone: the same session's user transport, called directly with each
|
- G5 the bus refusal stands alone: the same session's user transport, called directly with each
|
||||||
owner verb, gets `access-refused` from the broker and nothing is written.
|
owner verb, gets `access-refused` from the broker. The only write is the broker's own refusal
|
||||||
|
evidence: exactly one `action.refused` event per verb, the count taken from the verb list's length
|
||||||
|
(22 today), each body exactly `{ code: 'access-refused' }`, and every other table's row count
|
||||||
|
unchanged (round 2; run 1 placed the round 1 "events unchanged" pin as a test defect, sage-3194).
|
||||||
|
The broker's `#refused` (bus broker.mjs:4423) writes the code alone and no verb, so the test can't
|
||||||
|
match each event to its verb; pinning the whole body means a field added there shows up here.
|
||||||
- G9 the C6 seam (sage-3153, sage-3157), with the test's userOptions built by userOptionsFor as
|
- G9 the C6 seam (sage-3153, sage-3157), with the test's userOptions built by userOptionsFor as
|
||||||
cli.mjs builds them: a user session runs the chat's project list, thread create, list,
|
cli.mjs builds them: a user session runs the chat's project list, thread create, list,
|
||||||
open, send and messages. The owner transport (a recording `ownerCall`) saw only
|
open, send and messages. The owner transport (a recording `ownerCall`) saw only
|
||||||
@@ -308,4 +313,40 @@ exception is accepted and does not go to Mos.
|
|||||||
- N4: the user-bus.mjs fold-back (C7) is proposed to Sage as a queue row, for the next
|
- N4: the user-bus.mjs fold-back (C7) is proposed to Sage as a queue row, for the next
|
||||||
channel-proof re-pin.
|
channel-proof re-pin.
|
||||||
|
|
||||||
|
Round 2 (Mos mos-1412 through Sage sage-3195; for Duckworth): two test changes after run 1, no
|
||||||
|
product change. The manifest adds packages/webui/tests/browser.test.mjs (18 paths).
|
||||||
|
|
||||||
|
- Red 1, old test, Mos approved (a): browser.test.mjs:22 pins index.html's script list. It gains
|
||||||
|
'/federation.js' at index 2, where 294's index.html:7 puts it, ahead of brand.js. The :21 comment
|
||||||
|
adds row 294 and federation.js. No other assertion in the file changes. Old and new lines are in
|
||||||
|
ASSERTION-PRESERVATION.json. (b), loading the federation view another way, was rejected.
|
||||||
|
- Red 2, new test G5: the pin is the one in the G5 note above. Mos's suggestion is taken: the count
|
||||||
|
is `refusals.length`, not a literal. The verb check is not possible, because the event names no
|
||||||
|
verb; the test pins the whole body instead.
|
||||||
|
|
||||||
## Runs
|
## Runs
|
||||||
|
|
||||||
|
### Run 1, 2026-10-23 04:57Z (sage-3187 CLEAR), head 685ff053b, manifest 0b3f9c9d…94f3
|
||||||
|
|
||||||
|
Before the run, the branch was rebased from 253346e3c onto c902a767d. `git range-diff -s` showed all 6
|
||||||
|
commits "=", and the stable patch-ids matched. The head was pushed as launchpad/row294-on-c902a767d
|
||||||
|
024499fc2. TMPDIR was under /mnt/storage/scratch/tmp. npm ci --ignore-scripts ran at the root only.
|
||||||
|
|
||||||
|
| Step | Result | Time | Limit |
|
||||||
|
|---|---|---|---|
|
||||||
|
| webui suite | 365 tests: 362 pass, 2 fail, 1 skip | 55.8 s | 600 s |
|
||||||
|
|
||||||
|
The driver stopped at the first red, so the cli, bus, scripts and mutants did not run. The slot was
|
||||||
|
returned (launchpad-0060).
|
||||||
|
|
||||||
|
- browser.test.mjs:22, an old test, pins index.html's script list. 294 adds `/federation.js` at
|
||||||
|
index 2. It went to Mos through Sage (sage-3192); I made no change before the ruling.
|
||||||
|
- G5:262, a new test, failed `22 !== 0`: the broker writes one `action.refused` per refusal. This
|
||||||
|
was placed as a test defect under mos-1272 and accepted by Sage (sage-3194). It is fixed in round 2.
|
||||||
|
- The skip was the editor rebuild check (editor-provenance.test.mjs:162), which needs esbuild
|
||||||
|
0.28.2 from packages/webui's own lockfile. An environment fix: the next run also runs npm ci
|
||||||
|
--ignore-scripts in packages/webui (sage-3194).
|
||||||
|
- The last landed whole-webui gate skipped the same test: row 264a's run, webui 345 pass of 346 with
|
||||||
|
1 skipped, "the esbuild 0.28.1 editor rebuild" (gizmoduck queue-264 BUILD.md:516-518, DEFERRED
|
||||||
|
264a N2). Row 270's gate ran only webui pinned-copy.test. The fresh 294 gate still runs npm ci in
|
||||||
|
packages/webui first, so the test should run here. If it skips again, the run names it and says why.
|
||||||
@@ -1,15 +1,26 @@
|
|||||||
# Row 294 (FED R6, #1800) candidate manifest, round 1
|
# Row 294 (FED R6, #1800) candidate manifest, round 2
|
||||||
|
|
||||||
Branch launchpad/row294, base 253346e3c, pushed tip 9450774cbe7986d80150b27a4da33b43d93bf026.
|
Branch launchpad/row294, base c902a767d (the round 1 head ee77b3635 rebased with range-diff all "="
|
||||||
MANIFEST.sha256 lists the 17 code and test paths changed from the base, hashed from the tip's
|
and stable patch-ids unchanged; receipts in run1/). The round 2 head is the commit that adds this
|
||||||
blobs (`sha256sum -c` passes on the tip). BUILD.md is the row note and is not in the manifest.
|
file. MANIFEST.sha256 lists the 18 code and test paths changed from the base, hashed from that
|
||||||
No old test changes. webui/src/bus.mjs is byte-identical to the base (channel-proof hash pin, C7).
|
commit's blobs (`sha256sum -c` passes on it). BUILD.md, ASSERTION-PRESERVATION.json and run1/ are
|
||||||
packages/cli/tests/access.test.mjs is unchanged; packages/cli/src/access.mjs overlaps row 295,
|
the row note and are not in the manifest. webui/src/bus.mjs is byte-identical to the base
|
||||||
which rebases after this row (sage-3153).
|
(channel-proof hash pin, C7). packages/cli/tests/access.test.mjs is unchanged;
|
||||||
|
packages/cli/src/access.mjs overlaps row 295, which rebases after this row (sage-3153).
|
||||||
|
|
||||||
Nothing has run. Runs follow Duckworth's approval and Sage's test CLEAR, in slot order: each
|
Round 1 was 0b3f9c9d…94f3, approved by Duckworth (rev 3435, duckworth-0249b). Round 2 changes two
|
||||||
touched file alone, mutants M1-M11, the webui, cli and bus suites and every scripts/test-*.sh,
|
tests after run 1 went red, and no product file:
|
||||||
with the limits in BUILD.md.
|
|
||||||
|
- packages/webui/tests/browser.test.mjs (new to the manifest; an old test, Mos's ruling (a) in
|
||||||
|
mos-1412): the script-list pin at :22 gains '/federation.js' at index 2 and the :21 comment adds
|
||||||
|
row 294. No other line changes. ASSERTION-PRESERVATION.json has the old and new lines.
|
||||||
|
- packages/webui/tests/granted-user.test.mjs, G5 (new test, a run 1 placement Sage accepted in
|
||||||
|
sage-3194): exactly one `action.refused` per refused verb, the count from the verb list's length,
|
||||||
|
each body exactly `{ code: 'access-refused' }`, and every other table's row count unchanged.
|
||||||
|
|
||||||
|
Run 1 (webui only, stopped at the first red) is recorded in BUILD.md. The whole gate runs fresh on
|
||||||
|
Sage's next CLEAR: npm ci --ignore-scripts at the root and in packages/webui, the webui, cli and
|
||||||
|
bus suites, every scripts/test-*.sh, then mutants M1-M11, with the limits in BUILD.md.
|
||||||
|
|
||||||
## Exception for Duckworth to rule on: the owner transport in a user's chat (C6; mos-1394, sage-3157)
|
## Exception for Duckworth to rule on: the owner transport in a user's chat (C6; mos-1394, sage-3157)
|
||||||
|
|
||||||
|
|||||||
@@ -14,4 +14,5 @@ e7673188c1d76ecc63cdc24e7d1470922b1d69bedeb994a862e94924edfc27d2 packages/webui
|
|||||||
9343ea9edb862c1545df2886754244ffd76b714cc90d7791fc32aee4ecfec594 packages/webui/src/serve.mjs
|
9343ea9edb862c1545df2886754244ffd76b714cc90d7791fc32aee4ecfec594 packages/webui/src/serve.mjs
|
||||||
70b243ed9a83ff822a4c7a148528ff5153574cc87d5c776fd2e12f340762ed76 packages/webui/src/sso.mjs
|
70b243ed9a83ff822a4c7a148528ff5153574cc87d5c776fd2e12f340762ed76 packages/webui/src/sso.mjs
|
||||||
8cc1185beda9085ced62470f1b9e39d95dcca2dcc8bf9325c18c2f0b2da618dc packages/webui/src/user-bus.mjs
|
8cc1185beda9085ced62470f1b9e39d95dcca2dcc8bf9325c18c2f0b2da618dc packages/webui/src/user-bus.mjs
|
||||||
8f89a1cc853ad275e62a518eb4f5567b5aaa629d32060c11daaaa671aded29db packages/webui/tests/granted-user.test.mjs
|
58f022643839b78c0bd149927157d1f7b36977212975a4fe549c9661c31c4e40 packages/webui/tests/browser.test.mjs
|
||||||
|
8bf20e514817d21356e59ca21a8a99ee25609f084f4a26c5a409d71a90b6f6a4 packages/webui/tests/granted-user.test.mjs
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
4abc648140eef53c8cb841ae64c22afc4211d86b
|
||||||
|
bee007832071139bac9af318096710aeb95f1f79
|
||||||
|
6de7443b94d28676a42630986d86bac9de1479fb
|
||||||
|
f3ed47f0b12f628cdbf0efe66970e184eef74ae2
|
||||||
|
3cf8180c22ed655b4f163f7a35b06deb47b54493
|
||||||
|
d1689ae8ba689ab811560b5f8ae82d95cc745c3e
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
4abc648140eef53c8cb841ae64c22afc4211d86b
|
||||||
|
bee007832071139bac9af318096710aeb95f1f79
|
||||||
|
6de7443b94d28676a42630986d86bac9de1479fb
|
||||||
|
f3ed47f0b12f628cdbf0efe66970e184eef74ae2
|
||||||
|
3cf8180c22ed655b4f163f7a35b06deb47b54493
|
||||||
|
d1689ae8ba689ab811560b5f8ae82d95cc745c3e
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
1: c866a8a69 = 1: df21d2f4d launchpad: row 294 FED R6 build and plan, granted-user sign-in (unrun, #1800)
|
||||||
|
2: 338e93185 = 2: f392be6ac launchpad: row 294 rulings sage-3153 (boot refusal line, owner transport seam G9, C7 follow-up, access.test.mjs unchanged; unrun, #1800)
|
||||||
|
3: 77514b8b9 = 3: c22dcfdd0 launchpad: row 294 BUILD.md M4 kill names the moved test
|
||||||
|
4: 9450774cb = 4: 0622c2fc8 launchpad: row 294 sage-3157, owner-transport exception written out, userOptionsFor, G9 pins no user value, M10/M11 (unrun, #1800)
|
||||||
|
5: ca710eabd = 5: 65f1b81f3 launchpad: row 294 round 1 manifest (17 paths from 9450774cb) and notes with the owner-transport exception
|
||||||
|
6: ee77b3635 = 6: 024499fc2 launchpad: row 294 BUILD.md M1 expectation corrected (Duckworth C1), review recorded with N1-N4 dispositions
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
TMPDIR /mnt/storage/scratch/tmp/g8gFnfF head 685ff053b6336311668104d08826e923d9f4532d
|
||||||
|
webui rc=1 seconds=55.787 limit=600 04:58:35Z
|
||||||
|
STOP at webui
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
✖ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (3039.999029ms)
|
||||||
|
✖ R6 G5 the bus refuses every owner verb over the user transport on its own (555.936822ms)
|
||||||
|
ℹ tests 365
|
||||||
|
ℹ suites 0
|
||||||
|
ℹ pass 362
|
||||||
|
ℹ fail 2
|
||||||
|
ℹ cancelled 0
|
||||||
|
ℹ skipped 1
|
||||||
|
ℹ todo 0
|
||||||
|
ℹ duration_ms 55747.039135
|
||||||
|
✖ failing tests:
|
||||||
|
✖ served Console browser: real board fixtures, keyboard, drafts, receipts, themes, 320px and failures (3039.999029ms)
|
||||||
|
✖ R6 G5 the bus refuses every owner verb over the user transport on its own (555.936822ms)
|
||||||
@@ -18,8 +18,8 @@ test('served Console browser: real board fixtures, keyboard, drafts, receipts, t
|
|||||||
assert.equal(await b.evaluate('document.querySelector("#session-count").textContent'), '3 of 4');
|
assert.equal(await b.evaluate('document.querySelector("#session-count").textContent'), '3 of 4');
|
||||||
await b.evaluate('document.querySelector("#hide-offline").click()');
|
await b.evaluate('document.querySelector("#hide-offline").click()');
|
||||||
assert.equal(await b.evaluate('document.querySelectorAll("table.sessions tbody tr").length'), 4);
|
assert.equal(await b.evaluate('document.querySelectorAll("table.sessions tbody tr").length'), 4);
|
||||||
// Rows 129, 154, 191 and 194: chat.js, editor.js, processing.js and agents.js are the scripts added, same origin; the list is the pin, so another script is a visible change.
|
// Rows 129, 154, 191, 194 and 294: chat.js, editor.js, processing.js, agents.js and federation.js are the scripts added, same origin; the list is the pin, so another script is a visible change.
|
||||||
assert.deepEqual(await b.evaluate('[...document.querySelectorAll("script")].map(s => s.getAttribute("src"))'), ['/editor.js', '/processing.js', '/brand.js', '/app.js', '/markdown-preview.js', '/chat.js', '/agents.js', '/bus.js']);
|
assert.deepEqual(await b.evaluate('[...document.querySelectorAll("script")].map(s => s.getAttribute("src"))'), ['/editor.js', '/processing.js', '/federation.js', '/brand.js', '/app.js', '/markdown-preview.js', '/chat.js', '/agents.js', '/bus.js']);
|
||||||
assert.equal(await b.evaluate(`document.querySelectorAll('script[src="/processing.js"]').length`), 1);
|
assert.equal(await b.evaluate(`document.querySelectorAll('script[src="/processing.js"]').length`), 1);
|
||||||
assert.equal(await b.evaluate(`document.querySelectorAll('script[src="/chat.js"]').length`), 1);
|
assert.equal(await b.evaluate(`document.querySelectorAll('script[src="/chat.js"]').length`), 1);
|
||||||
assert.equal(await b.evaluate('!!window.injected'), false);
|
assert.equal(await b.evaluate('!!window.injected'), false);
|
||||||
|
|||||||
@@ -123,6 +123,9 @@ async function signIn(env, sub) {
|
|||||||
return { r, session: sessionOf(r) };
|
return { r, session: sessionOf(r) };
|
||||||
}
|
}
|
||||||
const events = env => env.store.get('SELECT count(*) n FROM events').n;
|
const events = env => env.store.get('SELECT count(*) n FROM events').n;
|
||||||
|
// Every table's row count but events', for a "nothing else written" pin.
|
||||||
|
const tables = env => Object.fromEntries(env.store.all("SELECT name FROM sqlite_master WHERE type='table' AND name NOT IN ('events', 'sqlite_sequence') ORDER BY name")
|
||||||
|
.map(({ name }) => [name, env.store.get(`SELECT count(*) n FROM "${name}"`).n]));
|
||||||
|
|
||||||
test('R6 G1 a granted user signs in, gets the user page and reaches the broker as itself', async t => {
|
test('R6 G1 a granted user signs in, gets the user page and reaches the broker as itself', async t => {
|
||||||
const env = await setup(t);
|
const env = await setup(t);
|
||||||
@@ -247,8 +250,8 @@ test('R6 G4 every owner route answers 403 owner-only before any bus call', async
|
|||||||
test('R6 G5 the bus refuses every owner verb over the user transport on its own', async t => {
|
test('R6 G5 the bus refuses every owner verb over the user transport on its own', async t => {
|
||||||
const env = await setup(t);
|
const env = await setup(t);
|
||||||
const o = consoleBus(env.userTransport('alice'), { send: true, owner: env.ownerCall });
|
const o = consoleBus(env.userTransport('alice'), { send: true, owner: env.ownerCall });
|
||||||
const before = events(env);
|
const before = env.store.get('SELECT max(seq) n FROM events').n, rest = tables(env);
|
||||||
for (const [why, run] of [
|
const refusals = [
|
||||||
['inbox', () => o.bus.inbox()], ['tasks', () => o.bus.tasks()], ['agents', () => o.bus.agents()], ['trail', () => o.bus.trail()],
|
['inbox', () => o.bus.inbox()], ['tasks', () => o.bus.tasks()], ['agents', () => o.bus.agents()], ['trail', () => o.bus.trail()],
|
||||||
['decisions', () => o.bus.decisions()], ['instances', () => o.bus.instances()], ['routes', () => o.bus.routes()], ['thread.claims', () => o.bus['thread.claims']()],
|
['decisions', () => o.bus.decisions()], ['instances', () => o.bus.instances()], ['routes', () => o.bus.routes()], ['thread.claims', () => o.bus['thread.claims']()],
|
||||||
['message.send', () => o.send({ to: 'chief', body: 'as the owner' })], ['limits.set', () => o.settingsWrite({ revision: 'x' })],
|
['message.send', () => o.send({ to: 'chief', body: 'as the owner' })], ['limits.set', () => o.settingsWrite({ revision: 'x' })],
|
||||||
@@ -258,8 +261,17 @@ test('R6 G5 the bus refuses every owner verb over the user transport on its own'
|
|||||||
['instance.launch', () => o.agentWrite('instance.launch', {})], ['processing.status', () => o.processing.read()],
|
['instance.launch', () => o.agentWrite('instance.launch', {})], ['processing.status', () => o.processing.read()],
|
||||||
['processing.halt', () => o.processing.halt({})], ['library.status', () => o.libraryStatus({})],
|
['processing.halt', () => o.processing.halt({})], ['library.status', () => o.libraryStatus({})],
|
||||||
['project.create', () => o.chat.createProject({ name: 'mine' })],
|
['project.create', () => o.chat.createProject({ name: 'mine' })],
|
||||||
]) await assert.rejects(Promise.resolve().then(run), e => e.code === 'access-refused', why);
|
];
|
||||||
assert.equal(events(env), before, 'a refused verb wrote');
|
for (const [why, run] of refusals) await assert.rejects(Promise.resolve().then(run), e => e.code === 'access-refused', why);
|
||||||
|
// The broker records each refusal (row 37): one action.refused per verb, its body the code
|
||||||
|
// alone (#refused names no verb). No other table gains or loses a row.
|
||||||
|
const added = env.store.all('SELECT kind, body FROM events WHERE seq > ? ORDER BY seq', before);
|
||||||
|
assert.equal(added.length, refusals.length, 'one event per refused verb');
|
||||||
|
for (const e of added) {
|
||||||
|
assert.equal(e.kind, 'action.refused');
|
||||||
|
assert.deepEqual(JSON.parse(e.body), { code: 'access-refused' });
|
||||||
|
}
|
||||||
|
assert.deepEqual(tables(env), rest, 'a refused verb wrote');
|
||||||
});
|
});
|
||||||
|
|
||||||
// sage-3153 (C6): in a user's chat the owner transport carries `plugins` with {} and nothing else,
|
// sage-3153 (C6): in a user's chat the owner transport carries `plugins` with {} and nothing else,
|
||||||
|
|||||||
Reference in new issue
Block a user