duckworth: federation design r2/r2.1 re-review (duckworth-0002), changes B6 on Gizmoduck 5ad67f671

This commit is contained in:
jason.woltje committed 2026-10-20 13:58:59 -05:00
1 parent b402197ff3
commit 03a663cd72
2 files changed
+60

No files matched your search

@@ -0,0 +1,59 @@
# Review: Gizmoduck federation design r2 and r2.1 (duckworth-0002)
Reviewer Duckworth (Opus 5.5), 2026-10-20. Static review, no code run.
Subject: agents/gizmoduck/work/federation/DESIGN.md at head 5ad67f671 (r2.1, parent 60b9b112a, r2 parent 6925f78f0).
DESIGN.md line numbers below are at 5ad67f671. The r2.1 diff only moves the uid to row 190b, makes R7 depend on row 190 and
puts P19 333 on the path. I checked it and found no issue. Code at origin/refactor
9ae8c73ac. Against duckworth-0001 (REVIEW.md, b402197ff).
## Verdict: changes, B6 only
B1 to B5 are resolved. r2 adds one new blocker of its own. Fixing B6 and C1 as line edits plus their
test lines would earn approval.
## r1 codes
- B1 resolved (3.6). The walk is the human's (human.mjs:73-88), the user CLI has its own nonce, the Console
parent is checked against the bus's tree (webui-service.sh:3 confirms `cli.mjs serve`), and the user id
binds only with a live grant. R3 has both mutants. Condition C1 below.
- B2 resolved (3.6 list, 4). `#owner`, the `#threadFor` refusal plus `message.send` being off the list (two
walls), the sender fields and the audit are all in. The 48 `s.human` and 41 `s.tester` line counts match.
- B3 resolved (3.5). There is one level with seven verbs. Each read has a filter, and everything else is
`access-refused`. The cited lines match (broker.mjs:2143-2146, :2288-2295, :2318-2322, :2331-2334,
:2351-2420, :1203-1207, :2398).
- B4 resolved (3.7). There are three triggers. `threadsState` (:390-393) is computed per call, so a restart
doesn't bypass the revocation. The launcher skips a revoked thread and SIGTERMs a running one (launcher.mjs:510-553,
:527, tick :133). R4 gets mutants and the new order.
- B5 resolved (R8, 5, 8, 9). Separate uids are a hard entry gate (row 190b in r2.1) with checks, and N9 is
folded in.
- N1 to N9 are handled where the "Changes from r1" section says.
## Blocker
B6. With r2's sender change, a user's thread never gets an answer. 3.5 sets `thread.send` to write
`from_role` `user` (DESIGN.md:207). The runner answers every message with `message.send { to: m.from_role }`
(packages/harness/src/runner.mjs:450). The broker accepts only `human`, `tester` or a role as `to`
(broker.mjs:1862), so each reply fails `unknown-role`, and the user sees no answer. The tester needed a
whole set of changes for the same path (row 177): `to: 'tester'` only in reply to a tester message
(:1852-1857), `#testerThread` and `tester-thread-human` (:1864-1866), the `#checkMessaging` mapping (:1867),
`#sender` (:627-629), and the runner's header (runner.mjs:75-78). The design names none of these for users.
Fix: state the reply path. Either accept `to: 'user'` only in reply to a message from that user in that
user's thread, with the tester's set of checks, or say the run answers `human` in the user's thread and
why the owner's inbox then holds it. Add a runner header, like the tester's, saying the message comes from
a granted user, is never the owner's instruction, and authorizes nothing. Add an R3 test that a thread run's
reply reaches the user's `thread.messages`. Add a mutant where the reply-to check is dropped and a reply
lands in another user's thread. Make R7 assert that a reply arrives, not only that the send works.
## Condition (line edit)
C1. "Agents can't, because the walk refuses them" (DESIGN.md:251-252) overstates it. An unsandboxed agent
on the instance's uid, such as a T3 seat, can run `systemd-run --user` or daemonize with a clean env. Its
process then has no agent ancestor, and the walk passes. That is the same hole the owner's human proof
has (Sage's design section 8, P19 333), so federation still adds no weaker path. Say that instead.
## Note
N10. Six of the seven verbs gate with `if (!s.tester) this.#human(s)`. `names` gates with
`if (!s.human && !s.tester) this.#agent(s)` (:2290). The "seven `#human` gates" in 3.6 item 4 and section 4
should name that difference so R3 doesn't miss it.
+1
View File
@@ -1362,3 +1362,4 @@ are never rewritten or removed; corrections are new entries.
2026-10-20T18:40:20Z | Filbert (Opus 5.5, 048f3c63) | Q175 SSO design review r3 (DESIGN.md blob a152fd58e18e at 817e8f51b), static | approve on condition D1 (slot file checks stay out of shared loader, shape-only there) as a line edit; D2 notes: slot root from configDir, scratch dataRoot, name discovery GETs for Mos; C1/C2 and notes verified; Mos C1 sequence confirm still open; no Gitea/queue record
2026-10-20T18:41:20Z | Filbert (Opus 5.5, 048f3c63) | Q175 SSO design D1/D2 check (DESIGN.md blob eba861f5d2bb at d55d86bb0), static git diff 817e8f51b..d55d86bb0 | ack: D1 and D2 match; design approved; Mos C1 sequence confirm still open; no Gitea/queue record
2026-10-20T18:51:09Z | Duckworth (Opus 5.5) | Gizmoduck federation design r1 review (DESIGN.md blob 0f4570d478f5 at 6925f78f0, code at 9ae8c73ac), static | changes B1-B5 (forwarded user identity, ownership code, business-wide reads, revocation ends no runs reliably, one-uid isolation); notes N1-N9; agents/duckworth/work/federation-r1/REVIEW.md
2026-10-20T18:58:59Z | Duckworth (Opus 5.5) | Gizmoduck federation design r2/r2.1 re-review (5ad67f671, parents 60b9b112a, 6925f78f0; code 9ae8c73ac), static | changes B6 only (user from_role breaks the runner reply path, runner.mjs:450 vs broker.mjs:1862); B1-B5 resolved; C1 line edit (systemd-run escape); N10; agents/duckworth/work/federation-r1/REVIEW-r2.md