diff --git a/BUILD-LOG.md b/BUILD-LOG.md index 4cbe222cb..d3fb6ce7b 100644 --- a/BUILD-LOG.md +++ b/BUILD-LOG.md @@ -5521,3 +5521,5 @@ claim. Receipts and limitations in agents/lena/work/queue-296/BUILD.md and run-r - 2026-10-24 (rockerduck, row 286 / #1791, r3 before gate): transplanted Ludwig 45dca69f6..573fa0be0 onto b19ffa04f, preserved newer exports in sole index.mjs conflict; plain-text range-diff, patch IDs and reader/pin drift inventory in agents/rockerduck/work/queue-286/BUILD.md. UNTESTED by sage-4040: no setup or tests until CLEAR. - 2026-10-24 (rockerduck, row 286 / #1791, r3 after sage-4054 CLEAR): own-worktree installs; library 140/140 and bus 963/963; M1 forced-refspec and M2 missing-inode-compare killed at semantic assertions, restored before final suites; all gate-output fixture searches zero. Four first-run reds only in new credential test; setup corrections and intermediate findings recorded in agents/rockerduck/work/queue-286/BUILD.md. No old test edited during gate; shell/CLI suites remain Sage landing gate. + +- 2026-10-24 (rockerduck, row286 / #1791, r4 before gate, sage-4079): all 15 r3 commits transplanted to d0a6a87cd on new rockerduck/row286-r4. Three product overlaps auto-merged with row217 preserved; two append-log conflicts retain both histories. Range-diff and adjacent hunk evidence in agents/rockerduck/work/queue-286/BUILD.md. UNTESTED r4: Git-only until own-branch push, library/bus rerun waits for CLEAR after row285. diff --git a/agents/rockerduck/work/queue-286/BUILD.md b/agents/rockerduck/work/queue-286/BUILD.md index c0d5c41e2..512a53b3e 100644 --- a/agents/rockerduck/work/queue-286/BUILD.md +++ b/agents/rockerduck/work/queue-286/BUILD.md @@ -522,3 +522,561 @@ this BUILD and gate receipts. Shared append-only BUILD-LOG/SESSIONS are excluded candidate hashes so unrelated later appends do not invalidate the review. Scratch run directory retained for landing audit: /mnt/storage/scratch/tmp/FcfQ9q + +## r4 transplant — sage-4079 (2026-10-24) + +Base d0a6a87cd includes rows 296 and 217; new branch rockerduck/row286-r4. +R3 branch is unchanged. All 15 commits b19ffa04f..2e3a5ddd4 cherry-picked in order; +transplanted implementation tip 02f1c2df6. No setup, npm, Node, tests or mutants run. +R3 gate receipts above are historical evidence only, not a claim about the new base. +Magica's row285 gate runs first; r4 library and bus reruns wait for Sage CLEAR. + +Only conflicts: BUILD-LOG.md and docs/SESSIONS.md during 29e830cac. For each, retained +the current-base bytes and appended exactly the additions from that commit. The later +r3 gate-log append auto-merged. Both complete log histories remain; no entry removed. +All product files auto-merged, without manual changes. No test file edited. + +Range command: git range-diff b19ffa04f..2e3a5ddd4 d0a6a87cd..02f1c2df6 +The endpoint is the transplanted implementation tip, before this r4 evidence/manifest +commit. Full command output in range-diff-r4.txt and below. The final bookkeeping +commit adds only evidence, manifest and append-only session/build entries. +12 commits are =, three are !: sync export context now includes row217's REPLY_LIMITS, +and the two append-log commits have the newer retained log context. No changed test patch. + + 1: 3326d9487 = 1: e6b7abf9b Row 286 C2-03b: build plan and four scope questions (BUILD.md only) + 2: e155e3245 = 2: 764debfe1 Row 286 C2-03b: sage-2922 files-owned extension; Q4 back to Sage (user is the bot fetch identity) + 3: 6ce15eddd = 3: d0d25b04b Row 286 C2-03b: sage-2925 Q4 ruling (humanCredential takes her login; editor.user is row 283's) + 4: c2c4ac679 = 4: 6c99ccc7b Row 286 C2-03b: fold dewey-0860 (Q1 sh fd/inode check, Q2 chief by roles definition, N1-N3) + 5: 8ca442959 = 5: 299d7f50f Row 286 C2-03b: sage-2928 rulings (sh helper, chief by roles definition, departure noted) + 6: cca76fa95 ! 6: a7f274b00 Row 286 C2-03b: library push, per-seat credentials, the chief's fetch credential, askpass fd check (#1791, sage-2922/2925/2928, dewey-0860); unrun + @@ packages/library/src/index.mjs: export { readLibrary, listTree, readTexts, parse + +export { syncCommand, sync, push, humanCredential, ASKPASS, SLOT, HUMAN_SLOT, CREDENTIAL_KINDS, SYNC_INTERVAL_MS } from './sync.mjs'; + export { buildIndex, indexFor, clearIndexCache, indexCacheSize } from './index-build.mjs'; + export { sees, find, get, search, manuscript, universeInfo, QUERY_REPLY_CAP, LOOKUP_LIMIT, MANUSCRIPT_LINES } from './query.mjs'; + + export { REPLY_LIMITS, resolveReplyLimits, checkReplyLimits } from './limits.mjs'; + + ## packages/library/src/mirror.mjs ## + @@ packages/library/src/mirror.mjs: async function readStateHeld(mirror, { branch } = {}) { + 7: bb29ee2d9 = 7: 4488f8ab0 Row 286: library.status shows the credential (webby-0151 R3); fired chief revokes its row as row 281 does; unrun + 8: 90b70a6a6 = 8: 6b731a305 Row 286 C2-03b: fold dewey-0864 (T7/T9 through grants.revoke and instance.fire, race fetch takes the sync guard, two-chief code, id -u shim note) + 9: d037e98d4 = 9: 0d1d99714 Row 286 C2-03b: cite sage-2947 (T7 real verbs, R1 in this row, 285/286 rebase rule) +10: f2a43d69d = 10: 2e2f71e6f Row 286 C2-03b: fold dewey-0869 and sage-2951 (marker-gated busy test, T9 scratch roles with a chief gitea credential, fired-chief path cited) +11: 888548607 = 11: 674f3d638 Row 286 C2-03b: BUILD.md notes for dewey-0869 and sage-2951 (fired-chief path :4308, marker-gated busy test, T9 scratch roles) +12: 7842700fb = 12: fd04dba8b Row 286 C2-03b r2: rebase onto 45dca69f6 (sage-3579). The range-diff is all =. Drift check of the paths the tests read is in BUILD.md. Unrun. +13: 29e830cac ! 13: ed94e24de Row 286 r3: transplant evidence, conflict resolution and static reader drift; untested pending CLEAR + @@ Commit message + Row 286 r3: transplant evidence, conflict resolution and static reader drift; untested pending CLEAR + + ## BUILD-LOG.md ## + -@@ BUILD-LOG.md: remain; no live state, schema or bus policy change. + +@@ BUILD-LOG.md: claim. Receipts and limitations in agents/lena/work/queue-296/BUILD.md and run-r + + 2026-10-24 | Beakley (88b97f65) | Row 217 round 2, sage-4037 | Rebased published dde5b8496 onto e0c6142f3 on new beakley/row217-r2; both append-log histories retained. Conflicts preserve landed grant dispatch, revocation hook and lookup exports. Added E4 citation-unavailable product path and real supporting-scope/index comparison tests after row283 8d2856ee3. Untested: no Node/npm/tests/mutants/build; ready for Sage CLEAR after Lena296. Full range-diff and honest discarded local rebase correction in agents/beakley/work/queue-217/BUILD.md. + + - 2026-10-24 | Goldie | Row265 / #1770 verified (mos-1567, sage-3942) | Approved correction adds solely address import pin + Row265 comment to project-runtime.test and one pure-source RUNNER_FILES mount; new block checks parser has no imports. Serialized fresh-short-TMP timeout-k10: unchanged sandbox10/10, parser15/15, rooms18/18, full bus957/957, twelve named refusal mutants killed (each Node1, driver0), restored parser15/15 + rooms18/18. All positives zero fail/skip/cancel; every mutation restored full broker SHA71b32ee4. Old first-red evidence retained, no other old-test change. Slot returned goldie-0034; Boyd packet explicitly includes mount-list review, candidate push next. + - 2026-10-24T07:18:53Z | Sage | Row 327 (#1825, Bradford, Poe and Dewey) LANDED 68c08b4e7. Before: refactor at 94d9e90a6; the push guard was a scratch script with no reviewed-binary check. After: scripts/push-check.sh and scripts/test-push-check.sh on refactor, 3 commits cherry-picked onto 6a5e12511 with blobs equal to the round 3 tip d858c9f8b, plus doc commits 76f84465f and 68c08b4e7. Binaries are found by numstat or a NUL in the first 8000 committed bytes, regardless of attributes; each needs its sha256 and path in an approved latest-round candidate; an unconfirmed queue tail exits 2. Reviews: Poe c31525 rev 3882, Dewey c31526 rev 3883. Gate: 1st run 06:57Z RED, not the candidate: canonical node_modules was empty from 05:45:15Z (sage-4023). Rerun with its own root npm ci GREEN 07:15:49Z: 17 package suites 0 failures (cli 986, plugins 119, webui 418), 11 scripts exit 0, push-check 6 mutants KILLED; skips are the queue canonical-root check and the row 244 live provider cases. The landed push-check.sh passed its own push (NO_BINARY, NO_ATTRIBUTION, PUSH_READY). mos-1575: gates install their own node_modules; canonical restored with npm ci (128 packages). + + 2026-10-24T10:21Z | Beakley (88b97f65) | Row 217 round2 slot verified, sage-4042/4043 | Source 2d274a5b6: touched57/57, whole library142/142 business270/270 bus974/974 cli988/988 harness172/172 seat218/218, all zero fail/skip/cancel. M1-M5 killed, controls/restored controls green, product hashes restored after each; E4 RED stand-in observed. Only first-red was new runtime fixture invalid-authority, corrected and retained in receipts; no old test failed/edited. Local root/webui npm ci, short TMPDIR, timeout-k10; no canonical npm/rm or module link. Full evidence agents/beakley/work/queue-217/run-r2; Sage owns scripts landing gate and formal review. + + + +- 2026-10-24 (rockerduck, row 286 / #1791, r3 before gate): transplanted Ludwig 45dca69f6..573fa0be0 onto b19ffa04f, preserved newer exports in sole index.mjs conflict; plain-text range-diff, patch IDs and reader/pin drift inventory in agents/rockerduck/work/queue-286/BUILD.md. UNTESTED by sage-4040: no setup or tests until CLEAR. + + @@ agents/rockerduck/work/queue-286/BUILD.md (new) + + ## docs/SESSIONS.md ## + @@ docs/SESSIONS.md: are never rewritten or removed; corrections are new entries. + - 2026-10-24T04:27Z | Goldie (a13dd6d5-5e73-4b7d-8318-02abeff24940) | Row265 / #1770 C2-09b rooms | Goldie owns build, Boyd reviews under sage-3915. New goldie/row265 worktree at ec86f2c84, claim rev3814; room verbs/parser/new tests prepared, no old tests changed. Sage-3932 slot: new parser14/14 and rooms18/18 passed; whole bus in progress before refusal mutants, stop rule active. + - 2026-10-24T04:35Z | Goldie (a13dd6d5-5e73-4b7d-8318-02abeff24940) | Row265 / #1770 verified | First slot stopped at project-runtime import pin. mos-1567 narrowly authorizes pin and pure-source mount correction. sage-3942 rerun: sandbox10/10, parser15/15, rooms18/18, bus957/957, twelve refusal mutants killed/restored SHA71b32ee4, parser15/15 + rooms18/18 again. Slot returned goldie-0034; no further test runs. Boyd reviews RUNNER_FILES alongside rooms; own-branch push/claimant in-review next. + - 2026-10-24T07:18:53Z | Sage (1ef1e4f8) | Row 327 / #1825 push guard landed (mos-1572 option A, mos-1575) | Gate went red 06:57Z on an empty canonical node_modules (Glomgold's webui npm ci through a link to canonical, glomgold-0011); rerun with its own npm ci GREEN 07:15:49Z on 1bd214e38; pushed 68c08b4e7 07:18:03Z; #1825 closed c31530; canonical restored (128 packages); brief template rule 4db23a51f | landed + + 2026-10-24 | Beakley (88b97f65) | Row 217 round 2 under sage-4037 | New beakley/row217-r2 rebased onto e0c6142f3, retained both log histories, E4 product fix and supporting/index tests drafted. No Node/npm/tests/mutants run; ready for CLEAR; local-only dependency installs required on CLEAR, old-test red goes to Sage. + + + + 2026-10-24T10:21Z | Beakley (88b97f65) | Row217 #1718 round2 slot | All touched57 and six whole suites2764 pass, zero skips/cancels; M1-M5 killed/restored, E4 RED stand-in observed. First-new runtime fixture red recorded and corrected; no old-test change/failure. Evidence in agents/beakley/work/queue-217/run-r2. Verified for review on beakley/row217-r2; Sage landing scripts/review remain. + + + +- 2026-10-24 — rockerduck (Codex, a403aa78-b550-4bab-a613-7ea3fd75ec79), row 286 C2-03b / #1791 r3: twelve-commit transplant and static drift evidence prepared; UNTESTED, awaiting Sage CLEAR after own-branch push; no npm/tests run. +14: 4b8261f41 = 14: b7d394928 Row 286 r3: record successful canonical queue start and pre-CLEAR push receipt +15: 2e3a5ddd4 ! 15: 02f1c2df6 Row 286 r3: fix new credential fixtures and record green CLEAR gate with killed mutants + @@ Commit message + Row 286 r3: fix new credential fixtures and record green CLEAR gate with killed mutants + + ## BUILD-LOG.md ## + -@@ BUILD-LOG.md: remain; no live state, schema or bus policy change. + - 2026-10-24T07:18:53Z | Sage | Row 327 (#1825, Bradford, Poe and Dewey) LANDED 68c08b4e7. Before: refactor at 94d9e90a6; the push guard was a scratch script with no reviewed-binary check. After: scripts/push-check.sh and scripts/test-push-check.sh on refactor, 3 commits cherry-picked onto 6a5e12511 with blobs equal to the round 3 tip d858c9f8b, plus doc commits 76f84465f and 68c08b4e7. Binaries are found by numstat or a NUL in the first 8000 committed bytes, regardless of attributes; each needs its sha256 and path in an approved latest-round candidate; an unconfirmed queue tail exits 2. Reviews: Poe c31525 rev 3882, Dewey c31526 rev 3883. Gate: 1st run 06:57Z RED, not the candidate: canonical node_modules was empty from 05:45:15Z (sage-4023). Rerun with its own root npm ci GREEN 07:15:49Z: 17 package suites 0 failures (cli 986, plugins 119, webui 418), 11 scripts exit 0, push-check 6 mutants KILLED; skips are the queue canonical-root check and the row 244 live provider cases. The landed push-check.sh passed its own push (NO_BINARY, NO_ATTRIBUTION, PUSH_READY). mos-1575: gates install their own node_modules; canonical restored with npm ci (128 packages). + +@@ BUILD-LOG.md: claim. Receipts and limitations in agents/lena/work/queue-296/BUILD.md and run-r + + 2026-10-24T10:21Z | Beakley (88b97f65) | Row 217 round2 slot verified, sage-4042/4043 | Source 2d274a5b6: touched57/57, whole library142/142 business270/270 bus974/974 cli988/988 harness172/172 seat218/218, all zero fail/skip/cancel. M1-M5 killed, controls/restored controls green, product hashes restored after each; E4 RED stand-in observed. Only first-red was new runtime fixture invalid-authority, corrected and retained in receipts; no old test failed/edited. Local root/webui npm ci, short TMPDIR, timeout-k10; no canonical npm/rm or module link. Full evidence agents/beakley/work/queue-217/run-r2; Sage owns scripts landing gate and formal review. + + - 2026-10-24 (rockerduck, row 286 / #1791, r3 before gate): transplanted Ludwig 45dca69f6..573fa0be0 onto b19ffa04f, preserved newer exports in sole index.mjs conflict; plain-text range-diff, patch IDs and reader/pin drift inventory in agents/rockerduck/work/queue-286/BUILD.md. UNTESTED by sage-4040: no setup or tests until CLEAR. + + + @@ agents/rockerduck/work/queue-286/token-search.txt (new) + + ## docs/SESSIONS.md ## + @@ docs/SESSIONS.md: are never rewritten or removed; corrections are new entries. + - 2026-10-24T07:18:53Z | Sage (1ef1e4f8) | Row 327 / #1825 push guard landed (mos-1572 option A, mos-1575) | Gate went red 06:57Z on an empty canonical node_modules (Glomgold's webui npm ci through a link to canonical, glomgold-0011); rerun with its own npm ci GREEN 07:15:49Z on 1bd214e38; pushed 68c08b4e7 07:18:03Z; #1825 closed c31530; canonical restored (128 packages); brief template rule 4db23a51f | landed + + 2026-10-24T10:21Z | Beakley (88b97f65) | Row217 #1718 round2 slot | All touched57 and six whole suites2764 pass, zero skips/cancels; M1-M5 killed/restored, E4 RED stand-in observed. First-new runtime fixture red recorded and corrected; no old-test change/failure. Evidence in agents/beakley/work/queue-217/run-r2. Verified for review on beakley/row217-r2; Sage landing scripts/review remain. + + - 2026-10-24 — rockerduck (Codex, a403aa78-b550-4bab-a613-7ea3fd75ec79), row 286 C2-03b / #1791 r3: twelve-commit transplant and static drift evidence prepared; UNTESTED, awaiting Sage CLEAR after own-branch push; no npm/tests run. + + + +Static append-prefix check: both logs begin with every byte at d0a6a87cd. + +### packages/bus/src/broker.mjs — row217 hunks next to the transplanted row286 hunks + +Row217 / newer base (b19ffa04f..d0a6a87cd): + +diff --git a/packages/bus/src/broker.mjs b/packages/bus/src/broker.mjs +index 163a7ec65..35e62ab27 100644 +--- a/packages/bus/src/broker.mjs ++++ b/packages/bus/src/broker.mjs +@@ -204,15 +204,26 @@ const canonical = (x) => + Number.isFinite(Date.parse(x)) && + new Date(x).toISOString() === x; + export class BusError extends Error { +- constructor(code) { ++ // C2-06 (sage-3599): only the citation guard's refusals carry a reason, and the envelope passes it on. ++ constructor(code, reason) { + super(code); + this.code = code; ++ if (reason !== undefined) this.reason = reason; + } + } + const fail = (code) => { + throw new BusError(code); + }; + const object = (x) => x !== null && typeof x === 'object' && !Array.isArray(x); ++// C2-06 (design 5.2, B7): the page store keeps a session's last 20 broker fetches, 200 KB of text each. ++const PAGE_COUNT = 20; ++const PAGE_BYTES = 200 * 1024; ++// C2-06: the guard's check event takes an id derived from the message's, so a thread read finds it ++// through the unique index on events.id (there is none on subject). ++const checkEventId = (mid) => { ++ const h = createHash('sha256').update('message.checked:' + mid).digest('hex'); ++ return `${h.slice(0, 8)}-${h.slice(8, 12)}-${h.slice(12, 16)}-${h.slice(16, 20)}-${h.slice(20, 32)}`; ++}; + const text = (x, max = 4096) => typeof x === 'string' && x.length > 0 && x.length <= max && !x.includes('\0'); + const id = (x) => text(x, 160) && /^[a-zA-Z0-9][a-zA-Z0-9_.:/-]*$/.test(x); + function keys(x, allowed, required = []) { +@@ -393,6 +404,11 @@ export class Broker { + #credentialVerbs; + #project; + #library; ++ // C2-06 (design 5.2, B7): cap -> the session's kept web.fetch pages, in a library business only. ++ // In memory, dropped with the session. ++ #pages = new Map(); ++ // C2-06: { s, check } while a guarded message.send or a thread.messages re-enters request(). ++ #guardPass = null; + #usage; + #limits; + #harnessOn; +@@ -1412,7 +1428,10 @@ export class Broker { + this.#launcherReleased.delete(key); + this.#accessRevoked.delete(key); + for (const [cap, s] of this.#sessions) +- if (!s.human && !s.reader && s.business === record.business && s.run === record.run) this.#sessions.delete(cap); ++ if (!s.human && !s.reader && s.business === record.business && s.run === record.run) { ++ this.#sessions.delete(cap); ++ this.#pages.delete(cap); ++ } + return this.#store.transaction(() => { + const h = this.#own(session); + const released = h?.op === 'claim' && h.holder_run === session.run; +@@ -1494,6 +1513,7 @@ export class Broker { + } + disconnect(cap) { + this.#sessions.delete(cap); ++ this.#pages.delete(cap); + } + identity(cap) { + const s = this.#session(cap); +@@ -4758,12 +4778,21 @@ export class Broker { + return this.#requestProjectFile(s, { verb: request.verb, args: structuredClone(args) }); + if (LIBRARY_VERBS.includes(request.verb)) + return this.#requestLibrary(s, { verb: request.verb, args: structuredClone(args) }); ++ // C2-06 (design 5.2): an agent's message to the human in a library business passes the citation ++ // guard first, outside any transaction, and thread.messages adds each path cite's `last`. Both ++ // then re-enter request() for the synchronous path below. ++ if (this.#guardPass?.s !== s) { ++ if (request.verb === 'message.send' && this.#guarded(s, args.to)) ++ return this.#guardedSend(cap, s, request, structuredClone(args)); ++ if (request.verb === 'thread.messages' && this.#libraryProject(s.business) && this.#library?.last) ++ return this.#withLast(cap, s, request); ++ } + if (CREDENTIAL_VERBS.includes(request.verb)) return this.#requestCredential(s, request.verb, structuredClone(args)); + if (request.verb === 'instance.hire' || request.verb === 'instance.fire') + return this.#chiefLifecycle(s, request.verb, structuredClone(args)); + if (request.verb === 'grants.scope' || request.verb === 'grants.scope.set') + return this.#grantScopeVerb(s, request.verb, structuredClone(args)); +- if (["limits", "limits.set", "organization.set", "organization.revision", "plugins", "plugins.set", "instances", "instances.set", "routes", "routes.set", "veto.set"].includes(request.verb)) { ++ if (["limits", "limits.set", "organization.set", "organization.revision", "plugins", "plugins.set", "instances", "instances.set", "routes", "routes.set", "veto.set", "library.limits.set"].includes(request.verb)) { + // Row 123 (#1617, REQ-COS-1, REQ-LIMIT-1): organization.set is limits.set for a role whose + // file lists organization.change. It takes the same keys, runs the same write path and + // logs the same receipt; only the actor differs: the role definition and instance. +@@ -4809,6 +4838,12 @@ export class Broker { + keys(args, VETO_KEYS, VETO_KEYS); + this.#human(s); + this.#mayHuman(s, "veto.set", args.name); ++ } ++ // C2-06 M11: the human's replyLimits verb. The tester is refused by the gate above and an agent ++ // session by human-required; the writer's fence refuses any other actor. ++ else if (request.verb === "library.limits.set") { ++ keys(args, ["revision", "replyLimits"], ["revision", "replyLimits"]); ++ this.#human(s); + } else { + keys(args, ORGANIZATION_KEYS, ["revision"]); + // Row 194 (D2.4, B7): the chief can't change a kept instance's model, as that replaces it at +@@ -5263,7 +5298,14 @@ export class Broker { + const context = { business: this.#business(s.business), project: args.project }; + let result; + if (verb === 'library.file') result = await this.#library.readFile({ ...context, path: args.path }); +- else if (verb === 'library.status') result = await this.#library.status(context); ++ else if (verb === 'library.status') { ++ result = await this.#library.status(context); ++ // C2-06: the reply limits in force, read from the file now, and the keys that fell back. ++ if (this.#library.replyLimits) { ++ const { requireCitation, citationsPerReply, fallback, unreadable } = this.#library.replyLimits(s.business); ++ result = { ...result, replyLimits: { requireCitation, citationsPerReply, fallback, problem: unreadable ? 'reply-limits-unreadable' : null } }; ++ } ++ } + else { + // A fetch that did not move served still answers with the code, so the refusal is recorded. + const { state, code } = await this.#library.sync(context, { accept: args.accept ?? null }); +@@ -5277,6 +5319,78 @@ export class Broker { + throw this.#refused(s, Failure && error instanceof Failure ? new BusError(error.code) : error, request); + } + } ++ // C2-06: the business's library project, the first in file order, or null. ++ #libraryProject(business) { ++ return Object.entries(this.#business(business).projects ?? {}).find(([, p]) => p.kind === 'library')?.[0] ?? null; ++ } ++ // C2-06 (design 5.2): every agent session's message to the human in a business with a library project ++ // is guarded, whatever the sender's definition. ++ #guarded(s, to) { ++ return to === 'human' && !s.human && !s.tester && !s.user && !s.reader && !s.console && this.#libraryProject(s.business) !== null; ++ } ++ #reenter(cap, s, request, check) { ++ this.#guardPass = { s, check }; ++ try { ++ return this.request(cap, request); ++ } finally { ++ this.#guardPass = null; ++ } ++ } ++ // As #requestProject: the git reads run outside any SQL transaction. A guard refusal is recorded with ++ // its code and reaches the caller with the guard's reason; the send then runs, and stores the check ++ // result in its own transaction. ++ async #guardedSend(cap, s, request, args) { ++ let check; ++ try { ++ this.#store.transaction(() => this.#agent(s)); ++ if (!this.#library?.guard || !this.#library?.replyLimits) fail('project-not-configured'); ++ if (typeof args.body !== 'string') fail('invalid-request'); ++ const business = this.#business(s.business); ++ check = await this.#library.guard({ business, project: this.#libraryProject(s.business) }, args.body, { ++ limits: this.#library.replyLimits(s.business), ++ definition: business.roles[s.role]?.definition ?? null, ++ pages: this.#pages.get(cap) ?? [], ++ }); ++ } catch (e) { ++ const Guard = this.#library?.GuardError; ++ throw this.#refused(s, Guard && e instanceof Guard ? new BusError(e.code, e.reason) : e, request); ++ } ++ return this.#reenter(cap, s, { verb: 'message.send', args }, check); ++ } ++ // C2-06 (sage-3595, morgana-0200): each path cite of a checked row gains `last`, the file's last commit ++ // at the served tip, one git call per distinct path. Rows without `check` are unchanged. ++ async #withLast(cap, s, request) { ++ const rows = this.#reenter(cap, s, request, null); ++ if (!rows.some((m) => m.check)) return rows; ++ const cites = (m) => { ++ try { ++ const c = JSON.parse(m.body).citations; ++ return Array.isArray(c) ? c : []; ++ } catch { ++ return []; ++ } ++ }; ++ let last = new Map(); ++ try { ++ const paths = rows.filter((m) => m.check).flatMap((m) => cites(m).filter((c) => typeof c?.path === 'string').map((c) => c.path)); ++ last = await this.#library.last({ business: this.#business(s.business), project: this.#libraryProject(s.business) }, paths); ++ } catch { ++ last = new Map(); ++ } ++ return rows.map((m) => { ++ if (!m.check) return m; ++ const body = cites(m); ++ return { ...m, check: { ...m.check, citations: m.check.citations.map((c, i) => ++ c.scope === 'web' ? c : { ...c, last: last.get(body[i]?.path) ?? null }) } }; ++ }); ++ } ++ // C2-06 (B7): a fetch's text, kept for url cites in a library business only. ++ #keepPage(cap, s, url, page) { ++ if (!this.#sessions.has(cap) || !this.#libraryProject(s.business) || typeof page?.text !== 'string') return; ++ const text = Buffer.from(page.text).subarray(0, PAGE_BYTES).toString(); ++ const kept = { url, finalUrl: typeof page.finalUrl === 'string' ? page.finalUrl : null, text }; ++ this.#pages.set(cap, [...(this.#pages.get(cap) ?? []), kept].slice(-PAGE_COUNT)); ++ } + // The eight task verbs reach the trusted S3 handler here. It runs outside any transaction, gets the + // cap to authorize and record through authorize() and recordTask(); refusals are recorded as in request(). + async requestTask(cap, request, handler) { +@@ -5360,6 +5474,7 @@ export class Broker { + throw refuse(new BusError('web-failed')); + } + complete(out.summary); ++ if (verb === 'web.fetch') this.#keepPage(cap, s, args.url, out.result); + return { ...out.result, untrusted: true, notice: WEB_UNTRUSTED, source: verb }; + } + // Row 210 (#1707, design D5): host.run, one sudo command on a registered host over ssh, for a +@@ -5486,7 +5601,7 @@ export class Broker { + by, + ); + this.#routeSession(s.session); +- return { role: s.role, run: s.run, thread: s.thread }; ++ return { role: s.role, run: s.run, thread: s.thread, ...(this.#libraryProject(s.business) ? { library: true } : {}) }; + } + if ( + this.#store.get( +@@ -5510,7 +5625,8 @@ export class Broker { + by, + ); + this.#routeWaiting(s.business, s.role); +- return { role: s.role, run: s.run }; ++ // C2-06 (C2-07): the runner's switch to the library texts and retry. Absent elsewhere. ++ return { role: s.role, run: s.run, ...(this.#libraryProject(s.business) ? { library: true } : {}) }; + } + case 'role.release': { + keys(a, []); +@@ -5874,6 +5990,10 @@ export class Broker { + if (this.#userThread(s) && to === 'human') fail('user-thread-human'); + this.#checkMessaging(s.business, this.#sender(s), testerThread && to === 'tester' ? 'human' : to); + string(a.body, 32768); ++ // C2-06: a guarded send is stored only through #guardedSend's pass, with its check result. ++ const guarded = this.#guarded(s, to); ++ if (guarded && this.#guardPass?.s !== s) fail('storage-refused'); ++ const check = guarded ? this.#guardPass.check : null; + if ( + a.class !== undefined && + ![ +@@ -5920,6 +6040,9 @@ export class Broker { + a.corrects ?? null, + a.body, + ); ++ // C2-06: the stored check result shares the message's transaction (sage-3595 item 3). No new ++ // event kind, which would be a schema step: the events kind CHECK is migrations/3b.sql:9. ++ if (check) this.#event(s, 'action.allowed', { action: 'message.checked', message: mid, check }, mid, checkEventId(mid)); + const cancelled = this.#route(s.business, mid, to, thread); + const request = s.human + ? this.#event(s, 'human.input', { kind: 'instruction', message: mid }, mid) +@@ -6632,11 +6755,15 @@ export class Broker { + )?.seq; + if (after === undefined) fail('message-not-found'); + } ++ // C2-06 (row 225, morgana-0198): a row the citation guard checked carries the stored result. + return this.#store.all( + `SELECT m.* FROM messages m JOIN message_threads mt ON mt.message=m.id WHERE mt.session=? AND m.seq>? ORDER BY m.seq LIMIT ${limit}`, + session, + after, +- ); ++ ).map((m) => { ++ const e = this.#store.get("SELECT body FROM events WHERE id=? AND kind='action.allowed' AND subject=?", checkEventId(m.id), m.id); ++ return e ? { ...m, check: JSON.parse(e.body).check } : m; ++ }); + } + // Row 206 (193b2, #1704, design 5.3): the owner of a thread shares it read-only, or ends a share. + // A user's collaborator grant must still cover the thread, and a user target needs a live grant + +Merged row286 contribution (d0a6a87cd..02f1c2df6): + +diff --git a/packages/bus/src/broker.mjs b/packages/bus/src/broker.mjs +index 35e62ab27..699bde561 100644 +--- a/packages/bus/src/broker.mjs ++++ b/packages/bus/src/broker.mjs +@@ -271,6 +271,9 @@ const grantName = (body) => [body?.action, body?.operation].some(n => typeof n = + // Every grant-evidence read filters on this (duckworth-0067 N1): a look-alike under another kind or + // actor is not evidence. + export const GRANT_EVIDENCE = "kind='action.allowed' AND actor_role IS NULL AND actor_run='grant'"; ++// C2-03b: what a library-fetch-no-grant refusal tells the human (sage-2928). A BusError carries only its ++// code, so the timer's log line and the library README carry this text. ++export const LIBRARY_FETCH_FIX = 'add the chief of staff, or grant the library through C2-21'; + // r6 R4: the host record's identity, hashed at raise and at each later check. + export const registrySha256 = ({ address, port, user, sudo, hostKeys }) => + createHash('sha256').update(JSON.stringify({ address, port, user, sudo: !!sudo, hostKeys })).digest('hex'); +@@ -2047,6 +2050,33 @@ export class Broker { + // grant.host.enrolled or grant.failed died after its registry step: the key file and the record + // go, and it ends grant.failed interrupted. A resolved, unspent one is spent and ends the same way. + // Neither runs late. ++ // C2-03b (#1791, design 7.2): the credential the library fetch runs with, the bus's choice and not a ++ // pure one: it reads the store. The chief is any roles entry of definition STAFF_TO; a fire keeps it ++ // there (dewey-0860 Q2). Gitea grant evidence for a chief ends the slot fallback, and only the one ++ // listed chief's live, unheld gitea_grants row answers. With no chief entry, any gitea grant evidence ++ // refuses: a departure from the brief's pre-C2-21 fallback, accepted in sage-2928. ++ libraryFetchCredential(business) { ++ const b = this.#business(business); ++ const chiefs = Object.entries(b.roles ?? {}).filter(([, r]) => r?.definition === STAFF_TO).map(([name]) => name); ++ const evidence = (agent) => ++ this.#store.get( ++ `SELECT 1 FROM events WHERE business=? AND ${GRANT_EVIDENCE} AND json_extract(body,'$.method')='gitea' AND (? IS NULL OR json_extract(body,'$.agent')=?) LIMIT 1`, ++ business, ++ agent, ++ agent, ++ ); ++ const refused = { refused: 'library-fetch-no-grant', fix: LIBRARY_FETCH_FIX }; ++ if (!chiefs.length) return evidence(null) ? refused : { kind: 'slot' }; ++ if (!chiefs.some((agent) => evidence(agent))) return { kind: 'slot' }; ++ const listed = chiefs.filter( ++ (agent) => !this.#firing(business, agent) && (!Array.isArray(b.launch?.instances) || b.launch.instances.includes(agent) || b.launch.by === agent), ++ ); ++ if (listed.length !== 1) return refused; ++ const [agent] = listed; ++ const live = this.#store.get('SELECT user FROM gitea_grants WHERE business=? AND agent=?', business, agent); ++ if (!live || !this.#giteaKeys || this.#giteaKeys.held(business, agent)) return refused; ++ return { kind: 'chief', agent, user: live.user }; ++ } + reconcileGrants() { + const ended = []; + for (const business of Object.keys(this.#businesses)) { + +### packages/bus/src/runtime.mjs — row217 hunks next to the transplanted row286 hunks + +Row217 / newer base (b19ffa04f..d0a6a87cd): + +diff --git a/packages/bus/src/runtime.mjs b/packages/bus/src/runtime.mjs +index 366fd8520..57e64055f 100644 +--- a/packages/bus/src/runtime.mjs ++++ b/packages/bus/src/runtime.mjs +@@ -14,7 +14,7 @@ import { publishRemote, workingRepo, WorkingError } from '../../seat/src/working + import { createLoader, hasModule } from '../../plugins/src/loader.mjs'; + import { pluginSettings } from '../../business/src/plugin-settings.mjs'; + import { instanceSettings } from '../../business/src/instance-settings.mjs'; +-import { organizationWriter, OrganizationError } from '../../business/src/organization.mjs'; ++import { organizationWriter, OrganizationError, setReplyLimits } from '../../business/src/organization.mjs'; + import { credentialVerbs } from './credential-verbs.mjs'; + import { loadBusiness } from '../../business/src/business.mjs'; + import { loadRole } from '../../business/src/role.mjs'; +@@ -305,6 +305,13 @@ export async function startBroker({ + status: context => libraryModule.libraryStatus({ ...context, dataRoot }), + sync: (context, { accept }) => processing.work(() => libraryModule.sync({ ...context, dataRoot }, { ...syncOptions(context.business), accept })), + LibraryError: libraryModule.LibraryError, ++ // C2-06: the citation guard, the reply limits read from the business file at each check (none ++ // configured reads as unreadable, so requireCitation is true), and thread.messages' `last`. ++ guard: (context, body, options) => libraryModule.guardReply({ ...context, dataRoot }, body, options), ++ replyLimits: id => libraryModule.resolveReplyLimits(organization ++ ? organizationWriter({ dir: organization.dir, rolesDir: organization.rolesDir }).readRaw(id) : { readable: false }), ++ last: (context, paths) => libraryModule.lastCommits({ ...context, dataRoot }, paths), ++ GuardError: libraryModule.GuardError, + }, + project: { + readSpec: context => projectModule.readSpec({ ...context, dataRoot }), +@@ -338,6 +345,8 @@ export async function startBroker({ + else if(verb==='veto.set')result=instances.veto(id,args,actor); + // Row 298: the human's grant scope, through the instance writer. + else if(verb==='grants.scope.set')result=instances.grantScope(id,args,actor); ++ // C2-06 M11: the human's replyLimits, through the organization writer's fence. ++ else if(verb==='library.limits.set')result=setReplyLimits(organizationWriter({dir:organization.dir,rolesDir:organization.rolesDir}),id,args,actor); + // Row 194 (D2.1, D2.2): the chief's hire and fire, with the reason in the change context. + else if(verb==='instance.hire')result=instances.hire(id,args,{actor,context}); + else if(verb==='instance.fire')result=instances.fire(id,{name:args.name},{actor,context}); + +Merged row286 contribution (d0a6a87cd..02f1c2df6): + +diff --git a/packages/bus/src/runtime.mjs b/packages/bus/src/runtime.mjs +index 57e64055f..48e0e61e3 100644 +--- a/packages/bus/src/runtime.mjs ++++ b/packages/bus/src/runtime.mjs +@@ -4,7 +4,7 @@ import { fileURLToPath } from 'node:url'; + import { Store } from './store.mjs'; + import * as projectModule from '../../project/src/index.mjs'; + import * as libraryModule from '../../library/src/index.mjs'; +-import { Broker, BusError } from './broker.mjs'; ++import { Broker, BusError, LIBRARY_FETCH_FIX } from './broker.mjs'; + import { Credentials } from './credentials.mjs'; + import { serve } from './server.mjs'; + import { launchSettings } from '../../business/src/launch-settings.mjs'; +@@ -24,7 +24,7 @@ import { busBusiness } from './business.mjs'; + import { webService } from './web.mjs'; + import { hostExecutor, sweepRunDir } from './host-run.mjs'; + import { grantKeys, hostGrant, hostReference, sweepHostKeys } from './host-grant.mjs'; +-import { giteaGrant, giteaKeys, giteaStart } from './gitea-grant.mjs'; ++import { giteaGrant, giteaKeys, giteaStart, giteaReference } from './gitea-grant.mjs'; + import { verifyPrincipal } from './principal.mjs'; + import { loadAccess } from '../../business/src/access.mjs'; + import { inspectInterpreter, recordInterpreterStart } from './interpreter.mjs'; +@@ -223,9 +223,18 @@ export async function startBroker({ + } + // C2-03a: the slot is /secrets//library-gitea (design 10 step 4). Sync only + // checks that it is there; the askpass helper reads it. ++ // C2-03b: the broker chooses. The chief's grant store file once a chief has Gitea grant evidence, ++ // the slot before that, or a refusal sync records. The answer carries no file to sync but this one. + const slotDir = librarySync?.configDir ?? organization?.dir ?? null; ++ const fetchCredential = business => { ++ const choice = broker.libraryFetchCredential(business.id); ++ if (choice.kind === 'chief') ++ return { kind: 'chief', user: choice.user, file: storeRoot ? giteaReference(storeRoot, business.id, choice.agent).file : null }; ++ if (choice.kind === 'slot') return { kind: 'slot', file: slotDir ? join(slotDir, 'secrets', business.id, libraryModule.SLOT) : null }; ++ return { refused: choice.refused }; ++ }; + const syncOptions = business => ({ +- slot: slotDir ? join(slotDir, 'secrets', business.id, libraryModule.SLOT) : null, ++ credential: fetchCredential(business), + ...(librarySync ? { command: librarySync.command } : {}), + }); + // Row 194 (#1692, D3): after every write that commits, the broker takes the business as a restart +@@ -585,7 +594,8 @@ export async function startBroker({ + for (const { business, project } of timed) { + try { + const { code } = await libraryModule.sync({ business, project, dataRoot }, syncOptions(business)); +- if (code !== null) syncLog({ event: 'library-sync-held', business: business.id, project, code }); ++ if (code !== null) syncLog({ event: 'library-sync-held', business: business.id, project, code, ++ ...(code === 'library-fetch-no-grant' ? { fix: LIBRARY_FETCH_FIX } : {}) }); + } catch (e) { + if (e?.code === 'library-sync-busy') continue; + syncLog({ event: 'library-sync-refused', business: business.id, project, + +### packages/library/src/index.mjs — row217 hunks next to the transplanted row286 hunks + +Row217 / newer base (b19ffa04f..d0a6a87cd): + +diff --git a/packages/library/src/index.mjs b/packages/library/src/index.mjs +index 65bb898bd..e9f8c8cae 100644 +--- a/packages/library/src/index.mjs ++++ b/packages/library/src/index.mjs +@@ -11,3 +11,5 @@ export { SYNC_STATE_FILE, mirrorPath, ensureMirror, withLibraryLock, servedCommi + export { syncCommand, sync, ASKPASS, SLOT, SYNC_INTERVAL_MS } from './sync.mjs'; + export { buildIndex, indexFor, clearIndexCache, indexCacheSize } from './index-build.mjs'; + export { sees, find, get, search, manuscript, universeInfo, QUERY_REPLY_CAP, LOOKUP_LIMIT, MANUSCRIPT_LINES } from './query.mjs'; ++export { REPLY_LIMITS, resolveReplyLimits, checkReplyLimits } from './limits.mjs'; ++export { GUARD_CODES, FIXED_TEXTS, WEB_CITE_DEFINITIONS, REASON_MAX, GuardError, parseReply, checkReply, libraryReader, guardReply, lastCommits } from './guard.mjs'; + +Merged row286 contribution (d0a6a87cd..02f1c2df6): + +diff --git a/packages/library/src/index.mjs b/packages/library/src/index.mjs +index e9f8c8cae..367cb0d9c 100644 +--- a/packages/library/src/index.mjs ++++ b/packages/library/src/index.mjs +@@ -8,7 +8,7 @@ export { readLibrary, listTree, readTexts, parseFile, parseFrontMatter, headComm + export { renderItems, KINDS, NOTICES, UNREADABLE } from './render.mjs'; + export { survey, formatSurvey, surveyMain } from './survey.mjs'; + export { SYNC_STATE_FILE, mirrorPath, ensureMirror, withLibraryLock, servedCommit, readSyncState, libraryStatus, readLibraryFile } from './mirror.mjs'; +-export { syncCommand, sync, ASKPASS, SLOT, SYNC_INTERVAL_MS } from './sync.mjs'; ++export { syncCommand, sync, push, humanCredential, ASKPASS, SLOT, HUMAN_SLOT, CREDENTIAL_KINDS, SYNC_INTERVAL_MS } from './sync.mjs'; + export { buildIndex, indexFor, clearIndexCache, indexCacheSize } from './index-build.mjs'; + export { sees, find, get, search, manuscript, universeInfo, QUERY_REPLY_CAP, LOOKUP_LIMIT, MANUSCRIPT_LINES } from './query.mjs'; + export { REPLY_LIMITS, resolveReplyLimits, checkReplyLimits } from './limits.mjs'; + + +Overlap conclusions: +- broker.mjs: preserve row217's citation guard/page store, message checks, optional + BusError.reason, role-claim library flag and replyLimits status field. Row286 adds + only LIBRARY_FETCH_FIX and libraryFetchCredential. Its status reads the mirror's + credential through the existing status result, alongside row217's replyLimits. + Row286's inherited comment that BusError carries only a code is now globally stale; + row217 permits reason only for the citation guard. No code/comment rewritten in this + Git-only transplant; fetch refusal behavior is unchanged and its fix stays in timer/README. +- runtime.mjs: preserve guard/replyLimits/last/GuardError wiring and library.limits.set; + retain row286's broker credential choice for verb/timer and refusal fix log. Imports + combine LIBRARY_FETCH_FIX/giteaReference with row217's setReplyLimits. +- library/src/index.mjs: keep row217's limits/guard exports and the earlier query/index + exports; keep row286's expanded sync/push/humanCredential export on its existing line. + +The row286 added/removed product lines compare identically between r3 and r4 for all +nine changed package paths after removing diff metadata/context; only base context moved. +Both row286 test files are byte-identical to the approved r3 files. Other six package +paths in the old manifest have the same blobs; only the three named overlap blobs differ. +The old 16-file candidate is preserved as candidate-r3.sha256; candidate-manifest.sha256 +is regenerated for r4, including this evidence and the range-diff. Shared append logs and +the manifest itself remain excluded as in r3. In-review round 2 waits for CLEAR and reruns. diff --git a/agents/rockerduck/work/queue-286/candidate-manifest.sha256 b/agents/rockerduck/work/queue-286/candidate-manifest.sha256 index 766687554..a646f0af0 100644 --- a/agents/rockerduck/work/queue-286/candidate-manifest.sha256 +++ b/agents/rockerduck/work/queue-286/candidate-manifest.sha256 @@ -1,16 +1,18 @@ 7fab157be380502b726c4a84772bfb667850766062e4952b73f172f5ada363ed agents/ludwig/work/queue-286/BUILD.md -7ce8537c45ab0dc66a6a33c1f0db838506c96e4fe313dc197755aa7aa0dd41cb agents/rockerduck/work/queue-286/BUILD.md +8cc9c6568b4f76b120fe00cb9b6d7e38f8dcf247d4f326bb6d5a766cf7a1f94a agents/rockerduck/work/queue-286/BUILD.md +1698321de2b17251ae3dd55bf3b79e03770d20d932fb60d514ee58700f80fb3b agents/rockerduck/work/queue-286/candidate-r3.sha256 e5026111e3c84f1294c80631fc5d5dad6dc77166209acdfd07c6ea8755469e19 agents/rockerduck/work/queue-286/gate-bus.txt 4e191637baa4d8683679fd6e84d81e29ec6fe64faf38b4b33f9b5965fce1dfcf agents/rockerduck/work/queue-286/gate-library.txt 50291819572752733a1c33e846e1e1e8d66e89b677a6a6d0cc7d2402e8fa82ea agents/rockerduck/work/queue-286/mutant-M1.txt ade72e9641ac5ee97b1ceaa266d54b48d28d0d613f415a030547963664a04646 agents/rockerduck/work/queue-286/mutant-M2.txt +f640bc30c0e07dad11d57f8f00397a76638f5fbc4c71fc56e748f9cb6f4e30e1 agents/rockerduck/work/queue-286/range-diff-r4.txt b3b9a19825a43f33942746bbaaa93670453d4f21b63005d915d9cf92523e9143 agents/rockerduck/work/queue-286/token-search.txt -b6c4c71e83d90a4415337cd5bad93200232ff3a74e0bdc303c1351c2f1a4aae4 packages/bus/src/broker.mjs -a93e322bd27fea2a5fe6a2f89aad04d9cf96b6cc2004dc1c663af5a46494fb09 packages/bus/src/runtime.mjs +f7f8122406b8f3588837ffc7557c6a4a58ddd863810b38cfd1138972c3a89fe2 packages/bus/src/broker.mjs +19f69252b3d0ea8d8098044a4ff7e2a6ba5d4fd7a4995bf0494395ad8a1a065c packages/bus/src/runtime.mjs 44e62c044caf66358c4469cd1549aebadaa1bc22e681e4e2ce1c8e07dae649b4 packages/bus/tests/library-credential.test.mjs d9c523d830c57df9fedf5cb42e6c74999fde529751e8a5eea95b3ae097d8548d packages/library/README.md 5c9b528fd69a2493f04933fc84f352b1101d276d69d9982806975def614fd740 packages/library/bin/askpass -978c7a404baeb52c472948a57a606c0881793c25ee85feef68b681f9ea15fc05 packages/library/src/index.mjs +143cafb4984921f6a6e45adcbb812ac402f2ad146ea58de4a0cb8e7c67a6b002 packages/library/src/index.mjs 0bea0f3553ecfca8bee81e545faf5142e5fa6521ea971fbd2d8a78932d644f2b packages/library/src/mirror.mjs 784af63a417b547b195ca835878daeba5b696b42a83a4c95de6728a0efa75e38 packages/library/src/sync.mjs c8500795d80f56536f0ffd17bcad4f38778d4b06ec39030200c17f31c750ac94 packages/library/tests/sync.test.mjs diff --git a/agents/rockerduck/work/queue-286/candidate-r3.sha256 b/agents/rockerduck/work/queue-286/candidate-r3.sha256 new file mode 100644 index 000000000..766687554 --- /dev/null +++ b/agents/rockerduck/work/queue-286/candidate-r3.sha256 @@ -0,0 +1,16 @@ +7fab157be380502b726c4a84772bfb667850766062e4952b73f172f5ada363ed agents/ludwig/work/queue-286/BUILD.md +7ce8537c45ab0dc66a6a33c1f0db838506c96e4fe313dc197755aa7aa0dd41cb agents/rockerduck/work/queue-286/BUILD.md +e5026111e3c84f1294c80631fc5d5dad6dc77166209acdfd07c6ea8755469e19 agents/rockerduck/work/queue-286/gate-bus.txt +4e191637baa4d8683679fd6e84d81e29ec6fe64faf38b4b33f9b5965fce1dfcf agents/rockerduck/work/queue-286/gate-library.txt +50291819572752733a1c33e846e1e1e8d66e89b677a6a6d0cc7d2402e8fa82ea agents/rockerduck/work/queue-286/mutant-M1.txt +ade72e9641ac5ee97b1ceaa266d54b48d28d0d613f415a030547963664a04646 agents/rockerduck/work/queue-286/mutant-M2.txt +b3b9a19825a43f33942746bbaaa93670453d4f21b63005d915d9cf92523e9143 agents/rockerduck/work/queue-286/token-search.txt +b6c4c71e83d90a4415337cd5bad93200232ff3a74e0bdc303c1351c2f1a4aae4 packages/bus/src/broker.mjs +a93e322bd27fea2a5fe6a2f89aad04d9cf96b6cc2004dc1c663af5a46494fb09 packages/bus/src/runtime.mjs +44e62c044caf66358c4469cd1549aebadaa1bc22e681e4e2ce1c8e07dae649b4 packages/bus/tests/library-credential.test.mjs +d9c523d830c57df9fedf5cb42e6c74999fde529751e8a5eea95b3ae097d8548d packages/library/README.md +5c9b528fd69a2493f04933fc84f352b1101d276d69d9982806975def614fd740 packages/library/bin/askpass +978c7a404baeb52c472948a57a606c0881793c25ee85feef68b681f9ea15fc05 packages/library/src/index.mjs +0bea0f3553ecfca8bee81e545faf5142e5fa6521ea971fbd2d8a78932d644f2b packages/library/src/mirror.mjs +784af63a417b547b195ca835878daeba5b696b42a83a4c95de6728a0efa75e38 packages/library/src/sync.mjs +c8500795d80f56536f0ffd17bcad4f38778d4b06ec39030200c17f31c750ac94 packages/library/tests/sync.test.mjs diff --git a/agents/rockerduck/work/queue-286/range-diff-r4.txt b/agents/rockerduck/work/queue-286/range-diff-r4.txt new file mode 100644 index 000000000..828c87fe4 --- /dev/null +++ b/agents/rockerduck/work/queue-286/range-diff-r4.txt @@ -0,0 +1,69 @@ + 1: 3326d9487 = 1: e6b7abf9b Row 286 C2-03b: build plan and four scope questions (BUILD.md only) + 2: e155e3245 = 2: 764debfe1 Row 286 C2-03b: sage-2922 files-owned extension; Q4 back to Sage (user is the bot fetch identity) + 3: 6ce15eddd = 3: d0d25b04b Row 286 C2-03b: sage-2925 Q4 ruling (humanCredential takes her login; editor.user is row 283's) + 4: c2c4ac679 = 4: 6c99ccc7b Row 286 C2-03b: fold dewey-0860 (Q1 sh fd/inode check, Q2 chief by roles definition, N1-N3) + 5: 8ca442959 = 5: 299d7f50f Row 286 C2-03b: sage-2928 rulings (sh helper, chief by roles definition, departure noted) + 6: cca76fa95 ! 6: a7f274b00 Row 286 C2-03b: library push, per-seat credentials, the chief's fetch credential, askpass fd check (#1791, sage-2922/2925/2928, dewey-0860); unrun + @@ packages/library/src/index.mjs: export { readLibrary, listTree, readTexts, parse + +export { syncCommand, sync, push, humanCredential, ASKPASS, SLOT, HUMAN_SLOT, CREDENTIAL_KINDS, SYNC_INTERVAL_MS } from './sync.mjs'; + export { buildIndex, indexFor, clearIndexCache, indexCacheSize } from './index-build.mjs'; + export { sees, find, get, search, manuscript, universeInfo, QUERY_REPLY_CAP, LOOKUP_LIMIT, MANUSCRIPT_LINES } from './query.mjs'; + + export { REPLY_LIMITS, resolveReplyLimits, checkReplyLimits } from './limits.mjs'; + + ## packages/library/src/mirror.mjs ## + @@ packages/library/src/mirror.mjs: async function readStateHeld(mirror, { branch } = {}) { + 7: bb29ee2d9 = 7: 4488f8ab0 Row 286: library.status shows the credential (webby-0151 R3); fired chief revokes its row as row 281 does; unrun + 8: 90b70a6a6 = 8: 6b731a305 Row 286 C2-03b: fold dewey-0864 (T7/T9 through grants.revoke and instance.fire, race fetch takes the sync guard, two-chief code, id -u shim note) + 9: d037e98d4 = 9: 0d1d99714 Row 286 C2-03b: cite sage-2947 (T7 real verbs, R1 in this row, 285/286 rebase rule) +10: f2a43d69d = 10: 2e2f71e6f Row 286 C2-03b: fold dewey-0869 and sage-2951 (marker-gated busy test, T9 scratch roles with a chief gitea credential, fired-chief path cited) +11: 888548607 = 11: 674f3d638 Row 286 C2-03b: BUILD.md notes for dewey-0869 and sage-2951 (fired-chief path :4308, marker-gated busy test, T9 scratch roles) +12: 7842700fb = 12: fd04dba8b Row 286 C2-03b r2: rebase onto 45dca69f6 (sage-3579). The range-diff is all =. Drift check of the paths the tests read is in BUILD.md. Unrun. +13: 29e830cac ! 13: ed94e24de Row 286 r3: transplant evidence, conflict resolution and static reader drift; untested pending CLEAR + @@ Commit message + Row 286 r3: transplant evidence, conflict resolution and static reader drift; untested pending CLEAR + + ## BUILD-LOG.md ## + -@@ BUILD-LOG.md: remain; no live state, schema or bus policy change. + +@@ BUILD-LOG.md: claim. Receipts and limitations in agents/lena/work/queue-296/BUILD.md and run-r + + 2026-10-24 | Beakley (88b97f65) | Row 217 round 2, sage-4037 | Rebased published dde5b8496 onto e0c6142f3 on new beakley/row217-r2; both append-log histories retained. Conflicts preserve landed grant dispatch, revocation hook and lookup exports. Added E4 citation-unavailable product path and real supporting-scope/index comparison tests after row283 8d2856ee3. Untested: no Node/npm/tests/mutants/build; ready for Sage CLEAR after Lena296. Full range-diff and honest discarded local rebase correction in agents/beakley/work/queue-217/BUILD.md. + + - 2026-10-24 | Goldie | Row265 / #1770 verified (mos-1567, sage-3942) | Approved correction adds solely address import pin + Row265 comment to project-runtime.test and one pure-source RUNNER_FILES mount; new block checks parser has no imports. Serialized fresh-short-TMP timeout-k10: unchanged sandbox10/10, parser15/15, rooms18/18, full bus957/957, twelve named refusal mutants killed (each Node1, driver0), restored parser15/15 + rooms18/18. All positives zero fail/skip/cancel; every mutation restored full broker SHA71b32ee4. Old first-red evidence retained, no other old-test change. Slot returned goldie-0034; Boyd packet explicitly includes mount-list review, candidate push next. + - 2026-10-24T07:18:53Z | Sage | Row 327 (#1825, Bradford, Poe and Dewey) LANDED 68c08b4e7. Before: refactor at 94d9e90a6; the push guard was a scratch script with no reviewed-binary check. After: scripts/push-check.sh and scripts/test-push-check.sh on refactor, 3 commits cherry-picked onto 6a5e12511 with blobs equal to the round 3 tip d858c9f8b, plus doc commits 76f84465f and 68c08b4e7. Binaries are found by numstat or a NUL in the first 8000 committed bytes, regardless of attributes; each needs its sha256 and path in an approved latest-round candidate; an unconfirmed queue tail exits 2. Reviews: Poe c31525 rev 3882, Dewey c31526 rev 3883. Gate: 1st run 06:57Z RED, not the candidate: canonical node_modules was empty from 05:45:15Z (sage-4023). Rerun with its own root npm ci GREEN 07:15:49Z: 17 package suites 0 failures (cli 986, plugins 119, webui 418), 11 scripts exit 0, push-check 6 mutants KILLED; skips are the queue canonical-root check and the row 244 live provider cases. The landed push-check.sh passed its own push (NO_BINARY, NO_ATTRIBUTION, PUSH_READY). mos-1575: gates install their own node_modules; canonical restored with npm ci (128 packages). + + 2026-10-24T10:21Z | Beakley (88b97f65) | Row 217 round2 slot verified, sage-4042/4043 | Source 2d274a5b6: touched57/57, whole library142/142 business270/270 bus974/974 cli988/988 harness172/172 seat218/218, all zero fail/skip/cancel. M1-M5 killed, controls/restored controls green, product hashes restored after each; E4 RED stand-in observed. Only first-red was new runtime fixture invalid-authority, corrected and retained in receipts; no old test failed/edited. Local root/webui npm ci, short TMPDIR, timeout-k10; no canonical npm/rm or module link. Full evidence agents/beakley/work/queue-217/run-r2; Sage owns scripts landing gate and formal review. + + + +- 2026-10-24 (rockerduck, row 286 / #1791, r3 before gate): transplanted Ludwig 45dca69f6..573fa0be0 onto b19ffa04f, preserved newer exports in sole index.mjs conflict; plain-text range-diff, patch IDs and reader/pin drift inventory in agents/rockerduck/work/queue-286/BUILD.md. UNTESTED by sage-4040: no setup or tests until CLEAR. + + @@ agents/rockerduck/work/queue-286/BUILD.md (new) + + ## docs/SESSIONS.md ## + @@ docs/SESSIONS.md: are never rewritten or removed; corrections are new entries. + - 2026-10-24T04:27Z | Goldie (a13dd6d5-5e73-4b7d-8318-02abeff24940) | Row265 / #1770 C2-09b rooms | Goldie owns build, Boyd reviews under sage-3915. New goldie/row265 worktree at ec86f2c84, claim rev3814; room verbs/parser/new tests prepared, no old tests changed. Sage-3932 slot: new parser14/14 and rooms18/18 passed; whole bus in progress before refusal mutants, stop rule active. + - 2026-10-24T04:35Z | Goldie (a13dd6d5-5e73-4b7d-8318-02abeff24940) | Row265 / #1770 verified | First slot stopped at project-runtime import pin. mos-1567 narrowly authorizes pin and pure-source mount correction. sage-3942 rerun: sandbox10/10, parser15/15, rooms18/18, bus957/957, twelve refusal mutants killed/restored SHA71b32ee4, parser15/15 + rooms18/18 again. Slot returned goldie-0034; no further test runs. Boyd reviews RUNNER_FILES alongside rooms; own-branch push/claimant in-review next. + - 2026-10-24T07:18:53Z | Sage (1ef1e4f8) | Row 327 / #1825 push guard landed (mos-1572 option A, mos-1575) | Gate went red 06:57Z on an empty canonical node_modules (Glomgold's webui npm ci through a link to canonical, glomgold-0011); rerun with its own npm ci GREEN 07:15:49Z on 1bd214e38; pushed 68c08b4e7 07:18:03Z; #1825 closed c31530; canonical restored (128 packages); brief template rule 4db23a51f | landed + + 2026-10-24 | Beakley (88b97f65) | Row 217 round 2 under sage-4037 | New beakley/row217-r2 rebased onto e0c6142f3, retained both log histories, E4 product fix and supporting/index tests drafted. No Node/npm/tests/mutants run; ready for CLEAR; local-only dependency installs required on CLEAR, old-test red goes to Sage. + + + + 2026-10-24T10:21Z | Beakley (88b97f65) | Row217 #1718 round2 slot | All touched57 and six whole suites2764 pass, zero skips/cancels; M1-M5 killed/restored, E4 RED stand-in observed. First-new runtime fixture red recorded and corrected; no old-test change/failure. Evidence in agents/beakley/work/queue-217/run-r2. Verified for review on beakley/row217-r2; Sage landing scripts/review remain. + + + +- 2026-10-24 — rockerduck (Codex, a403aa78-b550-4bab-a613-7ea3fd75ec79), row 286 C2-03b / #1791 r3: twelve-commit transplant and static drift evidence prepared; UNTESTED, awaiting Sage CLEAR after own-branch push; no npm/tests run. +14: 4b8261f41 = 14: b7d394928 Row 286 r3: record successful canonical queue start and pre-CLEAR push receipt +15: 2e3a5ddd4 ! 15: 02f1c2df6 Row 286 r3: fix new credential fixtures and record green CLEAR gate with killed mutants + @@ Commit message + Row 286 r3: fix new credential fixtures and record green CLEAR gate with killed mutants + + ## BUILD-LOG.md ## + -@@ BUILD-LOG.md: remain; no live state, schema or bus policy change. + - 2026-10-24T07:18:53Z | Sage | Row 327 (#1825, Bradford, Poe and Dewey) LANDED 68c08b4e7. Before: refactor at 94d9e90a6; the push guard was a scratch script with no reviewed-binary check. After: scripts/push-check.sh and scripts/test-push-check.sh on refactor, 3 commits cherry-picked onto 6a5e12511 with blobs equal to the round 3 tip d858c9f8b, plus doc commits 76f84465f and 68c08b4e7. Binaries are found by numstat or a NUL in the first 8000 committed bytes, regardless of attributes; each needs its sha256 and path in an approved latest-round candidate; an unconfirmed queue tail exits 2. Reviews: Poe c31525 rev 3882, Dewey c31526 rev 3883. Gate: 1st run 06:57Z RED, not the candidate: canonical node_modules was empty from 05:45:15Z (sage-4023). Rerun with its own root npm ci GREEN 07:15:49Z: 17 package suites 0 failures (cli 986, plugins 119, webui 418), 11 scripts exit 0, push-check 6 mutants KILLED; skips are the queue canonical-root check and the row 244 live provider cases. The landed push-check.sh passed its own push (NO_BINARY, NO_ATTRIBUTION, PUSH_READY). mos-1575: gates install their own node_modules; canonical restored with npm ci (128 packages). + +@@ BUILD-LOG.md: claim. Receipts and limitations in agents/lena/work/queue-296/BUILD.md and run-r + + 2026-10-24T10:21Z | Beakley (88b97f65) | Row 217 round2 slot verified, sage-4042/4043 | Source 2d274a5b6: touched57/57, whole library142/142 business270/270 bus974/974 cli988/988 harness172/172 seat218/218, all zero fail/skip/cancel. M1-M5 killed, controls/restored controls green, product hashes restored after each; E4 RED stand-in observed. Only first-red was new runtime fixture invalid-authority, corrected and retained in receipts; no old test failed/edited. Local root/webui npm ci, short TMPDIR, timeout-k10; no canonical npm/rm or module link. Full evidence agents/beakley/work/queue-217/run-r2; Sage owns scripts landing gate and formal review. + + - 2026-10-24 (rockerduck, row 286 / #1791, r3 before gate): transplanted Ludwig 45dca69f6..573fa0be0 onto b19ffa04f, preserved newer exports in sole index.mjs conflict; plain-text range-diff, patch IDs and reader/pin drift inventory in agents/rockerduck/work/queue-286/BUILD.md. UNTESTED by sage-4040: no setup or tests until CLEAR. + + + @@ agents/rockerduck/work/queue-286/token-search.txt (new) + + ## docs/SESSIONS.md ## + @@ docs/SESSIONS.md: are never rewritten or removed; corrections are new entries. + - 2026-10-24T07:18:53Z | Sage (1ef1e4f8) | Row 327 / #1825 push guard landed (mos-1572 option A, mos-1575) | Gate went red 06:57Z on an empty canonical node_modules (Glomgold's webui npm ci through a link to canonical, glomgold-0011); rerun with its own npm ci GREEN 07:15:49Z on 1bd214e38; pushed 68c08b4e7 07:18:03Z; #1825 closed c31530; canonical restored (128 packages); brief template rule 4db23a51f | landed + + 2026-10-24T10:21Z | Beakley (88b97f65) | Row217 #1718 round2 slot | All touched57 and six whole suites2764 pass, zero skips/cancels; M1-M5 killed/restored, E4 RED stand-in observed. First-new runtime fixture red recorded and corrected; no old-test change/failure. Evidence in agents/beakley/work/queue-217/run-r2. Verified for review on beakley/row217-r2; Sage landing scripts/review remain. + + - 2026-10-24 — rockerduck (Codex, a403aa78-b550-4bab-a613-7ea3fd75ec79), row 286 C2-03b / #1791 r3: twelve-commit transplant and static drift evidence prepared; UNTESTED, awaiting Sage CLEAR after own-branch push; no npm/tests run. + + diff --git a/docs/SESSIONS.md b/docs/SESSIONS.md index 327fa7302..3c849cf0b 100644 --- a/docs/SESSIONS.md +++ b/docs/SESSIONS.md @@ -1656,3 +1656,5 @@ are never rewritten or removed; corrections are new entries. - 2026-10-24 — rockerduck (Codex, a403aa78-b550-4bab-a613-7ea3fd75ec79), row 286 C2-03b / #1791 r3: twelve-commit transplant and static drift evidence prepared; UNTESTED, awaiting Sage CLEAR after own-branch push; no npm/tests run. - 2026-10-24 — rockerduck (Codex, a403aa78-b550-4bab-a613-7ea3fd75ec79), row 286 / #1791 r3 CLEAR gate: library 140/140, bus 963/963, both mutants killed/restored, gate-output fixture matches zero; new-test setup fixes only; candidate prepared for Boyd review and Sage landing. + +- 2026-10-24 — rockerduck (a403aa78-b550-4bab-a613-7ea3fd75ec79), row286 / #1791 r4 under sage-4079: new branch from d0a6a87cd, 15 r3 commits transplanted, both append histories retained, product/test patch unchanged apart from newer base context; evidence/manifest regenerated; no setup/tests run, CLEAR pending.