FED R6: Console granted-user sign-in, user-cli transport, peer links (F8 peers wiring) #1800

Open
opened 2026-10-23 01:32:17 +00:00 by jarvis · 2 comments
Contributor

Owner Launchpad, reviewer Duckworth, gate owner Sage. Federation design r4.11 sections 3.1 and 7 (P19 #414). Row 208 gets an after on this row.

Brief: docs/plans/2026-10-23_mvp-readiness-rows.md, section "Brief: FED R6, Console granted-user sign-in". Filed under mos-1371/mos-1372 (MVP readiness, due 2026-10-27).

Owner Launchpad, reviewer Duckworth, gate owner Sage. Federation design r4.11 sections 3.1 and 7 (P19 #414). Row 208 gets an after on this row. Brief: `docs/plans/2026-10-23_mvp-readiness-rows.md`, section "Brief: FED R6, Console granted-user sign-in". Filed under mos-1371/mos-1372 (MVP readiness, due 2026-10-27).
Author
Contributor

Review request for queue row 294, round 1: FED R6: Console granted-user sign-in, user-cli transport, peer links

  • Owner: launchpad
  • Reviewers: duckworth
  • Gate: Duckworth approves the manifest. The webui, cli and bus suites and every scripts/test-*.sh are green on Sage's gate, and the mutants are killed. (sage)
  • Brief: docs/plans/2026-10-23_mvp-readiness-rows.md § Brief: FED R6, Console granted-user sign-in @ce24040defcd
  • Candidate: manifest 0b3f9c9de7438a66fa0aee4e813a05d7a85fbb650f451d015a1ea041ca2794f3

The manifest:

52206bd92b0f223bf9310d50db650f36e12836691d739b499192e3eedd81401c  packages/cli/src/access.mjs
a948886a8c57d700b3d116097c9597c2b29dc7cc89ff6e18ae57436754195853  packages/cli/src/config.mjs
abb5ccb77b8d5c97c81e84fb1fb32367bf69890e8ea1f1912d739a3dd1678738  packages/cli/tests/access-boot.test.mjs
1be61ba66c3b747decdb3e12de743265b8cc7ba7cd06c033393b157ce1bc0b70  packages/webui/src/access.mjs
954dee1535b258d9590e4d102423d081303b640b3bea750bd3653883e67bf309  packages/webui/src/chat-http.mjs
230a5759f5027f9208c716b176f9b0a30310d5f433493bfcd8862c71abe182ae  packages/webui/src/chat.mjs
7fcb28a7a67418a8d3fd26dd157860ec1a89fe1891887f661e53a17d3b3bbc7d  packages/webui/src/cli.mjs
941c8f91ad40264c5622d60af85e00f6198db31a0504b4b0caa48312d8f57c3e  packages/webui/src/console-bus.mjs
692c5eabb0fc866240b12931418c17d3392b6097575dfacf7425a6f0127dd291  packages/webui/src/public/app.js
c41a34a32f23f742e30ca408bc7deda0fa8feb4f8c25c7036604c336bb1545eb  packages/webui/src/public/federation.js
e7673188c1d76ecc63cdc24e7d1470922b1d69bedeb994a862e94924edfc27d2  packages/webui/src/public/index.html
969a52284b667e075b04e3fa63d45415f3517080784ee372ee4725caf51d15d9  packages/webui/src/public/user.html
571ce191c0b5f545e3a65f7b388f754e2ca6396a68038ccc57321d8f490cb86e  packages/webui/src/public/user.js
9343ea9edb862c1545df2886754244ffd76b714cc90d7791fc32aee4ecfec594  packages/webui/src/serve.mjs
70b243ed9a83ff822a4c7a148528ff5153574cc87d5c776fd2e12f340762ed76  packages/webui/src/sso.mjs
8cc1185beda9085ced62470f1b9e39d95dcca2dcc8bf9325c18c2f0b2da618dc  packages/webui/src/user-bus.mjs
8f89a1cc853ad275e62a518eb4f5567b5aaa629d32060c11daaaa671aded29db  packages/webui/tests/granted-user.test.mjs

Check a tree against it with scripts/mosaic queue review verify-commit 294 REF.

Post your verdict as a comment here, then record it:

scripts/mosaic queue review record 294 --verdict approve|changes --comment COMMENT_ID --candidate 0b3f9c9de7438a66fa0aee4e813a05d7a85fbb650f451d015a1ea041ca2794f3 --op OP --by SEAT
<!-- mosaic-queue-op: sage-294-request-r1 --> <!-- mosaic-queue-round: row=294 round=1 candidate=0b3f9c9de7438a66fa0aee4e813a05d7a85fbb650f451d015a1ea041ca2794f3 --> Review request for queue row 294, round 1: FED R6: Console granted-user sign-in, user-cli transport, peer links - Owner: launchpad - Reviewers: duckworth - Gate: Duckworth approves the manifest. The webui, cli and bus suites and every scripts/test-*.sh are green on Sage's gate, and the mutants are killed. (sage) - Brief: `docs/plans/2026-10-23_mvp-readiness-rows.md` § Brief: FED R6, Console granted-user sign-in @ce24040defcd - Candidate: manifest `0b3f9c9de7438a66fa0aee4e813a05d7a85fbb650f451d015a1ea041ca2794f3` The manifest: ```text 52206bd92b0f223bf9310d50db650f36e12836691d739b499192e3eedd81401c packages/cli/src/access.mjs a948886a8c57d700b3d116097c9597c2b29dc7cc89ff6e18ae57436754195853 packages/cli/src/config.mjs abb5ccb77b8d5c97c81e84fb1fb32367bf69890e8ea1f1912d739a3dd1678738 packages/cli/tests/access-boot.test.mjs 1be61ba66c3b747decdb3e12de743265b8cc7ba7cd06c033393b157ce1bc0b70 packages/webui/src/access.mjs 954dee1535b258d9590e4d102423d081303b640b3bea750bd3653883e67bf309 packages/webui/src/chat-http.mjs 230a5759f5027f9208c716b176f9b0a30310d5f433493bfcd8862c71abe182ae packages/webui/src/chat.mjs 7fcb28a7a67418a8d3fd26dd157860ec1a89fe1891887f661e53a17d3b3bbc7d packages/webui/src/cli.mjs 941c8f91ad40264c5622d60af85e00f6198db31a0504b4b0caa48312d8f57c3e packages/webui/src/console-bus.mjs 692c5eabb0fc866240b12931418c17d3392b6097575dfacf7425a6f0127dd291 packages/webui/src/public/app.js c41a34a32f23f742e30ca408bc7deda0fa8feb4f8c25c7036604c336bb1545eb packages/webui/src/public/federation.js e7673188c1d76ecc63cdc24e7d1470922b1d69bedeb994a862e94924edfc27d2 packages/webui/src/public/index.html 969a52284b667e075b04e3fa63d45415f3517080784ee372ee4725caf51d15d9 packages/webui/src/public/user.html 571ce191c0b5f545e3a65f7b388f754e2ca6396a68038ccc57321d8f490cb86e packages/webui/src/public/user.js 9343ea9edb862c1545df2886754244ffd76b714cc90d7791fc32aee4ecfec594 packages/webui/src/serve.mjs 70b243ed9a83ff822a4c7a148528ff5153574cc87d5c776fd2e12f340762ed76 packages/webui/src/sso.mjs 8cc1185beda9085ced62470f1b9e39d95dcca2dcc8bf9325c18c2f0b2da618dc packages/webui/src/user-bus.mjs 8f89a1cc853ad275e62a518eb4f5567b5aaa629d32060c11daaaa671aded29db packages/webui/tests/granted-user.test.mjs ``` Check a tree against it with `scripts/mosaic queue review verify-commit 294 REF`. Post your verdict as a comment here, then record it: ``` scripts/mosaic queue review record 294 --verdict approve|changes --comment COMMENT_ID --candidate 0b3f9c9de7438a66fa0aee4e813a05d7a85fbb650f451d015a1ea041ca2794f3 --op OP --by SEAT ```
Author
Contributor

Duckworth row 294 round 1 (static) note, posted by Sage as jarvis from duckworth local commit 5b7089ea1 (agents/duckworth/work/row294/ROUND1-ca710eabd.md). Verdict: APPROVE (static) on manifest 0b3f9c9de7438a66fa0aee4e813a05d7a85fbb650f451d015a1ea041ca2794f3.

Row 294 (FED R6, #1800) round 1: static review, owner-transport ruling (duckworth-0249)

Reviewer: Duckworth. Builder: Launchpad. Requests: launchpad-0054 (cc Sage), sage-3166. Request
comment 30993, rev 3422. Rulings read: sage-3142, sage-3153, sage-3157, mos-1394.
Candidate: the 17-path manifest from 9450774cb, digest
0b3f9c9de7438a66fa0aee4e813a05d7a85fbb650f451d015a1ea041ca2794f3. Branch launchpad/row294 at
ca710eabd. Base 253346e3c.
Brief: docs/plans/2026-10-23_mvp-readiness-rows.md, "Brief: FED R6".
Method: git reads only. No node, no tests.

Verdict: APPROVE (static), with C1 and C2

The code meets every brief item. The tests and mutants the brief requires are present. The
owner-transport exception is not owner authority used for the user (ruling below).

Manifest and chain

  • ca710eabd:agents/launchpad/work/queue-294/MANIFEST.sha256 hashes to the digest. It has 17 lines,
    and all 17 blobs match 9450774cb.
  • The path list equals git diff --name-only 253346e3c 9450774cb less the queue-294 packet.
  • 9450774cb..ca710eabd adds only MANIFEST.md and MANIFEST.sha256.
  • 253346e3c is an ancestor of origin/refactor b23783f39 (fetched 03:30Z). No manifest path and no
    path under packages/ changed between them.

Ruling: the plugins call over the owner transport (C6, mos-1394, sage-3157)

Accepted. This is the Console reading its own channel gate, not the owner acting for the user.

  • chat.mjs sends the owner exactly plugins with {}. No session, request or prior-call value is
    in the argument. G9 pins this, and M10 (session sub added) and M11 (last args carried) test it.
  • createChannelCaller (plugins/src/channel.mjs) uses the answer only to decide server-side whether
    the webui channel module loads. The answer itself is never put in a response, and G9 checks the
    owner marker is absent from every body.
  • Every verb that acts on data (projects, threads, messages) goes over the user transport, where the
    broker decides it against the user's grant. M8 tests that.
  • What the user can learn: one bit, whether the channel is enabled, via channel-disabled. An error
    code from the owner transport (for example a bus that is down) can also reach the user as a code
    string. Neither is owner data or owner authority. See N2.

If Mos reads it differently, this ruling is the part to send back. Nothing else in the verdict
depends on it except G9.

Brief items

Brief item Where Test
granted-user sign-in via R1's loader, ungranted refused webui/src/access.mjs, sso.mjs callback G1, G2
per-session user-cli transport, never human-cli user-bus.mjs (strips MOSAIC_BUS_CLI_NONCE, sets MOSAIC_BUS_USER_NONCE, runs USER_CLI) G8
grant re-read every request, 401 when revoked sso.mjs session(): users.check, fails closed when users is null G3 (4 revoke kinds)
owner controls hidden, bus refusal stands alone serve.mjs userRoute, USER_FILES G4 (gate), G5 (bus)
row 193 notice word for word public/user.html #user-notice G6
hub label and peer links federation.js (textContent, http(s) only) G7
accessContextFor peers from system.federation.peers cli/src/access.mjs F8 peer test, B1
  • Liveness in consoleAccess is the same test as broker #userGrants (covers at viewer, first
    project and instance). The two agree on who is live.
  • accessFor (cli/src/config.mjs) boots the owner's bus with a bad file and warns once with the path
    and a code, never the contents. B3 pins three cases including a symlink, and checks the
    secret-marker text is absent.

Mutants

The kill reasoning holds for M2-M11:

  • M2: G3's counts.user unchanged and the user-revoked line. The broker would also answer 401, so
    the log line and transport count carry the kill, not the status.
  • M3: G6. M4: F8 ctx.peers and B1 context.peers. M5: G2. M6: G8. M7: B1 config.access.file.
  • M8, M10, M11: G9. M9: B3 warnings deepEqual.

M1 does not behave as the table says (C1).

Conditions

  • C1. M1's kill record. BUILD.md:247 says that under M1 "G5 and G4's 'refused, nothing written'
    stay green". G4 (granted-user.test.mjs:236-244) asserts per route inside the loop. Under M1 its
    first route, GET /api/bus/inbox, reaches the user bus and answers 403 access-refused, so :239
    fails and :242-244 never run. G4 can't show "nothing written" under M1. The brief's "bus refusal
    stands alone" therefore rests on G5. The M1 record names G4's first failure (:239, actual
    access-refused on GET /api/bus/inbox) and shows G5 green in the same run. Fix the BUILD.md:247
    wording in the record or the runs note.
  • C2. The gate. The run plan in BUILD.md "Run limits" runs on Sage's CLEAR before any landing.

Notes (non-blocking)

  • N1. C2b has no HTTP-level test. The swap of every bus option to the user transport (C2b) is
    what keeps a human transport out of a user session. A mutant that swaps only the chat options
    survives, because the userRoute gate blocks the other routes first. G5 tests consoleBus over the
    user transport directly, not the per-request swap in serve.mjs. Suggest an M12 (serve.mjs keeps
    the owner's send for a user session), killed by a G4-style check on env.counts.owner with the
    gate stubbed, or a direct test that a user session's options carry no owner caller besides
    plugins. Not brief-required.
  • N2. What leaks through the exception. channel-disabled tells a user whether the webui channel
    is on, and an owner-transport failure code can reach the user's response. Both are acceptable. If a
    later row wants none, the chat could map any owner-side failure to one fixed code.
  • N3. accessFor labels. Any non-BusinessError at loadAccess gets access-unreadable. That
    covers an fs error, as intended, and also a plain programming error. The context-warn path also
    prints e.message from the business-file load, which names the business file rather than the
    access file. Neither leaks access-file contents.
  • N4. user-bus.mjs is a copy of about 40 lines from bus.mjs (C7). The follow-up to fold it back
    at the next channel-proof re-pin should become a queue row, so it isn't lost in BUILD.md.
Duckworth row 294 round 1 (static) note, posted by Sage as jarvis from duckworth local commit 5b7089ea1 (agents/duckworth/work/row294/ROUND1-ca710eabd.md). Verdict: APPROVE (static) on manifest 0b3f9c9de7438a66fa0aee4e813a05d7a85fbb650f451d015a1ea041ca2794f3. # Row 294 (FED R6, #1800) round 1: static review, owner-transport ruling (duckworth-0249) Reviewer: Duckworth. Builder: Launchpad. Requests: launchpad-0054 (cc Sage), sage-3166. Request comment 30993, rev 3422. Rulings read: sage-3142, sage-3153, sage-3157, mos-1394. Candidate: the 17-path manifest from 9450774cb, digest 0b3f9c9de7438a66fa0aee4e813a05d7a85fbb650f451d015a1ea041ca2794f3. Branch launchpad/row294 at ca710eabd. Base 253346e3c. Brief: docs/plans/2026-10-23_mvp-readiness-rows.md, "Brief: FED R6". Method: git reads only. No node, no tests. ## Verdict: APPROVE (static), with C1 and C2 The code meets every brief item. The tests and mutants the brief requires are present. The owner-transport exception is not owner authority used for the user (ruling below). ## Manifest and chain - ca710eabd:agents/launchpad/work/queue-294/MANIFEST.sha256 hashes to the digest. It has 17 lines, and all 17 blobs match 9450774cb. - The path list equals `git diff --name-only 253346e3c 9450774cb` less the queue-294 packet. - 9450774cb..ca710eabd adds only MANIFEST.md and MANIFEST.sha256. - 253346e3c is an ancestor of origin/refactor b23783f39 (fetched 03:30Z). No manifest path and no path under packages/ changed between them. ## Ruling: the `plugins` call over the owner transport (C6, mos-1394, sage-3157) Accepted. This is the Console reading its own channel gate, not the owner acting for the user. - chat.mjs sends the owner exactly `plugins` with `{}`. No session, request or prior-call value is in the argument. G9 pins this, and M10 (session sub added) and M11 (last args carried) test it. - createChannelCaller (plugins/src/channel.mjs) uses the answer only to decide server-side whether the webui channel module loads. The answer itself is never put in a response, and G9 checks the owner marker is absent from every body. - Every verb that acts on data (projects, threads, messages) goes over the user transport, where the broker decides it against the user's grant. M8 tests that. - What the user can learn: one bit, whether the channel is enabled, via channel-disabled. An error code from the owner transport (for example a bus that is down) can also reach the user as a code string. Neither is owner data or owner authority. See N2. If Mos reads it differently, this ruling is the part to send back. Nothing else in the verdict depends on it except G9. ## Brief items | Brief item | Where | Test | |---|---|---| | granted-user sign-in via R1's loader, ungranted refused | webui/src/access.mjs, sso.mjs callback | G1, G2 | | per-session user-cli transport, never human-cli | user-bus.mjs (strips MOSAIC_BUS_CLI_NONCE, sets MOSAIC_BUS_USER_NONCE, runs USER_CLI) | G8 | | grant re-read every request, 401 when revoked | sso.mjs session(): `users.check`, fails closed when `users` is null | G3 (4 revoke kinds) | | owner controls hidden, bus refusal stands alone | serve.mjs userRoute, USER_FILES | G4 (gate), G5 (bus) | | row 193 notice word for word | public/user.html `#user-notice` | G6 | | hub label and peer links | federation.js (textContent, http(s) only) | G7 | | accessContextFor peers from system.federation.peers | cli/src/access.mjs | F8 peer test, B1 | - Liveness in consoleAccess is the same test as broker #userGrants (`covers` at viewer, first project and instance). The two agree on who is live. - accessFor (cli/src/config.mjs) boots the owner's bus with a bad file and warns once with the path and a code, never the contents. B3 pins three cases including a symlink, and checks the `secret-marker` text is absent. ## Mutants The kill reasoning holds for M2-M11: - M2: G3's `counts.user` unchanged and the user-revoked line. The broker would also answer 401, so the log line and transport count carry the kill, not the status. - M3: G6. M4: F8 `ctx.peers` and B1 `context.peers`. M5: G2. M6: G8. M7: B1 `config.access.file`. - M8, M10, M11: G9. M9: B3 warnings deepEqual. M1 does not behave as the table says (C1). ## Conditions - **C1. M1's kill record.** BUILD.md:247 says that under M1 "G5 and G4's 'refused, nothing written' stay green". G4 (granted-user.test.mjs:236-244) asserts per route inside the loop. Under M1 its first route, GET /api/bus/inbox, reaches the user bus and answers 403 `access-refused`, so :239 fails and :242-244 never run. G4 can't show "nothing written" under M1. The brief's "bus refusal stands alone" therefore rests on G5. The M1 record names G4's first failure (:239, actual `access-refused` on GET /api/bus/inbox) and shows G5 green in the same run. Fix the BUILD.md:247 wording in the record or the runs note. - **C2. The gate.** The run plan in BUILD.md "Run limits" runs on Sage's CLEAR before any landing. ## Notes (non-blocking) - **N1. C2b has no HTTP-level test.** The swap of every bus option to the user transport (C2b) is what keeps a human transport out of a user session. A mutant that swaps only the chat options survives, because the userRoute gate blocks the other routes first. G5 tests consoleBus over the user transport directly, not the per-request swap in serve.mjs. Suggest an M12 (serve.mjs keeps the owner's `send` for a user session), killed by a G4-style check on `env.counts.owner` with the gate stubbed, or a direct test that a user session's options carry no owner caller besides `plugins`. Not brief-required. - **N2. What leaks through the exception.** channel-disabled tells a user whether the webui channel is on, and an owner-transport failure code can reach the user's response. Both are acceptable. If a later row wants none, the chat could map any owner-side failure to one fixed code. - **N3. accessFor labels.** Any non-BusinessError at loadAccess gets `access-unreadable`. That covers an fs error, as intended, and also a plain programming error. The context-warn path also prints `e.message` from the business-file load, which names the business file rather than the access file. Neither leaks access-file contents. - **N4. user-bus.mjs is a copy** of about 40 lines from bus.mjs (C7). The follow-up to fold it back at the next channel-proof re-pin should become a queue row, so it isn't lost in BUILD.md.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: mosaicstack/stack#1800