15 KiB
Row 298 (#1804, Q228): chief-of-staff grant scope
Owner Boyd (48a3ae38), reviewer Dewey. Branch boyd/row298, base 45dca69f6.
Assignment: mos-1496/Q245. Handoff: Megavolt megavolt-0203, local 7a141269c;
cherry-picked as 4de3cec27 (design) and 7cea739de (UNTESTED code).
Brief: docs/plans/2026-10-23_mvp-readiness-rows.md, chief-of-staff grant scope.
Megavolt's original design remains in agents/megavolt/work/queue-298/BUILD.md.
Authority and accepted design
Sage sage-3594, restated in sage-3612: launch.grantScope, lenient read with empty
fallback, strict human-only write. No general organization setter may write it.
Per-method agents/projects or agents/hosts/commands; host-enroll never in scope.
Host command arrays match whole tokens and exact lengths. grants.scope.set
from the human CLI is Approve; no Console page or chief-raised scope change.
Mos mos-1496/1502 requires the same human-shell guard as mosaic access.
The broker closes an in-scope request via scope and writes grant.scope.used;
missing evidence must refuse execution. Narrowing before spend fails
scope-changed. Empty scope ships; only Jason sets the live value (Q188).
No credential files read, no live grants, no deployment, no queue writes. Push only boyd/*, additive commits, no amend/force-push or attribution trailers. Sage owns queue, shared test slot and landing. No Node/tests before CLEAR.
Implementation plan and ledger
Using writing-plans and executing-plans inline; the approved brief and D1-D6 are the spec. This packet is the requested plan/tracking location.
- Read brief, roster, implementation and handoff; register session.
- Bring Megavolt's two commits onto Boyd's branch without changing history.
- Add independent CLI tests in
packages/cli/tests/grants-scope.test.mjs: scope read/set requests; agent-marker rejection before stdin/transport; --tester rejection; missing revision, malformed/empty/oversize input. - Strengthen new business/bus grant-scope tests for exact commands, scope evidence binding, host-enroll exclusion and spent scope-changed.
- On Sage CLEAR, observe targeted failures before fixes; fix inherited implementation using the existing human proof and grant executors.
- Update bus/CLI docs, append BUILD-LOG before/after evidence, manifest.
- On Sage CLEAR run touched suites; record exact results and mutants.
- Commit UNTESTED until verified; push boyd/row298 only when slot permits; report to Sage and Dewey, cc Mos for pushes/blockers. Dewey reviews manifest.
Pre-flight interfaces: business checkGrantScope/grantScopeOf/grantInScope feed the instance writer and broker. Runtime supplies a fresh scope from the org file and routes the human setter to the same organization writer. CLI callFor supplies refuseInsideAgent and humanTransport. The grant executors consume the broker's immutable close/evidence. Tests use scratch files/fake Gitea only.
Review focus: exact argv length, stale scope before spend, forged/missing scope evidence, malformed fallback, and CLI agent ancestry. Tests must cover each.
Static findings before any Boyd Node/test run:
- Handoff introduced commandPrefixes beyond the accepted D2 shape, allowing trailing args. Remove it; only exact command arrays are authorized.
- scope.used carries a digest without validating it, and no org revision. Bind evidence to the canonical scope snapshot and grant/close sequence; preserve historical grants when scope is later changed, recheck at spend.
- Gitea recheck throws inside the spend transaction and rolls back spend on scope-changed. Preserve spend and log failure for that case (D6).
- The optional giteaStart?. assertion always passes when the API is absent; use the real runGiteaGrant entry point. Fake Gitea tokens() does exist.
Existing test changes (mos-1272)
Approved by Mos mos-1510 via Sage sage-3624; edited exactly as approved:
| File | Actual numstat | Reason |
|---|---|---|
| packages/bus/tests/project-runtime.test.mjs | +1 / -1 | Vocabulary import pin adds grantScopeOf and grantInScope. |
Other test work is confined to row 298's new files. No pre-existing CLI tests will change. Record final numstat here before review.
Human proof and organization ownership
CLI: packages/cli/src/cli.mjs callFor runs refuseInsideAgent before constructing
humanTransport, as accessCommand does. The setter takes no --tester flag.
packages/bus/src/human.mjs verifyHuman checks the nonce, CLI path and every
ancestor's markers/argv; bindHuman and #human in broker.mjs require the
business human, via cli, outsideAgent true. Tests will pin this chain's caller
refusal. The scope receipt records by/via/outsideAgent and old/new sha256.
Org file: packages/business/src/organization.mjs regular() requires a regular,
non-symlink file owned by the process uid and not writable by group/other;
write() uses revision checks, locked durable receipts and atomic rename.
The OS owner uid can edit it directly; the agent sandbox does not mount the
user's config (packages/seat/src/sandbox.mjs). This is the existing cooperative
human/process boundary, not a hostile same-uid isolation claim.
Chief enrollment: broker instances.set calls #human and #mayHuman before add/change; credential issue/delete use #requestCredential's human gate. launch.by is an organization-file setting, excluded from general setters; only that chief may auto-approve within scope. Additional chief instances remain on the per-grant human approval path.
Validation
UNTESTED. No Boyd Node/test run yet; waiting for Sage CLEAR. M1: bypass in-scope check. M2: bypass invalid-value fallback. M3: remove human setter guard. M4: drop grant.scope.used. All need named failing tests on gate.
Session correction
The initial SESSIONS entry labels startup 19:13Z; startup was approximately 19:08Z. Message header timestamps in boyd-0001 through 0004 were estimates; use T3's receipt timestamps as authoritative. Subsequent reports use date -u.
Departures from Megavolt 7a141269c (Sage sage-3624)
- Removed commandPrefixes; host scope commands match exact token arrays only.
- grantScope callback now supplies one organization read
{value,revision}. grant.scope.used includes that revision, canonical scope snapshot and digest; #approvedGrant validates the digest, shape, method, agent and close sequence. It uses the immutable snapshot so later narrowing doesn't revoke issued grants. - Gitea scope-changed is caught inside the spend transaction and logs a terminal failure without rolling back its spend. Other recheck failures keep their existing behavior. Host already catches recheck failures after spending.
Additional handoff corrections: replaced optional nonexistent giteaStart with runGiteaGrant; added successful host executor/revoke and enrollment-exclusion coverage; added real runtime writer coverage and independent CLI guard tests.
Sage scheduled push at 19:41Z with MOSAIC_GITEA_CREDENTIAL_FILE unset, then T1 lane B around 19:47Z (after explicit CLEAR), four new files whole and serial, hard stop 20:00Z. Fethry lane A is disjoint. No test was run early. Production corrections are marked UNTESTED under that slot mandate; baseline regression checks against the inherited implementation will run only on CLEAR.
Candidate preparation (before T1)
The three static corrections, CLI/runtime coverage and docs are prepared but
UNTESTED. git diff --check is clean. The approved import-pin edit is exactly
1 addition / 1 deletion. M1-M4 are encoded in mutants.py (not run). No Node,
https git, full suite or webui build has run in Boyd's worktree.
Review package: product/test/documentation files in MANIFEST.sha256, excluding append-only project logs and the preserved predecessor packet. The manifest identifies exact bytes for Dewey; each later product change regenerates it and requires a review delta. Existing tests changed: only project-runtime, 1/1.
Dewey static review dewey-0933
N1: Added a positive control to the malformed-evidence fixture. A valid event must pass scope authorization and reach decision-mismatch on the deliberately absent definition binding; invalid events remain not-authorized. No spend. N2: Additional named mutants cover spend recheck, exact argv length, Gitea spend rollback, launch.by eligibility and accepting any evidence row (results below). N3: At spend only grant scope membership is rechecked, not whether the raising chief is still launch.by. This implements sage-3594 Q5; changing the launcher later does not by itself invalidate a pending scope-approved request. N4: The scope shortcut returns the closed decision view to the chief without sending a separate close message; documented in the bus verb table. N5: grant.scope is logged after the organization file commit in a separate bus transaction. A crash between them leaves durable changes.jsonl as the receipt, as with other organization writers. The setter does not claim cross-store atomicity.
T1 lane B results (sage-3642, 2026-10-23 19:23Z–19:29Z)
TMPDIR: /mnt/storage/scratch/tmp/boyd298-4bzr6fn7. Each whole file ran serially
as timeout -k 10 180 node --test --test-concurrency=1 FILE, TMPDIR set to that
scratch directory. Final restored candidate results:
| Whole file | Pass | Fail | Skip |
|---|---|---|---|
| business/tests/grant-scope.test.mjs | 7 | 0 | 0 |
| bus/tests/grant-scope.test.mjs | 14 | 0 | 0 |
| bus/tests/grant-scope-runtime.test.mjs | 1 | 0 | 0 |
| cli/tests/grants-scope.test.mjs | 4 | 0 | 0 |
| bus/tests/project-runtime.test.mjs | 3 | 0 | 0 |
29/0/0 total. final-1.log through final-5.log hold the final output. The
runtime's reload-needs-restart notice is expected: the fixture's boot document
has fewer credential references than its organization document, as in the
existing instances runtime tests. No credential contents are loaded from the
real user config.
Initial run: business 7/0; bus 13/1 due to Boyd's test typo, an out-of-scope
opts reference in the missing-scope assertion. Corrected only that new-test
line, then bus 14/0 and the remaining files green. Dewey N1 positive control
was added and the whole bus file passed again; final rerun above followed all
mutants. No production code changed during this test window.
Mutants: all whole files, serial, with timeout -k 10 and the same TMPDIR.
mutants.py --sage-clear sage-3642 --logs SCRATCH/review-mutants --deadline 2026-10-23T19:38:00+00:00 restores exact original source after each run.
M1/M2/M3/M4 are brief/Sage mutants; M5–M10 cover review focus and dewey-0933.
Each exited 1 with named assertion failures, no loader/syntax kill.
| Mutant | Change | Pass/fail | Named killer |
|---|---|---|---|
| M1 | skip raise scope check | 11/3 | bus out-of-scope Gitea waits; empty/bad scope waits; host argv exclusion |
| M2 | skip invalid-value fallback | 5/2 | business missing/bad scope fallback; bad file scope fallback |
| M3 | remove #human from scope verb | 13/1 | bus Q3 caller refusals |
| M4 | drop grant.scope.used write | 9/5 | bus Q4 protected evidence assertion; four executor waits also fail |
| M5 | skip scope digest check | 13/1 | bus Q4 bad evidence: decision-mismatch instead of not-authorized |
| M6 | rethrow narrowing, rolling spend back | 13/1 | bus Q5 Gitea spent assertion |
| M7 | same without length check | 6/1 | business Q2 shorter command prefix exclusion |
| M8 | no-op #scopeRecheck | 12/2 | bus Q5 Gitea and host scope-changed outcomes |
| M9 | remove launch.by check | 13/1 | bus Q6 second chief stays open |
| M10 | accept any matched scope evidence row | 13/1 | bus Q4 bad evidence, with positive control |
Mutation log sha256 (under scratch/review-mutants):
55e9973af5fca0088963e2ca11fd81b2fb46dfead813a577c0e0aad2d6269b68 M1.log
abd1b784eff5ae1333a7b47085d3e199cad6d27a00e2584edf0b62417ad4c888 M2.log
1a56085e548d1e244f0f88fe12a45f77c162375880794f9ef88b241ed3a1704d M3.log
9c120f3f7128488edaf8bfd6d41bae712e69e76da4195a0d4dc0e8336b02038f M4.log
1bba88a3752823454acdaa51abde6aad66fdd5488801b4aceda02a3b42c8123d M5.log
a4ce3cacca9f7ea56b8cdfd503c76173a8e4ff1d8a7ec07032c93f0b51aa60d8 M6.log
acecd5afc93d68d96d713f8a9a2dc08351831a0b7360a13b4e30a572ad4167bf M7.log
fce7fa505ccf4f2d4190bd03c209fd19f1cf2770d3ae1246a3bd03697594019e M8.log
a830a7964890dd04a2dcc7a932a1502f1dea06419a1eae6b91a85f7878dc5681 M9.log
38ce3e7f69f6c6ffe10133397465d52538a930a830f76256a8b9280f8df78e4b M10.log
Full touched-package suites and every scripts/test-*.sh remain for Sage's full gate; this CLEAR authorized only the five whole files. Candidate remains marked Untested for the full gate. No queue row has been changed by Boyd.
Dewey final delta review (dewey-0935, 2026-10-23 19:31:55Z)
Dewey reviewed 574ece13c..bcd93dc08 with local git only, no Node: CLEAN, nothing blocks. Verified all 13 manifest entries, exact package-file coverage, project-runtime 1/1, M5-M10 mutation sites, all ten mutation log hashes and counts, named assertion kills without loader/syntax errors, final five logs 29/0/0, and N1-N5 coverage. No production code delta in this review range.
Formal Gitea APPROVE on #1804 and queue record wait on the row 291 hold release and Sage's go. Sage's touched-package and every scripts/test-*.sh gate remains required. Boyd has released lane B and has no running test processes.
Rebase after row 239 (sage-3794)
Current branch: boyd/row298-r2, rebased from published row 298 tip
2fc27bce6bfac2debe9703782bf308132c26b393 onto
833ec1cc8d7c11842efb82e57c1a0b256c8d22d7, which includes row 239 through
e0cb1db2c. Original boyd/row298 remains intact locally and remotely. A new
Boyd branch carries the rebased candidate so no published history is amended
or force-pushed. This section supersedes the original base/branch header for
current candidate work.
Conflicts: only the first Boyd log append in BUILD-LOG.md and
docs/SESSIONS.md conflicted while replaying 574ece13c. For each, verified the
old commit's log started with the merge base bytes, then retained the new
base's complete log bytes and appended only Boyd's suffix (434 and 281 bytes
respectively). Later Boyd appends replayed automatically. No prior entries
were removed or rewritten. Five commits replayed; the third/fourth range-diff
entries differ only in append-log context; package-only range-diff is all =.
The overlapping product files merged automatically: broker.mjs, runtime.mjs
and instance-settings.mjs had no textual conflicts. Inspected their diff
against the new base: only the existing row 298 scope additions remain.
Preserved row 239's injected writer, fire/delete beforeWrite callback, and
commit() passing beforeWrite into writer.write. There is no pre-lock revoke
call in commit(). packages/business/src/organization.mjs is byte-identical
to the new base: beforeWrite still runs inside withLock, after revision and
validation checks; post-revoke errors still carry revoked true. Broker's
row-239 error handling and runtime's lock/revoke wiring remain intact.
Static checks only: package patch range-diff all equal, organization writer unchanged, diff whitespace clean, refreshed 13-file package manifest verifies. The only pre-existing row-298 test change remains project-runtime.test.mjs exactly 1/1 under mos-1510. No test files were changed for this rebase. UNTESTED on the new base: no Node, tests, mutants, builds or queue writes run. Earlier 29/0 and M1-M10 results apply to the old base only. Await Sage CLEAR for whole touched-file reruns; Dewey reviews the new candidate.
Row 321 (#1817) review assignment acknowledged; waiting for Sage's request and Gladstone's pushed docs-only F7/F10 run-sheet candidate.