Row 286 r5: rebase onto row285 and seed chief read-grant fixtures under sage-4100

This commit is contained in:
jason.woltje committed 2026-10-24 08:41:17 -05:00
1 parent 0663e87242
commit 045eec61ae
7 files changed
+183 -34

No files matched your search

+2
View File
@@ -5523,3 +5523,5 @@ claim. Receipts and limitations in agents/lena/work/queue-296/BUILD.md and run-r
- 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.
- 2026-10-24 (rockerduck, row286 / #1791, r5 before gate, sage-4097/4100): transplanted r4 onto 1f3d0350f; kept row285 library.write routing and chief write-grant refusal plus both append-log histories. Chief fixture refs added; T7/T9 mint setup now pins real refusal then seeds read-only fixture as explicitly ruled, keeping real revoke/fire assertions. Scratch role declaration mutation removed; range-diff/drift evidence recorded. No r5 tests yet; CLEAR starts after own-branch push.
+60
View File
@@ -1080,3 +1080,63 @@ paths in the old manifest have the same blobs; only the three named overlap blob
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.
## r5 rebase and ruling correction — sage-4097 / sage-4100 (2026-10-24)
Base 1f3d0350f31a93e9868f5242795e9bff1890add2; branch rockerduck/row286-r5.
All 16 r4 commits transplanted; implementation transplant tip 0663e8724. R4 remote
is unchanged. Only conflicts were the two append logs, each resolved by retaining
all current bytes then appending the picked entry; both histories preserved.
Range-diff: git range-diff d0a6a87cd..67e084406 1f3d0350f..0663e8724
Full plain text in range-diff-r5.txt. This precedes the new, separately recorded
fixture setup and evidence commit. Product auto-merged. No row286 production hunk
was rewritten. Row285's library.write ACTIONS/ROUTED entries and its chief refusal
in #giteaRole remain unchanged; this row changes no grant path or executor policy.
Drift check from d0a6a87cd to 1f3d0350f:
- broker.mjs adds routed library.write and refuses STAFF_TO in the write-scoped
Gitea executor. Row286's credential chooser is at a separate hunk; both preserved.
- business.mjs requires a chief gitea ref for a library; vocabulary, role and
instance-settings change creative/chief credential rules. Our raw Broker fixtures
use authority projections rather than validateBusinessDocument, but now explicitly
carry the chief's own giteaReference. The no-chief negative fixture remains absent.
- roles/chief-of-staff.json now declares the real read credential. T9 uses shipped
roles directly; the scratch roles copy and credential-declaration mutation are gone.
- Other changed role files are copied/read by upstream runtime/roles helpers. The
new source/role contracts are exercised by the full bus suite on this base.
- No library source or sync/mirror helper changed between those bases. The sync.test
world() at lines 28-41 uses a minimal library-module context. sync() and mirrorPath()
call checkMapping on the project; neither calls validateBusinessDocument/loadBusiness.
It therefore does not need a chief ref. File remains byte-identical to approved r4.
- T7 revoke/fire helper blocks and every assertion in them remain byte-identical to r4.
T7/T9 existing revoked/fired/status assertions are unchanged; only mint setup changes.
Correction to the earlier sage-2947 no-SQL-mint ruling (and dewey-0864 real-mint
setup), explicitly superseded by sage-4100 to preserve sage-2921:
The chief's legitimate read executor belongs to C2-21 and has not landed. T7/T9 now
first assert the real decision.raise write-grant path refuses gitea-not-declared.
They then seed a fixture read grant using the fake API's actual account/token IDs
and only read:repository/read:user scopes. No exported grant-record insert helper
exists; records use direct Store inserts. The physical token file uses the same
exported giteaKeys.issue -> Credentials.issue writer as the executor, with record
inserts in its commit callback. grant.applied evidence names the chief and permission
read. The seed comment cites sage-4100/C2-21 and explicitly requires replacement by
the real read executor. Real grants.revoke and instance.fire by boss still delete the
row before the fetch refusal; no SQL stages their outcomes. Dewey and Boyd must
confirm this corrected fixture path at round 2.
Fixture changes only in packages/bus/tests/library-credential.test.mjs:
- makeBusiness gets root and gives an existing chief its own store Gitea ref;
world passes its scratch root. The deliberate departure/no-chief case stays absent.
- verbDoc carries the chief's store ref, shared by T7 and T9's runtime projection.
- approveChief setup becomes seedChiefReadGrant as ruled; existing real revoke/fire
bodies remain byte-identical. New setup assertions pin refusal and read-only scopes.
- T9 removes the scratch rolesCopy and uses the shipped roles directory read-only.
No production, schema, role-policy or old-test assertion change.
The withdrawn r4 CLEAR (sage-4083/4084) ran only the two own-worktree npm ci installs
successfully; no tests/mutants/build began. This historical fact corrects no code.
For r5, sage-4097/4100 grants CLEAR after the own-branch push: every touched test
file whole, full library/bus and affected broker mutant. Gate results follow as
new entries; historical r3 logs above are not r5 results.
@@ -1,15 +1,17 @@
7fab157be380502b726c4a84772bfb667850766062e4952b73f172f5ada363ed agents/ludwig/work/queue-286/BUILD.md
8cc9c6568b4f76b120fe00cb9b6d7e38f8dcf247d4f326bb6d5a766cf7a1f94a agents/rockerduck/work/queue-286/BUILD.md
4de1780a7dbfdedfb8606fd12e4d4122735d3bca9308b6b2288690f5fffa2b9f agents/rockerduck/work/queue-286/BUILD.md
1698321de2b17251ae3dd55bf3b79e03770d20d932fb60d514ee58700f80fb3b agents/rockerduck/work/queue-286/candidate-r3.sha256
647776d3f75e00023ce1a1b286ff67a0f7a4958165dcebe24216fb6bde27e610 agents/rockerduck/work/queue-286/candidate-r4.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
a0b7fb45d5bbf213a9a01ddf25c5306f2d280544ed452ced2cf329ab6ac6590d agents/rockerduck/work/queue-286/range-diff-r5.txt
b3b9a19825a43f33942746bbaaa93670453d4f21b63005d915d9cf92523e9143 agents/rockerduck/work/queue-286/token-search.txt
f7f8122406b8f3588837ffc7557c6a4a58ddd863810b38cfd1138972c3a89fe2 packages/bus/src/broker.mjs
9e16ff6225cf5e438b0694e2f2b5831c2750f2d0dfc43c7f2f257d8cdacf9ffd packages/bus/src/broker.mjs
19f69252b3d0ea8d8098044a4ff7e2a6ba5d4fd7a4995bf0494395ad8a1a065c packages/bus/src/runtime.mjs
44e62c044caf66358c4469cd1549aebadaa1bc22e681e4e2ce1c8e07dae649b4 packages/bus/tests/library-credential.test.mjs
693e669a8182c320e028389d55cfeed07504104ffe2b0faf8a8d86e9d6f6ff61 packages/bus/tests/library-credential.test.mjs
d9c523d830c57df9fedf5cb42e6c74999fde529751e8a5eea95b3ae097d8548d packages/library/README.md
5c9b528fd69a2493f04933fc84f352b1101d276d69d9982806975def614fd740 packages/library/bin/askpass
143cafb4984921f6a6e45adcbb812ac402f2ad146ea58de4a0cb8e7c67a6b002 packages/library/src/index.mjs
@@ -0,0 +1,18 @@
7fab157be380502b726c4a84772bfb667850766062e4952b73f172f5ada363ed agents/ludwig/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
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
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,57 @@
1: e6b7abf9b = 1: 228dbf394 Row 286 C2-03b: build plan and four scope questions (BUILD.md only)
2: 764debfe1 = 2: 9875fe01b Row 286 C2-03b: sage-2922 files-owned extension; Q4 back to Sage (user is the bot fetch identity)
3: d0d25b04b = 3: ac713ef82 Row 286 C2-03b: sage-2925 Q4 ruling (humanCredential takes her login; editor.user is row 283's)
4: 6c99ccc7b = 4: c7a789901 Row 286 C2-03b: fold dewey-0860 (Q1 sh fd/inode check, Q2 chief by roles definition, N1-N3)
5: 299d7f50f = 5: f1d6d3aba Row 286 C2-03b: sage-2928 rulings (sh helper, chief by roles definition, departure noted)
6: a7f274b00 = 6: 4b97ce7b2 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
7: 4488f8ab0 = 7: 8fdd496e4 Row 286: library.status shows the credential (webby-0151 R3); fired chief revokes its row as row 281 does; unrun
8: 6b731a305 = 8: 3da343422 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: 0d1d99714 = 9: 735c6598e Row 286 C2-03b: cite sage-2947 (T7 real verbs, R1 in this row, 285/286 rebase rule)
10: 2e2f71e6f = 10: f80482183 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: 674f3d638 = 11: 5221f7d3c 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: fd04dba8b = 12: bd4311eb0 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: ed94e24de ! 13: 64f1ff950 Row 286 r3: transplant evidence, conflict resolution and static reader drift; untested pending CLEAR
@@ Commit message
## BUILD-LOG.md ##
@@ 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-24T12:09:17Z | Magica | Row285 / #1790 r4 C1 diagnostic result | Before: valid landed-base candidate0f6cdc861; first old citation-runtime red. After: mos-1584/sage-4086 full unchanged collection, six suites2950 tests2937pass/12fail/1skip/0cancel; WebUI418 and plugins119 green, all12 script suites exit0, dedicated federation1/1. CLI release300s runner cap interrupted; retained and resolved via unchanged1800s retry224/224 in599.6s. Failures: citation-runtime1, instance-settings2, lifecycle-settings1, launcher1, harnesscreative7. Static root causes/fix classes and r3 parity in agents/magica/work/queue-285/BUILD.md. No source/test edits or fix round/mutants; no final manifest or in-review; owner ruling required.
- 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-24T13:02:03Z | Magica | Row285 / #1790 r4 VERIFIED | Before: C1 collection12 failures. After: approved three data corrections, actual-bound-ref guard, duplicate-before-eligibility hire, data-derived creative equal-service retention/listing with validator first; no old assertion edits. Own fresh128/2 installs, editor-required shortTMP serialized final gate: bus975/975 business282/282 cli988pass/1expectedskip webui418/418 harness172/172 plugins119/119, all12 scripts exit0.13 mutations14 independent checks killed; each SHA256/Git blob restored; restored controls136/136. Case1 doc/test/helper base-identical; N1 deferred. Own r4 candidate for Poe/Webby review, no landing/live action.
+
+- 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-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-24T12:09:17Z | Magica | Row285 r4 C1 collected, HOLD | sage-4080/4085/4086, mos-1584: unchanged0f6cdc861, own installs/editor-required/shortTMP; six suites2950 tests2937pass/12fail/1expectedskip, all12 scripts exit0. Release first300s bound exit124 preserved; unchanged1800s retry224/224 in599.6s. Twelve product failures in5 files, six cause classes traced in BUILD; both instance-settings reds preexist onr3 by identical source/role blobs. No fix round, source/test edits, mutants, commit/push or in-review; Sage takes full picture to Mos.
- 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-24T13:02:03Z | Magica | Row285 r4 verified | mos-1585/1586: source/fixture fixes complete, six whole suites2955 tests2954pass/0fail/1expectedskip/0cancel; all12 scripts exit0;13 mutations14 checks killed and blob-restored; restored controls136/136. Old assertions and Case1 preserved. Evidence agents/magica/work/queue-285/BUILD.md. Own-r4 commit/push/manifest and canonical in-review move authorized next; Poe/Webby reviews 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: b7d394928 = 14: f6ae69cd0 Row 286 r3: record successful canonical queue start and pre-CLEAR push receipt
15: 02f1c2df6 ! 15: c536f3fd6 Row 286 r3: fix new credential fixtures and record green CLEAR gate with killed mutants
@@ Commit message
## BUILD-LOG.md ##
@@ 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-24T13:02:03Z | Magica | Row285 / #1790 r4 VERIFIED | Before: C1 collection12 failures. After: approved three data corrections, actual-bound-ref guard, duplicate-before-eligibility hire, data-derived creative equal-service retention/listing with validator first; no old assertion edits. Own fresh128/2 installs, editor-required shortTMP serialized final gate: bus975/975 business282/282 cli988pass/1expectedskip webui418/418 harness172/172 plugins119/119, all12 scripts exit0.13 mutations14 independent checks killed; each SHA256/Git blob restored; restored controls136/136. Case1 doc/test/helper base-identical; N1 deferred. Own r4 candidate for Poe/Webby review, no landing/live action.
- 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-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-24T13:02:03Z | Magica | Row285 r4 verified | mos-1585/1586: source/fixture fixes complete, six whole suites2955 tests2954pass/0fail/1expectedskip/0cancel; all12 scripts exit0;13 mutations14 checks killed and blob-restored; restored controls136/136. Old assertions and Case1 preserved. Evidence agents/magica/work/queue-285/BUILD.md. Own-r4 commit/push/manifest and canonical in-review move authorized next; Poe/Webby reviews 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.
+
16: 67e084406 = 16: 0663e8724 Row 286 r4: record transplant onto landed row217, hunk comparisons and refreshed untested manifest
+2
View File
@@ -1658,3 +1658,5 @@ are never rewritten or removed; corrections are new entries.
- 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.
- 2026-10-24 — rockerduck (a403aa78-b550-4bab-a613-7ea3fd75ec79), row286 / #1791 r5: rebase onto row285 landing 1f3d0350f, both logs preserved, chief refs and ruled read-mint fixtures prepared; real revoke/fire checks preserved, no product change; pre-gate push next under sage-4097/4100.
+39 -31
View File
@@ -1,10 +1,9 @@
// C2-03b (#1791, design 7.2): the credential the library fetch runs with. The chief's grant store file
// once a chief has Gitea grant evidence, slot library-gitea before that, and a refusal otherwise.
// T7's revoked and fired cases and T9's revoked case run the broker's real paths (dewey-0864): the
// chief's grant through decision.raise and the human's yes against the fake Gitea in fake-gitea-api.mjs
// on 127.0.0.1, then grants.revoke or instance.fire. roles/chief-of-staff.json names no gitea credential,
// so these tests give chief-of-staff one in their own definitions, as gitea-grant.test.mjs gives coder
// one. The choice function's other checks (listed, a fire under way, held, two chiefs, another project)
// sage-4100 corrects sage-2947/dewey-0864 for the mint only: before C2-21, the real write-grant
// path must refuse the chief. T7/T9 assert that refusal, then seed a read-only fake grant. C2-21's
// real chief read executor replaces that seed when it lands. Revocation and fire use the real verbs.
// The choice function's other checks (listed, a fire under way, held, two chiefs, another project)
// use fixtures: the evidence and the gitea_grants row go in by SQL, as gitea-grant.test.mjs does for
// decisions. Tokens are made up or the fake's, and only ever compared.
import test from 'node:test';
@@ -17,14 +16,14 @@ import { randomBytes } from 'node:crypto';
import { Store } from '../src/store.mjs';
import { Broker, GRANT_EVIDENCE, LIBRARY_FETCH_FIX, writeGrantEvent } from '../src/broker.mjs';
import { Credentials } from '../src/credentials.mjs';
import { giteaGrant, giteaKeys, giteaStart } from '../src/gitea-grant.mjs';
import { giteaGrant, giteaKeys, giteaStart, giteaReference } from '../src/gitea-grant.mjs';
import { startBroker } from '../src/runtime.mjs';
import { gitEnv } from '../../seat/src/checkout.mjs';
import { mappingEntry, repo } from '../../library/tests/helpers.mjs';
import * as library from '../../library/src/index.mjs';
import { fakeGiteaApi } from './fake-gitea-api.mjs';
import { grantDecision } from './host-fixtures.mjs';
import { rolesCopy, systemFor } from '../../business/tests/helpers.mjs';
import { systemFor } from '../../business/tests/helpers.mjs';
const AT = '2026-10-22T00:00:00.000Z';
const REV = 'b'.repeat(64);
@@ -44,9 +43,10 @@ async function until(fn, ms = 10000) {
}
}
const makeBusiness = ({ chief = true, instances = null } = {}) => ({
const makeBusiness = ({ root, chief = true, instances = null } = {}) => ({
id: 'acme', human: 'jason', arbiters: { technical: 'coder', delivery: 'coder' },
roles: { ...(chief ? { chief: { definition: 'chief-of-staff', ...role } } : {}), coder: { definition: 'coder', ...role } },
// sage-4097 / mos-1584: the chief's declared read credential; no-chief negative fixture stays absent.
roles: { ...(chief ? { chief: { definition: 'chief-of-staff', ...role, credentials: { gitea: giteaReference(join(root, 'secrets', 'agents'), 'acme', 'chief', '2099-01-01') } } } : {}), coder: { definition: 'coder', ...role } },
projects: { books: { ...mappingEntry(), user: 'books-bot' } },
...(instances ? { launch: { instances } } : {}),
});
@@ -67,7 +67,7 @@ function grant(store, agent, { user = agent + '-bot', project = 'books', row = t
function world(t, options) {
const root = mkdtempSync(join(tmpdir(), 'bus-library-credential-')), store = new Store(root);
t.after(() => { store.close(); rmSync(root, { recursive: true, force: true }); });
const business = makeBusiness(options);
const business = makeBusiness({ ...options, root });
const held = new Set();
const broker = new Broker({ store, businesses: { acme: business }, giteaKeys: { held: (b, a) => held.has(b + '/' + a) } });
return { store, business, broker, held, choose: () => broker.libraryFetchCredential('acme') };
@@ -81,7 +81,8 @@ function verbDoc(url, root) {
id: 'acme', human: 'jason', arbiters: { technical: 'boss', delivery: 'boss' },
roles: {
boss: { definition: 'pm', authority: chiefAuthority },
chief: { definition: 'chief-of-staff', ...none, identity: { name: 'Chief', email: '[email protected]', gitea: { url, user: 'acme-chief' } }, publish: ['app'] },
// sage-4097 / mos-1584: fixture projection carries the chief's own Gitea store reference.
chief: { definition: 'chief-of-staff', ...none, credentials: { gitea: giteaReference(join(root, 'secrets', 'agents'), 'acme', 'chief', '2099-01-01') }, identity: { name: 'Chief', email: '[email protected]', gitea: { url, user: 'acme-chief' } }, publish: ['app'] },
coder: { definition: 'coder', ...none },
},
definitions: {
@@ -148,20 +149,33 @@ async function verbWorld(t, opts = {}) {
broker.request(chief, { verb: 'role.claim' });
const human = broker.bindHuman({ business: 'acme', human: 'jason', via: 'cli', outsideAgent: true });
const events = () => store.all(`SELECT body FROM events WHERE business='acme' AND ${GRANT_EVIDENCE} ORDER BY seq`).map((e) => JSON.parse(e.body));
const ended = (id) => events().findLast((e) => e.grantDecision === id && ['grant.applied', 'grant.failed'].includes(e.action));
const row = () => store.get("SELECT 1 FROM gitea_grants WHERE business='acme' AND agent='chief'");
const approveChief = async () => {
const d = await broker.request(chief, {
const seedChiefReadGrant = async () => {
// sage-4100 / C2-21: the real chief read-grant executor replaces this fixture seed.
// The current executor mints write scopes and must keep refusing the chief (sage-2921).
await assert.rejects(broker.request(chief, {
verb: 'decision.raise',
args: {
action: 'credential.mint', question: 'Grant chief Gitea?', options, recommendation: 'yes', blocking: false,
grant: { method: 'gitea', agent: 'chief', target: { projects: ['app'] }, rotateBy: dayFrom(30) },
},
});
broker.request(human, { verb: 'decision.resolve', args: { id: d.id, choice: 'yes' } });
await until(() => ended(d.id));
await broker.giteaIdle();
assert.equal(ended(d.id).action, 'grant.applied', 'the chief\'s grant landed');
}), { code: 'gitea-not-declared' });
const rotateBy = dayFrom(30), user = 'acme-chief', nonce = randomBytes(8).toString('hex');
const decision = grantDecision(store, { business: 'acme', grant: { method: 'gitea', agent: 'chief', target: { projects: ['app'] }, rotateBy } });
const { user: account } = gitea.addUser(user, { full_name: `Chief [mosaic ${nonce}]` });
const token = gitea.addToken(user, 'mosaic-chief-read-' + decision, ['read:repository', 'read:user']);
assert.deepEqual(token.scopes, ['read:repository', 'read:user'], 'fixture grants read scopes only (sage-4100)');
const keys = giteaKeys({ credentials, storeRoot });
keys.register('acme', 'chief', rotateBy);
// No exported grant-record writer exists; use the executor's credential-file writer and direct
// store inserts for the fixture-only records (sage-4100), with the fake's actual user/token IDs.
keys.issue('acme', 'chief', token.sha1, rotateBy, () => store.transaction(() => {
store.run('INSERT INTO gitea_users(business,agent,user,id,nonce,decision) VALUES(?,?,?,?,?,?)', 'acme', 'chief', user, account.id, nonce, decision);
store.run('INSERT INTO gitea_grants(business,agent,user,token_id,token_name,projects,rotate_by,decision) VALUES(?,?,?,?,?,?,?,?)',
'acme', 'chief', user, token.id, token.name, JSON.stringify(['app']), rotateBy, decision);
writeGrantEvent(store, AT, 'acme', { action: 'grant.applied', method: 'gitea', agent: 'chief', grantDecision: decision, user,
userId: account.id, tokenId: token.id, permission: 'read' }, 'chief');
}));
assert.ok(row(), 'with its gitea_grants row');
};
const revoke = async () => {
@@ -181,7 +195,7 @@ async function verbWorld(t, opts = {}) {
broker.request(chief, { verb: 'role.release' });
broker.request(boss, { verb: 'role.release' });
};
return { gitea, doc, store, broker, storeRoot, row, approveChief, revoke, fire, close, release, choose: () => broker.libraryFetchCredential('acme') };
return { gitea, doc, store, broker, storeRoot, row, seedChiefReadGrant, revoke, fire, close, release, choose: () => broker.libraryFetchCredential('acme') };
}
const REFUSED = { refused: 'library-fetch-no-grant', fix: LIBRARY_FETCH_FIX };
@@ -202,13 +216,13 @@ test('C2-03b T6: the slot before any chief evidence, then the listed chief\'s li
test('C2-03b T7: a chief revoked through grants.revoke or fired through instance.fire refuses, and the fallback stays ended', { timeout: 60000 }, async t => {
const revoked = await verbWorld(t);
assert.deepEqual(revoked.choose(), { kind: 'slot' });
await revoked.approveChief();
await revoked.seedChiefReadGrant();
assert.deepEqual(revoked.choose(), { kind: 'chief', agent: 'chief', user: 'acme-chief' });
await revoked.revoke();
assert.deepEqual(revoked.choose(), REFUSED, 'revoked');
const fired = await verbWorld(t);
await fired.approveChief();
await fired.seedChiefReadGrant();
assert.deepEqual(fired.choose(), { kind: 'chief', agent: 'chief', user: 'acme-chief' });
await fired.fire();
assert.equal(fired.doc.launch.instances.includes('chief'), false, 'delisted');
@@ -263,19 +277,13 @@ test('C2-03b T9 runtime: the chief\'s store file and user, then a real revoke th
const f = repo(t), root = f.root, dataRoot = join(root, 'data');
mkdirSync(dataRoot, { mode: 0o700 });
const storeRoot = join(root, 'secrets', 'agents');
// A scratch roles/ whose chief-of-staff carries a gitea credential, as row 285 ships it
// (case2-rows.md:1823-1824), so the runtime's definitions match the ones the grant ran under
// (dewey-0869). Rebased onto 285, the copy needs no edit.
const rolesDir = rolesCopy(root);
const chiefRole = join(rolesDir, 'chief-of-staff.json');
const chiefDefinition = JSON.parse(readFileSync(chiefRole, 'utf8'));
if (!chiefDefinition.credentials.some(c => c.service === 'gitea')) chiefDefinition.credentials.push({ service: 'gitea' });
writeFileSync(chiefRole, JSON.stringify(chiefDefinition, null, 2) + '\n');
// sage-4100: row285 ships the chief's read declaration; use the real roles without a scratch copy.
const rolesDir = fileURLToPath(new URL('../../../roles', import.meta.url));
const slot = join(root, 'secrets', 'acme', library.SLOT);
mkdirSync(join(root, 'secrets', 'acme'), { recursive: true, mode: 0o700 });
writeFileSync(slot, SLOT_TOKEN + '\n', { mode: 0o600 });
const granted = await verbWorld(t, { dataRoot, storeRoot });
await granted.approveChief();
await granted.seedChiefReadGrant();
granted.release();
granted.close();
const gitea = granted.gitea;