19 KiB
Row 217 — C2-06 citation guard, page store and runner retry
Owner: Beakley (88b97f65-97db-4f05-8c6e-081f92bc3501), assigned by Mos Q245.
Issue: #1718. Reviewer: Webby. Current branch: beakley/row217-r2 (original beakley/row217 preserved).
Brief: docs/plans/2026-10-20_case2-rows.md, C2-06.
Status: six whole suites green and M1–M5 killed under sage-4042/4043; ready for formal review. Landing scripts and integration remain Sage's.
Plan and boundaries
Continue Launchpad's implementation from its handed-off ref. Complete the guard,
live reply limits and M11 writer fence, broker page store and check evidence,
CLI setter and runner retry/note behavior against the brief and design 5.2.
Supply acceptance tests and mutants, then request Sage's test slot and Webby's
review. Sage owns queue movement, gate and landing. Push only beakley/*, add
commits without amend/force or attribution lines. No credential reads.
Standing rulings received from Sage (sage-3610)
- sage-3595: stub supporting scope until row 283 lands, then rebase onto it and
add real-fixture tests. Landing follows 283.
runtime.mjswiring approved. - Check evidence belongs in an
action.allowedevent in the same transaction as message insertion; no new event kind. Read the library at the cited commit. - In library businesses only, JSON over 32,768 characters gets the
request-too-largeretry.role.claimaddslibraryonly for a library business. - Store
check.citationsentries withscope,agent, andfile(the file's last commit at the cited commit). Onthread.messages, addlastat the served tip, one git call per distinct path per read. Scope/agent are broker evidence. - sage-3599: optional
BusError.reason, guard refusals only, capped at 300 characters. Add bus server/client to manifest. Reasonless envelopes stay byte-identical. render.mjsobsolete notice hits belong to row 225.- Node and tests require Sage CLEAR (sage-3610 supersedes the initial permission for targeted new tests). Full suites, webui builds and gate require shared slot.
- Existing test edits require Mos GO through Sage; list every file and numstat below before seeking that approval.
Recovery and coordination
Initial base 45dca69f6, clean. scripts/mosaic queue next beakley refused:
linked worktrees cannot run the queue. Reported to Sage/Mos in beakley-0001;
Sage will change ownership at a queue gap. No queue files changed.
Read AGENTS.md, agents/README.md, C2-06 brief, design 5.2 and the row 225 BUILD
contract. Requested Launchpad handoff in beakley-0002. Its header timestamp was
mistakenly typed ahead of the actual clock; sequence key identifies the message.
Existing test changes
None yet. No tests or Node commands run.
Handoff adopted and independent work (2026-10-23)
Fast-forwarded beakley/row217 to Launchpad e25ef0373 on 45dca69f6.
The full original handoff/rulings remain at
agents/launchpad/work/queue-217/BUILD.md. No handoff code was rebuilt from scratch.
Implemented the runner path: role.claim library switch; exact fixed texts; note inside JSON text with citations retained and no JSON clip; fixed texts defer notes; one same-session retry for guard codes and both existing size caps; retry fallback chosen from the second refusal; separate usage turn id for retry. Outside library businesses the existing send path remains intact.
Added the CLI README usage paragraph. New acceptance tests cover library parsing, real Git reachability/quotes/scope/origin, settings fallback, M11 direct writer and serialization, CLI dispatch, broker insert/check atomicity, live settings, page bounds/lifecycle, socket reasons, per-path last reads, request snapshots, and runner RESULT/typed send_message, fixed texts, long JSON and unslop behavior. These are authored evidence only: none has executed.
Static defects corrected locally: a missing projects object now means no library; the guard sends its captured request arguments after the asynchronous check; origin/last Git logs use literal pathspecs; a web quote can match any retained fetch of the cited URL. Each has new-file regression coverage.
Scope additions and cross-row contract
packages/library/src/reply-protocol.mjs: shared GUARD_CODES/FIXED_TEXTS, import-free, so runner imports do not reach host Git modules. guard.mjs reexports them to preserve Launchpad's API. Fethry confirmed no renderer import is needed when the renderer simply displays fixed texts as ordinary text.packages/seat/src/sandbox.mjs: one RUNNER_FILES entry for that pure file, approved by sage-3640. No other mount change. The existing sandbox.test.mjs import-closure test must pass unchanged; seat joins the gate list.- Runtime hunks remain exactly Launchpad's import and library guard/limits/last adapters, plus library.limits.set dispatch. Drift checks wait on 216 and 285.
- Status contract confirmed with Fethry (beakley-0004, fethry-0009): nested
replyLimits: {requireCitation, citationsPerReply, fallback: [keys], problem: "reply-limits-unreadable" | null}. Check entries remain orderedscope/agent/file, pluslaston reads; no changed boolean.
Verification and remaining acceptance
- Static
git diff --check: clean so far. No Node, suite, test or mutant run. - Existing test file edits: none (numstat 0/0 for every pre-existing test). All new test files are listed in manifest.r1.sha256; no Mos approval requested.
mutants.pyis authored for isolated HEAD archives with green controls: M1 remove both writer fences; M2 compare incoming human; M3 split evidence from insert; M4 drop client reason. Not executed.- Still required: Sage CLEAR for targeted runs; fix first-run failures; supporting scope acceptance against row 283; 216 index/readLibrary fixture comparison; 285/runtime drift check; full library/business/bus/cli/harness/seat suites and every scripts/test-*.sh on Sage's gate; mutant execution; Webby approval.
- Before in-review, perform brief's obsolete-code/key search and report outside ownership hits to Sage. render.mjs/render.test.mjs hits belong to 225.
- No queue changes, protected branch pushes, gate claims or acceptance claims.
Static obsolete-code/key search completed: only packages/library/src/render.mjs:6 and packages/library/tests/render.test.mjs:58 match no-cited-answer; both belong to row 225 per standing ruling. No owned-path hit. Repeat before in-review after dependency changes.
Webby early look 0939c0682 / webby-0249 and sage-3668/3670
This remains an untested draft. The follow-up adds tests only; production E4 changes wait for the held-lock regression's first RED under Sage CLEAR.
- E1: added an ordinary actor
mallorythat sets bothhumanto itself andreplyLimits. The existing role/tester actors did not distinguish M2 because the actor-shape exclusions rejected them independently of the human comparison. M2 is still unrun; no kill claimed. - E2: added a real bus event assertion for
agent: "acme/scribe"from a file's Mosaic-Agent trailer. The cited tip includes a later unrelated commit, so the event must store the file commit rather than the library tip. thread.messages must showlast === filefor that unchanged path. Supporting scope still waits for row 283's real fixture, as ruled. - E3: sage-3668 accepts direct writer.write tests under chief and tester actors
as substitutes for the brief's setter cases (brief lines 483-491 at base
45dca69f6). Correction to the early-look premise: organization.set DOES exist, broker.mjs:4701/4709, but ORGANIZATION_KEYS excludes replyLimits; instances.set also cannot carry it. Direct writes exercise the shared M11 boundary those setters cannot reach with that input. Sage confirmed the accurate reason in sage-3670; the unrelated actor case remains required. - E4: traced readSyncState -> withLibraryLock -> library-sync-busy after five seconds -> servedMirror catch-all -> null served -> misleading citation-invalid. New real-flock/socket test first proves the cite valid, holds the lock, asserts the exact citation-unavailable reason the agent receives, verifies no insert, and checks fixed fallback delivery and recovery after unlock. Additional tests distinguish malformed sync state from absent/new mirrors, and assert that the actual runner retry request contains that reason. These tests are expected RED until the fix. Planned production change: only an absent mirror or legitimate empty state yields null; other failures become GuardError citation-unavailable; bodies without path cites do not require the mirror lock. Add the code to GUARD_CODES so the runner sends the agent that reason on its one retry. Per sage-3670, existing four fallback bodies can remain only if that delivery is verified. M5 restores catch-all behavior; authored, not run.
- E5: first-library-project selection is a Launchpad handoff implementation choice, not a validated rule that a business can only have one library. Cites into another library remain a limitation. No mapping/schema rule added.
- E6: the broker's full guard table now runs as both coder and research.
- E7: new citation-runtime.test.mjs starts the real runtime, reads limits from the real organization file, then changes, corrupts and removes that fixture file and checks library.status without replacing the library adapter.
No Node, tests or mutants ran. No test that predated row 217 changed.
Webby follow-up 192049c98 / webby-0258
E1, E2, E6 and E7 closed statically; no executed acceptance claimed. E3 correction and E5 limitation accepted. E4 tests accepted statically; real RED then production fix/green remain on hold for Sage CLEAR, with supporting scope waiting on 283. F1: citation-helpers status now uses its mutable served value, matching guard/last after setServed instead of reporting the original fixture commit. Test-only fixture correction, unrun. manifest.r3.sha256 records the updated helper; no production or old-test changes.
Round 2 / sage-4037 — 2026-10-24, Untested
New branch beakley/row217-r2 from published dde5b8496, rebased exactly onto
origin/refactor at e0c6142f3 (109 upstream commits since 45dca69f6). The
published original branch is unchanged; no amend or force-push. The replayed
four commits are b9ef816ff, 7400509ba, a447880cb, 2655ec010. Full range-diff:
rebase-r2.range-diff.txt. Last commit is =, the first three are ! from
conflict context/indentation and append-log placement described below.
Conflict resolutions:
- broker.mjs: retained landed grants.scope/grants.scope.set dispatch and added library.limits.set to the organization verb dispatch; neither path removed.
- runtime.mjs: retained grants.scope.set and added library.limits.set alongside it; retained query/sync wiring and all new base lifecycle behavior.
- organization.mjs: retained row 239's beforeWrite/revoked wrapper, placing both M11 fences before validations/revocation as on the old candidate. A refused reply-limit write cannot invoke beforeWrite.
- library/index.mjs: retained C2-05a buildIndex/query exports and added the guard and reply-limits exports.
- BUILD-LOG.md and docs/SESSIONS.md: retained upstream appends followed by all
Beakley appends. Static byte-prefix checks prove the entire
e0c6142f3log histories survive; all original Beakley entries also survive. - business.mjs, cli README and sandbox.mjs auto-merged. Static diff against the target confirms only this row's TOP_KEYS addition, README paragraph and one import-free protocol mount; landed supporting scope and room-address mount remain intact. runtime diff contains only the approved import, injected guard/limits/last adapters and setter dispatch, now beside grants.scope.set.
Correction recorded honestly: the first unpublished rebase attempt used an unbounded marker regex that removed code after a conflict. The diff stat caught it immediately; aborted the rebase and repeated with bounded markers. No result from that discarded attempt was pushed. The successful first replay matches the original 589 insertions/20 deletions; no broad deletions remain.
Implemented E4 under sage-4037's explicit direction to make the product fix while keeping all tests unrun. This supersedes the earlier planned RED-first execution order; no RED or green has been observed. The existing regression cases predate the fix. GUARD_CODES now includes citation-unavailable. Only a mirror confirmed absent by lstat, or readSyncState's legitimate empty state, yields no served commit. Other read/lock/metadata errors give the fixed safe reason: "The library is busy or unavailable. Retry the answer when the library is available." The runner receives it through BusError.reason and includes it in its one retry request. The existing four fallback bodies remain. Plain, web-only and fixed replies require no mirror read, so a busy mirror cannot block the runner's fixed fallback. M5's real production anchor now exists.
Supporting scope after row 283 (8d2856ee3): added two broker tests using real
mapping/reader classification, not a scope stub. A path in both supporting and
playground refuses as canon; an agent-committed supporting path stores
scope=supporting, agent=acme/scribe and its file commit in message.checked.
C2-05a comparison: index-build.mjs builds its file map directly from readLibrary files; indexFor calls that same reader at the requested commit. Added a real fixture test comparing the index set, readLibrary set and libraryReader.lines admission, including supporting, unmapped Markdown and .canvas. This comparison is authored and statically traced, not executed; numerical results wait on CLEAR.
Current packet: manifest.r4.sha256, relative to e0c6142f3. No test file already
present at that base was edited. No Node, npm, tests, mutants or webui build run.
Ready for CLEAR after Lena's row 296. On CLEAR, install with npm ci
--ignore-scripts --no-audit --no-fund in THIS worktree root and packages/webui;
never link to canonical node_modules or run npm/rm in the canonical checkout.
Use short mktemp TMPDIR and timeout -k 10. Any old-test red goes to Sage before
an edit. Full green gate, mutants and Webby verdict remain outstanding.
Range-diff receipt rendering trims trailing whitespace on diff separator lines; no substantive range-diff content changed. This removes whitespace warnings caused by embedding raw diff output in a tracked text file.
Final base-to-candidate whitespace check found a trailing blank line inherited from Launchpad in limits.mjs; removed it without behavior changes. manifest.r5.sha256 supersedes r4 for the exact candidate file hashes.
CLEAR sage-4042/4043 — execution started 2026-10-24
Queue beakley-217-start initially refused Lena's review-outcome lock twice; same-op retry succeeded at rev3894 (briefed→in-progress). No queue bypass. Short TMPDIR /mnt/storage/scratch/tmp/tNoueZ. Worktree-local npm ci at root (128 packages) and packages/webui (2) completed; neither path was a symlink. No npm/rm command ran in canonical. All test commands use timeout -k 10.
E4 current file: 3 pass/0 fail/0 skip. M5 isolated pre-fix stand-in: 1 pass, 2 expected assertion failures (citation-invalid instead of citation-unavailable), exit1. Restored product bytes and checkout product hashes, then E4 restored control 3/3. Receipts under run-r2/m5-red. M1 six-space anchors both match exactly once on the eight-space lines.
Touched test files first run: 56 pass/1 fail, zero skip/cancel. The sole first-red was NEW citation-runtime.test.mjs invalid-authority at Broker.checkBusiness: validator output has unresolved roles and is not the host's broker projection. Adjusted that new fixture only, following limits-runtime.test.mjs: minimal empty-authority coder, validated real project mappings, real organization adapter and systemFor(root). Single rerun 1/1, then all touched files 57/57. No base test failure or edit. First log retained as run-r2/touched-first.log and reported to Sage in beakley-0014. No production change was required.
The isolated mutant driver now wraps each node run in timeout -k 10, refuses a symlinked root node_modules, restores mutated files in finally, verifies original checkout product hashes after every mutant and reruns the restored control. Optional name filters allow the E4 M5 RED before the full mutant pass. No canonical dependency link is used; isolated copies link only this worktree's own dependency install.
Final slot results / 2026-10-24 10:21Z
All requested runs completed serially under sage-4042/4043 on source revision
2d274a5b6. Final receipt commits change only tracking and logs, not packages.
| Whole suite | Pass | Fail / skip / cancel |
|---|---|---|
| library | 142 | 0 / 0 / 0 |
| business | 270 | 0 / 0 / 0 |
| bus | 974 | 0 / 0 / 0 |
| cli | 988 | 0 / 0 / 0 |
| harness | 172 | 0 / 0 / 0 |
| seat | 218 | 0 / 0 / 0 |
Total 2,764 whole-suite tests. Touched files rerun 57/57. The unchanged
RUNNER_FILES import-closure test passed in seat (seat-suite.log:153). The only
first-run failure was the NEW runtime fixture already recorded above; no old
test failed and no test present at e0c6142f3 was edited.
M1–M5 all killed by the intended assertion, each with Node exit1, a green control and green restored control. Driver exit0. M1 catches missing writer refusals; M2 is killed by mallory's human swap; M3 detects one message left behind after evidence failure; M4 detects the missing reason; M5 detects citation-invalid in place of citation-unavailable on contention and bad state. Every mutation was in a disposable HEAD archive. Each changed file was restored, checkout product hashes checked after every mutant, and the restored control rerun. All five final restored.sha256 certificates match current product files. M5 also ran separately before the whole suites as the authorized pre-fix RED stand-in; its held-lock and malformed-state assertions failed, then restored E4 passed 3/3. Full raw controls/negatives/restores are retained.
Receipts: run-r2/summary.json and summary.txt; *-suite.log; touched-first.log, touched-rerun.log; availability-green.log; runtime-fixture-retry.log; npm-root.log and npm-webui.log; m1-anchors.txt; m5-red/ and mutants/. All are text, no binary artifact added. All Node/mutant/npm runs used the short TMPDIR and timeout -k 10. Both node_modules trees are local npm ci installs. No canonical npm/rm or canonical dependency link. No further runtime/source changes after the tests.
Acceptance formerly waiting on dependencies is executed: real row283 supporting canon refusal and supporting/agent event pass; the C2-05a readLibrary/index set comparison passes; runtime readRaw live/corrupt/missing-file test passes; runner retry request carries the E4 availability reason. The repeat obsolete-name search finds only render.mjs:6 and render.test.mjs:58, owned by row225; no owned hit. First-library selection remains the accepted E5 limitation. Webby-0274 N1 is a nonblocking wording limitation: configuration faults share the safe busy-or-unavailable retry text. No policy/schema restriction was invented.
Current complete changed-file manifest over e0c6142f3..candidate is candidate-manifest.sha256, excluding itself to avoid a circular hash. It includes source, tests, records and evidence. Earlier numbered manifests are historical. Formal Webby verdict and all scripts/test-*.sh at landing remain Sage's steps; this is verified for review, not an integration/deployment claim.
Exact negative-test logs retain Node's whitespace-only diagnostic lines. Whole diff --check reports those 12 blank-line padding warnings in run-r2 logs; source/docs diff --check excluding captured run-r2 evidence is clean. No source whitespace problem or test failure is hidden by that exclusion.