diff --git a/agents/webby/work/queue-217/EARLY-LOOK-c25f5b8da.md b/agents/webby/work/queue-217/EARLY-LOOK-c25f5b8da.md new file mode 100644 index 000000000..c6d5722e0 --- /dev/null +++ b/agents/webby/work/queue-217/EARLY-LOOK-c25f5b8da.md @@ -0,0 +1,88 @@ +# Row 217 early look: C2-06 citation guard, page store, runner texts and the retry + +Webby, 2026-10-23. Request: beakley-0008 (c25f5b8da). This is a static draft read, as Beakley +asked. It isn't a verdict, and I ran nothing. + +- Branch: beakley/row217 at c25f5b8da, carried on from Launchpad's e25ef0373. Base 45dca69f6. +- 28 files, +1486/-24. Seven test files are new, and no existing test line changes. +- Brief: docs/plans/2026-10-20_case2-rows.md, "C2-06 the citation guard, the page store, the + runner texts and the retry" (blob 3a5ed91a4). + +## Checked, nothing blocking + +- The page store outlives the transport. server.mjs:36 `release()` disconnects only `boundCap`, + and :92 sets that only from a human, tester, user or console proof. An agent's cap is never + disconnected when a connection closes, so a `web.fetch` page is still there for the next + `message.send`. The broker drops pages in release-session and in `disconnect(cap)`, and the + page store test covers the replacement session. +- The guard runs outside the transaction and re-enters with the checked request. The snapshot + test shows a body changed after the call can't replace the checked one. The check event and + the message insert share one transaction, and the trigger test shows a failed evidence insert + leaves `messages` at 0. M3 targets that. +- The transport passes `reason` only when the error has one, and the client cuts it to 300. The + unknown-verb envelope is byte-identical, `{"ok":false,"error":"unknown-verb"}`. +- A non-library business keeps role.claim's old shape and unguarded sends. +- The guard table: all seven codes refuse through `message.send` and through the runner's RESULT + path, each with one retry, and `messages` stays the same. The typed `send_message` tool runs all + seven before a valid RESULT. 20 citations pass and 21 refuse at the default. +- Settings: every invalid value in the brief's list falls back alone in limits.mjs, inherited + keys are ignored, and an unreadable or non-object file turns `requireCitation` on. The bus test + changes the file in both directions with no restart. With the file unreadable, 21 citations + and an uncited reply refuse, and the four fixed texts pass. +- The runner: one retry per answer for a guard refusal, a request-too-large or a mix of the two. + The fallback text matches the second refusal. Fixed texts carry no note, and the note goes on + the next cited reply. Cited JSON over 32,000 characters isn't cut. Outside a library business, + the old failed text, clip, note and no-retry behaviour hold. +- The supporting scope is stubbed until 283 lands, per sage-3595 (BUILD.md:19). I'll check the + real-fixture tests after the rebase. +- The obsolete-code grep hits only row 225's files, as BUILD.md says. + +## Early items for the manifest round + +- E1 (would block). M2 survives every case in reply-limits.test.mjs. M2 swaps `old.human` for + `document.human` at organization.mjs:90. Each refused case is still refused under the swap: + - 'tester' fails `actor !== "tester"`. + - 'chief-of-staff.chief' and 'coder.coder' fail `!agents.includes(actor)`. The fixture's + `chief` role is `chief-of-staff.chief` (business/tests/helpers.mjs:73). + - The human-swap case changes `human` to 'chief-of-staff.chief', which the agent clause + refuses before the human comparison matters. + + Only an actor that is neither the tester nor any role's `.` tells the + two apart. For example, actor `mallory` changes `human` to `mallory` and changes + `replyLimits`. That case kills M2, and it's the brief's "changes both human, to its own actor, + and replyLimits" case with an actor the other clauses don't catch. +- E2 (would block). The brief asks that "the stored check result names ... the agent-written + flag for a fixture file whose last commit has the trailer." guard.test.mjs:95 pins + `reader.origin` directly. Every stored check in citation-guard.test.mjs has `agent: null`. + A bus test that commits the cited file with `Mosaic-Agent: acme/scribe`, sends a cite of it + and reads the `message.checked` event for `agent: 'acme/scribe'` would cover it. The + supporting half waits for 283, as sage-3595 rules. +- E3. The brief names "the chief of staff's `organization.set`" and "the tester's + `instances.set`". No verb is named `organization.set` (no hit in packages/*/src), and + `instances.set` writes one instance, so its args can't carry `replyLimits`. The business tests + call `writer.write` directly with the chief and tester actors, which reaches the same fence. + That's a reasonable substitute, but BUILD.md should say so, and Sage should rule on it, since + the brief's list is the gate. +- E4. guard.mjs:176 reads served through `readSyncState`, which takes the library lock with a + 5 s wait. Any error leaves served null (:177), and then every library cite refuses + `citation-invalid` with "isn't an indexed file at a commit reachable from the served commit". + A sync, or row 288's write holding the lock through a network push, can make a valid cite + refuse with that reason. The runner then spends its one retry on it. A lock-free read of the + served ref, or a distinct reason for "served unreadable", would fix it. That isn't a safety + hole (it fails closed), but the reason misleads the agent. +- E5. `#libraryProject` takes the first library project in file order. A cite into a second + library project refuses. If one library project per business is the rule, a line in BUILD.md + should say so. +- E6. The guard table runs with a `coder` sender throughout. The brief reads as creative senders + for the table plus "once with a non-creative sender". `#guarded` doesn't look at the + definition, so the result is the same, but one `research` run of `guardCases` would match the + brief's wording. +- E7. The settings tests use the fixture's own `limits` function. Runtime's `replyLimits` through + `organizationWriter.readRaw` is wired (sage-3595 approved it) but only the + `library.limits.set` test reaches `readRaw`, with a replaced adapter. A runtime-level case with + the business file made unreadable would pin the wiring. + +## Gate left to Sage + +Per the brief: the library, bus, business, cli and harness suites green, every scripts/test-*.sh +on CLEAR, M1-M4 killed, and the obsolete-code grep. Nothing above has been run. diff --git a/docs/SESSIONS.md b/docs/SESSIONS.md index dfc9d06ee..365c0de62 100644 --- a/docs/SESSIONS.md +++ b/docs/SESSIONS.md @@ -1531,3 +1531,4 @@ are never rewritten or removed; corrections are new entries. 2026-10-23T19:17Z | Webby (Opus 5.5, reviewer seat) | row 198 r4 B1 scope correction on 4d8123b0a | B1 is six test files (browser, return-flow, history-return-flow, discord, board-held besides browser-edge); canReply/seen gating owned by 198 2026-10-23T19:26Z | Webby (Opus 5.5, reviewer seat) | row 288 early static look on c867cada9 and 7dc4fb2cc (bubba-0005, bubba-0008) | nothing blocking; E1-E5 for the manifest round; nothing run 2026-10-23T19:30Z | Webby (Opus 5.5, reviewer seat) | row 283 46bad7ea3 delta (honker-0191); row 288 E6 editor.user | 283 clean, nothing open; 288 E6 to Bubba; nothing run +2026-10-23T19:34Z | Webby (Opus 5.5, reviewer seat) | row 217 early look on beakley/row217 c25f5b8da (static, draft) | E1 M2 survives (no non-agent actor case), E2 stored agent flag untested, E3-E7 notes; nothing run