Row 286 r4: record transplant onto landed row217, hunk comparisons and refreshed untested manifest

This commit is contained in:
jason.woltje committed 2026-10-24 08:35:11 -05:00
1 parent c536f3fd6d
commit 0663e87242
6 files changed
+653 -4

No files matched your search

+2
View File
@@ -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.
+558
View File
@@ -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 <configDir>/secrets/<business>/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.
@@ -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
@@ -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
@@ -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.
+
+2
View File
@@ -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.