67 lines
4.0 KiB
Markdown
67 lines
4.0 KiB
Markdown
# Row 300 build notes (Launchpad): R6-N1, an HTTP-level test of the user-session option swap (#1807)
|
|
|
|
Brief: docs/plans/2026-10-23_r6-followup-rows.md § Brief: R6-N1. Reviewer Duckworth, gate owner Sage.
|
|
Base c13c337e1 (refactor, after row 294 landed at d3059c2c3). Branch launchpad/row300.
|
|
|
|
## Change
|
|
|
|
Tests only. One new file, packages/webui/tests/user-option-swap.test.mjs. No product change and no
|
|
existing assertion or fixture touched.
|
|
|
|
- **Gate stubbed open.** The file registers an in-thread load hook (`registerHooks`, as
|
|
thread-claims.test and library-cli.test do through `--import`) keyed on the one URL
|
|
`serve.mjs?gate=open`. On that URL alone it prepends `return true;` to `userRoute`'s body, then
|
|
imports `startServer` from it. Every other import of serve.mjs, and every relative import inside
|
|
the copy, is the real module. If the gate's signature line is not in serve.mjs exactly once, the
|
|
hook throws. A renamed gate then fails loudly, instead of quietly testing the closed gate. The
|
|
test also asserts that the copy's `userRoute` answers true for `POST /api/bus/message`.
|
|
- **Setup.** This is granted-user.test.mjs's setup, cut to what the test needs: the fake OP, the
|
|
in-process broker for `demo`, createSso with the access hook, and `userOptionsFor` over alice's
|
|
transport. Every owner option is a stub that records its own name. The owner transport records
|
|
`['transport', verb, args]`. One list, `owner`, holds both kinds of owner call.
|
|
- **Positive control.** The owner signs in and posts `/api/bus/message`. Exactly
|
|
`['option', 'send']` must be recorded, so the route reaches `send` and the count works.
|
|
- **The check.** Alice signs in and walks G4's owner routes, copied, plus two chat reads. No answer
|
|
may say `owner-only`, so the gate really is open. After each route, every owner record must be
|
|
`['transport', 'plugins', {}]`, the read mos-1394 allowed. The message route must reach the user
|
|
transport (`message.send`), and every transport opened is alice's.
|
|
|
|
Why a new file: granted-user.test.mjs's setup imports startServer statically. Passing the gate-open
|
|
copy into it would change that fixture, and a fixture change goes to Mos. The route list and setup
|
|
are copied, with a comment naming their source.
|
|
|
|
## Mutant
|
|
|
|
M12: serve.mjs:689 drops `send` from the user-session destructure, so a user session keeps the
|
|
owner's `send`. Killed when "R6-N1" reports not ok. Expected failure: on `POST /api/bus/message`,
|
|
the owner record holds `['option', 'send']`. run1/mutants.py applies it (anchor exactly once), runs
|
|
the new file alone, restores with git checkout and checks the tree is clean.
|
|
|
|
## Gate
|
|
|
|
Duckworth approves the manifest. On Sage's CLEAR: run1/gate.sh does npm ci (root and webui), the new
|
|
file whole, the webui suite whole, then M12. Logs go to /mnt/storage/scratch/launchpad-r300/run1,
|
|
outside the tree. Not run yet.
|
|
|
|
MANIFEST.sha256 lists the one new path.
|
|
|
|
## Run 1 (sage-3408 CLEAR, 12:05Z)
|
|
|
|
npm ci root and webui were green. The new file was red on its first run (mos-1272, placed by me):
|
|
`TypeError: Cannot read properties of undefined (reading 'set-cookie')` in signIn. When I cut down
|
|
granted-user.test.mjs's `call`, I dropped `headers: res.headers` from what it resolves, so the
|
|
sign-in found no cookies. The fix puts `headers` back, the same as granted-user.test.mjs:40. No
|
|
assertion changed. The new file then passed alone (1/0). The fix is a new commit, and the manifest
|
|
is re-hashed. The gate resumes at new-file on the new head.
|
|
|
|
Run 1 resumed (TAG -r2) on db5122920, manifest db8be52ce895603e687985acfae29e53e3e8782ae945c3cded6cca36141bfa3b:
|
|
|
|
- new file whole: 1 pass, 0 fail.
|
|
- webui suite whole: 375 pass, 0 fail, 0 skipped, 0 cancelled, 58.2 s (limit 600).
|
|
- M12 killed. "R6-N1" reports not ok at :151: `POST /api/bus/message: ["option","send"]`, where
|
|
`["transport","plugins",{}]` is expected. The restore left the tree clean.
|
|
|
|
Duckworth N1 (duckworth-0263, non-blocking): the setup passes no `upstream`, so the swap's
|
|
`upstream = null` has no recorder here. The test proves the swap for the options it stubs. It
|
|
proves nothing about `upstream`.
|