Compare commits

...
Author SHA1 Message Date
jason.woltje c6ab9bdc95 row 296 handoff: FED R7 design notes to lena/row296 (mos-1503, Q245)
Quackerjack stops row 296 here. BUILD.md holds the verified reads, the proposed
harness design, the open decisions for Lena, and the R2 learning that R7 depends on.
No test or code changes in this commit.
2026-10-23 14:10:09 -05:00
@@ -0,0 +1,87 @@
# Row 296: FED R7, scratch two-instance acceptance (#1802)
## Start
- Started 2026-10-23 18:53:27Z, on Sage's sage-3583 (mos-1489).
- Base: origin/refactor 45dca69f6 (pinned; local copy used, no fetch: fetch runs the credential node script, which
is held during Darkwing's re-pin window).
- Branch: quackerjack/row296 in worktree quackerjack-fed-r5-row296.
- Brief: docs/plans/2026-10-23_mvp-readiness-rows.md at 45dca69f6, section "Brief: FED R7, scratch two-instance
acceptance" (line 77).
- Constraints from Sage: scratch roots only (mktemp -d under /mnt/storage/scratch/tmp), never ~/.mosaic-dev or
the live bus. No push, claim, queue write, node or test run until CLEAR.
## What the brief asks for (summary)
- One script test under scripts/ with its harness in packages/*/tests/, as row 190's tests are.
- Two configs, two data roots, two Consoles, one fake OP. Consoles start outside agent ancestry in a transient
user unit. They never use the live stack's units, ports or sockets. The script removes its units on exit (trap).
- Test (design section 7 R7 gate): Jason's test identity, granted collaborator on one hub project, signs in,
makes a thread, sends to the granted instance, gets the reply in the thread, is refused on another project and
on board reads, is revoked, is refused again, and the run ends. The factory shows nothing of the hub.
- Mutants: grant project list widened to `*`; revocation claim end skipped.
- Gate: Filbert approves the manifest; the script test and every scripts/test-*.sh green on Sage's gate; no unit,
port or socket of the script outlives the run. R8 (live window) stays row 209.
## Open reads before design
- R4 and R6 candidates (the brief says it builds on their combined candidate). Confirm what they expose: the
hub sign-in, grant and revocation paths, and the Console's board-read refusal.
- Row 190's test harness (several instances on one uid): how it starts units and cleans up.
- Transient user unit support on this host (systemd-run --user), and how the existing tests detect it.
## Status
- 18:53Z: worktree created, brief read. No code yet.
## Handoff 2026-10-23 19:10:09Z (Mos ruling Q245, mos-1503)
Row 296 moves to Lena (Codex seat, thread db27faca-85fb-4ca0-9fc7-78d740d3fa3a, branch lena/row296). Quackerjack
stops here: no builds, no claim, no queue writes. This design is the handoff; Lena continues it.
Base: 45dca69f6. R4 landed as 2efd127ce (ancestor of the base, checked with merge-base --is-ancestor). R6 landed as
d3059c2c3 (row 294). R7 is claimable once Darkwing's window ends (Sage, sage-3592).
What I verified by reading (not by running):
- packages/cli/src/access.mjs:65 reads `system.federation?.peers ?? []` (the R6 seam).
- packages/bus/src/user-cli.mjs exists at base (the user-cli transport).
- Row 190's tests (packages/cli/tests/stack-instances.test.mjs, stack-release.test.mjs T56, stack-release-fixture.mjs)
drive stand-in units and fixtures. They do not start real transient user units. Not a model for R7's Consoles.
- Real transient-unit launch pattern: packages/conversation/src/cohort.mjs (`scopeAvailable()` and `ScopeLauncher`,
systemd-run --user --scope -p Delegate=yes --unit=...; MANAGER_ENV = XDG_RUNTIME_DIR, DBUS_SESSION_BUS_ADDRESS).
- Test-only spawn of systemd-run in packages/conversation/tests is the nearest precedent for start/stop cleanup.
What I did NOT verify (so treat as open): the hub sign-in, grant, revocation and board-read paths in R4/R6 code; the
Console startup flags; whether the fake OP can be a local stand-in; the trap-based unit cleanup.
Design (proposal, not yet checked against code):
1. scripts/test-federation-acceptance.sh: the entry point. Creates a mktemp -d scratch root under
/mnt/storage/scratch/tmp (never ~/.mosaic-dev, never the live bus). trap removes every unit it started and the
scratch root. Refuses to run if a transient unit name collides.
2. Two configs (instance A = hub-side granted seat, instance B = collaborator's home), each with its own
MOSAIC_CONFIG, data root and federation.self; federation.peers names the other.
3. One fake OP: a local stand-in that issues Jason's test identity. Its port and socket are per-run, not the live ones.
4. Two Consoles, each in its own transient user unit (systemd-run --user --unit=mosaic-r7-<run>-<A|B>); outside agent
ancestry; ports picked per run.
5. Test flow (the R7 gate): identity -> grant on one hub project -> sign in -> thread -> send to granted instance ->
reply in thread -> refused on another project -> refused on board reads -> revoke -> refused after revoke -> run
ends. Factory output must show nothing of the hub.
6. Mutants: (a) grant project list widened to `*`, must fail the other-project refusal; (b) revocation claim end
skipped, must fail the refusal-after-revoke check.
Unresolved decisions for Lena (I did not decide these):
- Whether the harness lives in packages/cli/tests (matching row 190) or packages/conversation/tests (matching
cohort.mjs). Brief says packages/*/tests/; pick the one that owns the Console start path.
- Fake OP: in-process HTTP stand-in versus file-backed identity. No preference recorded.
- Port selection: fixed range per run vs OS-assigned. Brief forbids the live ports; it does not pick a range.
R2 and R5 learning:
- R2 (row 203, #1701) landed as a4da4e6df. I built it. Relevant to R7: validateFederation in
scripts/mosaic-config.mjs rejects unknown keys and bad ids, and test-config.sh has an FED block
(expect_fed_refusal). Use federation.self/peers exactly as row 203 validates them.
Mutant runner pattern: one textual edit that must occur exactly once, then a named test must fail; restore from git.
Name filter gotcha: `node --test --test-name-pattern` skips subtests whose parent does not match; include the
parent name (T57 for row 203).
- R5: I did not build R5 in this session and have no first-hand notes on it. Ask Sage for R5's landing sha and notes.
Status: design written; no code, no test runs, no claim, no push of the test files. Next owner: Lena.