diff --git a/agents/quackerjack/work/queue-296/BUILD.md b/agents/quackerjack/work/queue-296/BUILD.md new file mode 100644 index 000000000..af952d455 --- /dev/null +++ b/agents/quackerjack/work/queue-296/BUILD.md @@ -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--); 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.