sessions and session_defaults are new and append-only. thread_claims, message_threads and
thread_opens are rebuilt in place with a session column, and thread_claims gains a generation
counted from claim rows. Each existing thread gets a default session with the thread's id; new
threads get a random one. Holder, per-run, release and delivery triggers key on the session,
and two id triggers keep session and thread ids apart (Duckworth checks 1-7, duckworth-0106).
The broker binds a thread run to a session (the default when the record names none), and
thread.open, thread.send and thread.messages take an optional session. New verbs session.list
and session.create (idempotent on op). Tests: sessions.test.mjs for T1 bus half, T2 and T7 with
a pinned 3k fixture; count, version and verb pins; hand-made test threads write the legacy
default session.
Built on row 236 (8f51900b5), which takes 3j-3k, so this step is 3k-3l by landing order
(row264 Q2, sage-2412). The op values are legacy-3l and migration-3l. gitea-migration.test reads
its store after both steps. Not run yet: every run waits for Sage's CLEAR.
Gitea grant executor (steps 0-8, settle, restart, revoke and fire, sweep,
status), the grants.* verbs and mosaic grants, the 3j-3k migration with
gitea_users and gitea_grants, and the section 9 tests with a fake Gitea and
a scratch gitea/gitea:1.27.1 X-G3 test. Build notes in
agents/megavolt/work/queue-236/BUILD.md.
B1: row 200's rollback to a Console without --sso kept the pointer's --send,
which F39 b forbids once --send can sit beside --sso. send_for_target drops it
whenever the run drops the pointer's --sso, and the plan and steps say so.
N1: an ok line with no activation refuses sso-off-flags instead of being
skipped.
activate --send turns send on only when the run's Console flags hold
--sso, given or carried (F39 b), and puts it after --sso and before the
tester flags. activate --no-sso turns --sso off with the Console flags
from the set of the activation that turned it on, drops --send (F39 a)
and keeps the pointer's tester. Both are usage errors under --units
external. T58 covers the brief's T1-T4; the external test covers T5.
Design and the set-walk choice: agents/darkwing/work/queue-273/BUILD.md.
Candidate quackerjack/fed-r5-r5 a74cd9f87 on c3d88840c, manifest of 6
paths (CANDIDATE.sha256). Duckworth APPROVE round 5, rev 3026 (#1700
c30184). C1 gate on Sage's slot by Quackerjack on the merge of a74cd9f87
onto a849d89b7 (3b86180b9), finished 01:56:24Z: cli suite 771/771, skip 0
(run 2; run 1 red on a too-long gate TMPDIR, harness only), every
scripts/test-*.sh rc 0 with Docker up, mutants M1-M13 killed by their
named tests. Landed onto 9c9732983 with the candidate's blobs and modes
for the 6 paths; c3d88840c..9c9732983 touches none of them.
Candidate morgana/row244 94ab4c2fe on a36523713, manifest 6e7e3e3c (8 paths).
Webby APPROVE r1, rev 3008 (webby-0084, REVIEW-r1.md at webby/reviews
ebb3d83bf; request #1757 c30154). Gate on Sage's slot at 81e037d20
(sage-2147): the five gate-lane files whole 51/0, test-task.sh 91/0,
test-release.sh 14/0, mutants M-G, M-L, M-A, M-T and M-F killed.
94ab4c2fe adds only BUILD.md results. Webby's drift check: a36523713..d37210288
changes none of the 8 paths and no path either suite reads; merge-tree clean.
Rulings A and C (sage-1914, sage-2061). The dropped real-model coverage goes
to DEFERRED in the follow-up doc commit.
Lands Sage's sage/row66-r5 at 7ffb640ac, round 4 (r4d 82c830779) rebased onto a36523713 after row 197,
approved by Dewey (comment 30085) and Filbert (30086) on manifest 6cfd812da4ca (23 paths, rev 2905). The
rebase had no conflict. The range-diff is = except one pi-session.test.mjs hunk header. Patch-id without
agents/ is d67275ac4251 on 7b9737953, a36523713 and this commit's parent. Gate (mos-1186): unslop,
harness, cli and every scripts/test-*.sh green on r4d, harness 149/0 again on r5. Landing sessions on a
scratch root from the candidate tree: Claude Code r4ab24630d323 showed the note, the injected notice and
counts checked 2, flagged 1, notices 1. Pi r1dd94171bede is launch only until #383 (Vikunja #454).
Gosalyn's 6d43618a3 (gosalyn/c2-20b), Webby round 1 APPROVE webby-0076 (rev 2852), manifest 6d3f279f692b,
4 paths. Webby's row 221 notes N1, N2 and N4. Slot runs sage-1969 (red base, the builder's comma
regression) and sage-1971 (14/0, M1-M4 killed). M1/M2 sit at :248 in this commit, not :237 as
BUILD.md says (gosalyn-0111). JSON.stringify leaves DEL, C1, U+2028/9 and bidi raw, a known limit
by sage-1964.
Sage gate on 5c6f73ed7 plus these 4 paths (12:10-12:21Z): the test file alone 14/0, cli 680/0,
every scripts/test-*.sh 429/0. f8276c5eb adds only docs/SESSIONS and docs/case2 sheets no test reads.
Lands Gosalyn's round 1 candidate, 8f403d0d4 on gosalyn/c2-20-r2 (48f044ccc plus its BUILD.md, on
62ddc96cc), approved by Webby (webby-0073, REVIEW-r1 a0a00630e, rev 2808). 22 paths, manifest
20f05e3a6ad5. No 221 path changed between 62ddc96cc and this commit's parent. Patch-id dfbb754c6fb4, the
same as 62ddc96cc..8f403d0d4. The two state.db fixtures and auth.json are short text stand-ins.
Webby's N1, N2 and N4 go to the C2-20b follow-up row before Jason's import run. N3 (mutants.py:48
anchor) is in DEFERRED.md. The script itself runs only under Jason's go (design 10 step 6, 9.1).
Evidence: Gosalyn's singles on my slot, 419/0 on 48f044ccc (gosalyn-0104).
Gate on my slot, 11:07:50-11:19Z on b1fece6f0 plus the 22 paths: case2-persona-import.test.mjs alone
11/0, harness 140/0 (bundle.mjs changed), cli 677/0, and every scripts/test-*.sh green (auth 15,
conductor 17, config 31, discord 78, extension-package 18, foundation 44, land-work 86, queue 156 and 28,
release 14, task 98, all 0 failed). Lands before row 197 r7: no shared paths, and r7's proof candidates
both carry it (sage-1954).
Lands Darkwing's manifest round 1 candidate, 37171f65b (base 4ced5e63d), approved by Duckworth
(duckworth-0088, REVIEW-m1 6afcee2a5, #1693 comment 29988, rev 2758). Five paths:
scripts/case1-accept.sh (100755), packages/cli/tests/case1-accept.test.mjs, docs/TOOLS.md,
agents/darkwing/work/queue-195/DESIGN.md (r7, approved duckworth-0087) and BUILD.md. No 195 path changed
between 4ced5e63d and this commit's parent. Patch-id 656e43ff25de, the same as 4ced5e63d..37171f65b.
Evidence: Darkwing's slot runs: single 22/22 (sage-1829), 12/12 mutants killed and gate cli 662/0 plus
selftests 429/0 on ddf7dce6c (sage-1865, sage-1870).
Gate on my slot (sage-r195land, base 38b83ea5c plus 195's 5 and 213's 39 paths, 09:45:52-09:57:52Z): business 200/0, bus 542/0, harness 140/0, cli 663/0; scripts auth 15/0, conductor 17/0, config 31/0, discord 78/0, extension-package 18/0, foundation 44/0, land-work 86/0, queue 156/0 plus 28/0, release 14/0, task 98/0; the models mutant L1 killed (launch-settings 15/1), restore matched.
Between the gate base 38b83ea5c and 4364dddb0 only docs/plans/2026-10-20_host-credentials.md changed (01e1fe512, 4364dddb0), which no test reads.
Duckworth's notes N1-N3 go to docs/plans/DEFERRED.md in the next commit.
Lands Gosalyn's round 3 candidate, a2c72ac95 (commit candidate, base c771a36f4), approved by Webby
(29979, rev 2731). 21 paths: the new packages/library (src, tests, fixtures, package.json, README),
scripts/stack-copy.sh (packages/library/src in COPY_PATHS), packages/cli/tests/stack-copy.test.mjs,
scripts/mosaic and agents/gosalyn/work/queue-212/BUILD.md. The 21-path patch-id, ea84d3e35470, equals
the candidate's.
Evidence: Gosalyn's slot run on round 3: 20 files 451 pass, 0 fail; test-queue 28/0 (gosalyn-0086).
Landing gate (Sage, 08:51-09:03Z, base 4ced5e63d) on a tree that also held row 197's 32 paths:
GATE_PASSED, node tests 981 pass 0 fail (library 39, cli 681, control-board 38, harness 16, webui 51, plus
the scripts/test-*.sh node suites), selftests 429 passed 0 failed. Row 212 lands alone (mos-1162); row
197 waits for an r6 after its lane proof stopped. No 212 path changed between c771a36f4 and this commit's
parent.
`queue review verify-commit 212` -> ok row 212 round 3: a2c72ac95 matches the commit candidate (21 paths).
Lands Launchpad's round 3 candidate, manifest 1bf831f3 (4c90099ea on launchpad/row238-r4, base
c515273db), approved by Webby (29956, rev 2717). Three paths: scripts/stack-release.sh, packages/cli/tests/
stack-release.test.mjs and docs/TOOLS.md. It is row 200's follow-up N1. Round 3 only merges docs/TOOLS.md
onto the row 240 landing: the landed blob plus the one hunk at :599. The 3-path patch-id, b9d0bb0ee3c7,
is the same in all three rounds, and stack-release.sh stays 100755.
Evidence: Launchpad's slot run on round 2, 2afbfbb01: stack-release.test.mjs 196/0 (sage-1794). Sage's
combined gate with row 228 on c515273db plus both rows' paths (07:11:30Z to 07:23:34Z): packages/seat 165 pass, 0 fail; packages/cli 640 pass, 0 fail; all ten scripts/test-*.sh 585 pass, 0 fail (out/, run.log). Row 238's mutant, the sso-config first step dropping --instance NAME, was killed (2 fails), survived: none, and stack-release.sh was restored to its blob.
`queue review verify-commit 238` matches the manifest on all 3 paths. Round 1's N1 stays on the #1744
carry list.
Lands Darkwing's round 1 candidate, manifest 573ece95a4a9 (ad1b23ab2 on darkwing/row240-r3, base
c771a36f4), approved by Filbert (29945, rev 2696). Nine paths: scripts/case1-hostcheck.sh (new),
scripts/case1-pins.sh (new), packages/cli/systemd/mosaic-hostcheck.service (new),
packages/cli/tests/case1-hostcheck.test.mjs (new), scripts/stack-upgrade.sh,
packages/cli/tests/stack-upgrade.test.mjs, docs/guides/host-run-sheet.md, docs/TOOLS.md and
agents/darkwing/work/queue-240/BUILD.md. File modes match the candidate. case1-hostcheck.sh and
stack-upgrade.sh are 100755. case1-pins.sh is 100644, because the host check sources it.
Evidence: Darkwing's first slot run failed one test, the N1 test's after hook (ENOENT once the
fixture had removed its root). The fix b45852daa is test-only. The second run on b45852daa was green:
singles 37/0, mutants M1-M8 8 of 8 killed, cli 639/0, scripts 585/0. Since c771a36f4 no commit
touches the nine paths. Sage's gate on 060a17b54 plus the nine paths (06:45:05Z to 06:56:21Z):
packages/cli 639 pass, 0 fail, and all ten scripts/test-*.sh 585 pass, 0 fail (out/, run.log). `queue review verify-commit 240` matches the manifest on all 9 paths.
Filbert's notes: N1 (the boot unit orders only mosaic-bus@mosaic-stack) and N2 (the run sheet writes
the apt hook before the first --check) are in docs/plans/DEFERRED.md. N3, repeated DRIFT lines after
bwrap is closed, is by design and is noted with N2.
Lands Gizmoduck's round 3 candidate, manifest 4782c8b5ecb7 (c783d5e39 on gizmoduck/row234-r3, one commit
on 57f59e0c3), approved by Duckworth: content on round 1 (861182fa6, 29919), the round 2 rebase check
(29928, rev 2670) and round 3 (REVIEW-r3.md 7c8c38b69, posted 29935, rev 2683). 41 paths.
Round 3 fixes the two failures in Sage's combined gate with row 233: bus schema.test.mjs now counts 18
tables and 71 triggers for the new hosts and host_grants tables, and stack-release.test.mjs T46 puts both
tables in the untimed restore-guard list, since every write shares a transaction with a grant.* event.
Round 3 rebuilt on the row 233 landing as one commit. 38 of the 39 round 2 blobs are unchanged and BUILD.md
is append-only. Gizmoduck's singles on round 3: stack-release 196/0, schema 1/0.
Evidence: Gizmoduck's slot runs, 25 of 25 mutants killed (A22b and A23 included, A9 structural), singles on
r2 387/0 over 47 files. Sage's landing gate on the c783d5e39 tree: 06:02:12Z to 06:15:26Z, every package except queue 2890 pass, 0 fail (15 packages; bus 539, cli 622), and all ten scripts/test-*.sh 585 pass, 0 fail.
This is code only. The live stack runs from a pinned copy at schema 3i. The 3i to 3j migration runs in the
10-24 window (mos-1145), agent-run under Q173, with a backup first. Duckworth's N10 (hosts.mjs
Object.hasOwn) and N12 (doc-only) go to row 235's carry list.
Lands Darkwing's round 1 candidate, manifest 464ce9eb177a (1a1dc80ca on darkwing's branch), approved by
Filbert (29922, rev 2659). Seven paths: scripts/stack-upgrade.sh (new), scripts/stack-release.sh,
docs/guides/host-run-sheet.md (new), docs/TOOLS.md, packages/cli/tests/stack-upgrade.test.mjs (new),
packages/cli/tests/stack-release.test.mjs and agents/darkwing/work/queue-233/BUILD.md.
Evidence: Darkwing's gate on d99166ade (base e65a3ab4d) 1201/0, mutants m1-m8 8 of 8 killed. The N1 fix
08db6ac3f (flock sleep leak in stack-upgrade.test.mjs) reran c0 20/0 with m1 killed (sage-1708); BUILD.md
doesn't record that rerun. Since e65a3ab4d no commit touches the seven paths. Rows 241 and 242 changed bus
and cli files. Only cli tests read the seven paths, so Sage ran the cli suite on 5465fd52d plus the seven
paths: 617 pass, 0 fail (out233/pkg-cli.log, 05:26:33Z to 05:35:00Z). A combined gate with row 234 failed bus schema.test.mjs:522 on 234's new tables, and
Gizmoduck found a second 234 failure (stack-release.test.mjs T46), so Sage stopped it. Row 234 round 3 fixes
both and rebuilds on this landing, since its T46 lines go in a file this commit changes.
Filbert's N1, N4 and N5 go to row 240 (brief b00d7d94d). N2 and N3 are in DEFERRED.md.
Blobs of Darkwing's round 2 da2da2f6c on origin/darkwing/row232-r2 (base
8fede5fc6), the 9 manifest paths, manifest 7af3c943. Round 2 is a
rebase-only round over row 230 (c8bc5cf4c): packages/cli/README.md is a
clean 3-way merge with 232's hunk unchanged, and the other 8 paths keep the
round 1 hashes (manifest 7a3b4ea1). Filbert approve round 1 (comment 29829)
and round 2 (comment 29865).
Under --units user every command line and every byte of output is the
base's. Under external the script reads root's system units, starts and
stops none, stages a copy behind AWAITING-UNITS, and confirm gates root's
start on the bus unit's ActiveEnterTimestamp and launches list.
Mutants 17 of 17 killed (BUILD.md). Darkwing's landing gate on da2da2f6c,
03:07:15Z to 03:17:48Z: packages/cli 593 pass 0 fail, 10 scripts/test-*.sh
suites 429 pass 0 fail (plus 156 node tests in the queue suite). Refactor
moved to 0444acd08 since, three commits touching no manifest path. No live
change: the stack runs from copy 4429a104f, and --units user stays the
default.
Squash of Gosalyn's 96768766c on gosalyn/c2-13a-r2 (base 722136772), the
5 manifest paths, build.patch 56649f9a, manifest fbb0d7e42c67 (Webby
approve round 2, rev 2563). Gosalyn's gate on 96768766c: cli 541 pass
0 fail; scripts/test-*.sh 429 pass 0 fail (summed by script); mutants
10 of 10 killed. packages/cli/README.md is a 3-way merge with row 199
(cb5fdb064): the hunks don't overlap (line 710 vs 1022). host.test.mjs:855
is the only test that reads that file. On cb5fdb064 plus the patch,
case2-unit.test.mjs 30/0 and host.test.mjs 42/0. Refactor moved to
390ea5261 since, a README fix touching no manifest path. The script
runs on a host only in a separate window with Jason's go.
Squash of Megavolt's 627979a17..86963d281 on origin/megavolt/row199-on-190
(base 00d4cc1f6, row 190's landing), the 37 manifest paths, build.patch
05383075, manifest 35f900fd (Duckworth approve round 1, comment 29779,
rev 2540). Mutant batches 1 and 2 in agents/megavolt/work/queue-199/BUILD.md:
batch 2 26 of 28 killed, M17 and M27 equivalent. docs/TOOLS.md is a 3-way
merge with row 200 (9e1085816): row 199's hunk applies unchanged (patch-id
d88379111e2e) and no test reads the file. Gate on 9e1085816 plus the patch:
15 package suites 2735 pass 0 fail, 10 scripts/test-*.sh suites 429 pass
0 fail (plus 156 node tests in the queue suite). Refactor moved to 76134dfde
since, a brief touching no manifest path. No live change: the stack runs from
copy 4429a104f until the 10-24 re-pin window.
Squash of Launchpad's 30e4bb1a3..9df40878f (round 3 on row 190's landing
00d4cc1f6), the 3 manifest paths: scripts/stack-release.sh,
packages/cli/tests/stack-release.test.mjs, docs/TOOLS.md. Manifest
b3ead55c8b48 (Webby approve round 3, rev 2539, comment 29772).
Patch b2a8f5de18b7. Gate on 9df40878f: 15 package suites 2675 pass
0 fail, 10 scripts/test-*.sh suites 429 pass 0 fail (plus 156 node tests
in the queue suite). Mutants 13 of 14 killed, M12 the ruled equivalent
(sage-1446). Refactor moved to 722136772 since the base, touching none of
the 3 paths. No live change: the stack runs from copy 4429a104f until a
re-pin.
Squash of Darkwing's 176a6bf4b..df65a3d4c on origin/darkwing/row190-r3,
the 25 manifest paths, build-r3.patch efe898c2, manifest cc0ea9e8
(Filbert approve round 3, comment 29713). Design revision 3 in
agents/darkwing/work/queue-190/DESIGN.md. Gate on base d0bbc5c1c with
the patch: 15 package suites 2664 pass 0 fail, 10 scripts/test-*.sh
suites 429 pass 0 fail (plus 156 node tests in the queue suite).
Refactor moved to 99a406ed3 since, a window record touching no manifest
path. Mutants 20 of 20 killed (BUILD.md, round 3). No live change: the
stack runs from copy 4429a104f until a re-pin.
Squash of Launchpad's launchpad/row192 53bb59462..37582e820, manifest round 2
6f8cee147713c53652b58d47c5efd15ed47da1efbef6a126464857269b0b7787 (18 paths).
Sage's gate on 088087ac9: package suites 2758 pass 0 fail, scripts/test-*.sh
429 pass 0 fail; mutants 22 of 23 killed, #23 (second origin check) declared
equivalent by Launchpad (sage-1407). New dependency oauth4webapi 3.8.8: the
canonical checkout and any stack copy need npm ci. No live change; the live
re-pin is a window with Mos (mos-1099 item 3).
Row 178 gave the Console --proof-header NAME --proof-file PATH, but on the pinned stack only
activate --tester-port could write a new Console flag into the pointer. A hand install of the pair
would make every later activate, pm-on and rollback refuse unit-flags-drift. activate now takes
the pair, which replaces any pair in the pointer, and --no-proof, which drops it. The pair goes
after the preview flags and before --send and --tester-port, the order webui-service.sh render
writes and flags_drift compares. With neither flag, a target Console that takes --proof-header
carries the pair; a rollback to one that doesn't drops it and says so, and an activate to one
refuses proof-target unless --no-proof is given.
An activate may name the pointer's copy only when it sets a pair or drops one with --no-proof, so
Part B's B3 and its corrected rollback line B-R1 (activate <live copy> --pm --no-proof) can run;
every other activate of the live copy still refuses already-active. Before anything stops, the run
refuses proof-needs-preview, proof-header-invalid (proofOptions' own rules) and proof-file-invalid:
not absolute, a character the unit can't carry, a symlink, missing, not a regular file, inside the
repository or the copies, mode other than 600 or 400, or another owner. The file gets lstat, stat
and realpath only; the script never opens it and no line it writes holds the value. --plan prints
one proof: line. docs/TOOLS.md "Pinned stack update" lists the flags and describes the pair.
stack-release.test.mjs adds T53, eleven subtests. Each ends with a scan of every written file and
output for the proof file's sentinel and an inotify watch that counts no open or read of it. The
five brief mutants and Darkwing's two are killed. Filbert's M8 (a carried pair skips the checks)
and M9 (the repository case dropped) survive T53; both are follow-ups on P19, with a stale comment
in proof_for_target and the stale row 178 paragraph in docs/TOOLS.md.
This is step A0 of mos-0928 Part B and builds the tool only; nothing turns the proof on for the
live Console. Filbert approved round 1 on #1685.
activate --plan printed the backup line whenever the store file existed. But run_steps rolls back
with store-newer or migration-needs-flag before backup_store, so in those two cases the plan said
both that the run rolls back and that it backs up the store. The plan now prints
"backup: none; the run rolls back before the backup" there. The no-store line comes first, since
with no store file the run skips the whole store block. When S_CHANGED is set the plan keeps the
backup line: a wrong backup line costs nothing, a wrong none line hides the directory a --restore
needs. run_steps, backup_store, refusals, exit codes and flags are unchanged; the diff to
stack-release.sh is inside plan only. docs/TOOLS.md "Pinned stack update" step 3 names the
backup line. These are Filbert's N1 and N2 on row 185 (P19 404).
stack-release.test.mjs updates T26's not-given case and adds T52, six activate cases that plan,
check the one backup line and that nothing was written, then run and check the backup exists
exactly when the plan said so. The three brief mutants are killed, and so is Filbert's M7 (an
S_CHANGED read counted as early, by T29). Filbert's M6 (the early test ahead of the no-store test)
survives, since no test plans a missing store with an out-of-chain pointer schema; that is a
bounded follow-up with the store-unclean reading, on P19 404.
Filbert approved round 1 in #1684 comment 29419, with two non-blocking notes.
stack-release.sh activate now backs up the stopped store under its activation id on every run
with a store file, before any migration. Before this, backup_store ran only when the schemas
differed, so a same-schema activate took no backup and rollback --restore had nothing to name.
store-newer and migration-needs-flag still roll back before the backup, since those runs never
touch the store, and a missing store takes no backup.
BACKUP and TAKEN now mean two things. BACKUP is set by every backup, so the log line names it and
from_log backup finds it. TAKEN is set only right before a migration, so a gate failure after a
same-schema activate puts back the units and the wrapper and leaves the store as the failed run
left it. activate --plan prints a backup line, or "backup: none" with no store file. Rollback and
pm-on are unchanged; a same-schema rollback --restore already works through the row 181 guard.
docs/TOOLS.md "Pinned stack update" steps 5-7 say so.
stack-release.test.mjs updates T5, T11, T26 and T29 and adds T47-T51, with one fixture fault
(start-writes-row-<copy>). The three brief mutants are killed, and Filbert's two more (the backup
ahead of the schema checks, the plan line on a rollback) are killed by T6, T9 and T50.
This is the precondition for mos-0928 Part A, the re-pin from 89af38a83.
Filbert approved round 1 in #1683 comment 29404, with two non-blocking notes.
webui serve takes --proof-header NAME --proof-file PATH, only with the --public-host preview flags.
Before listen it reads the file once through O_NOFOLLOW and fstat: a regular file owned by the
Console uid, mode 0400 or 0600, at least 32 base64url bytes with one optional final LF. Any file
problem gives one fixed refusal that names neither the path nor the contents. The header name can't
collide with Host, Origin, auth or tester names.
On a public Host the guard runs before any auth header is read. It needs exactly one proof header
and compares equal-length buffers with timingSafeEqual. Missing, wrong and repeated proofs get the
same fixed 401. A proof header on another Host or on the tester listener gets 403. The existing
auth, Origin, Fetch Metadata and human write checks are unchanged.
webui-service.sh renders both flags and checks the file's metadata and canonical location without
opening it, and the send-status regex accepts the proof pair. stack-release.sh only gains a comment:
it already carries Console flags through re-pin and rollback, and new tests pin that.
This is a partial fix. Same-uid seats can still read the proof file. Activation (middleware, unit
flags, restart, smoke) is a separate Mos-checked window and isn't part of this commit.
Dewey approved round 2 in #1676 comment 29386, candidate 9300a670. Round 1 changes were in 29374.
COUNTED, next to STORE_JS, lists the 11 tables a bus writer fills without an event in the same
transaction (role_claims through usage_records, in schema order). STORE_JS count and heldcount
return events after STAMP plus each listed table after STAMP from the same open as before. A
listed table the store lacks counts 0, and one that exists but can't be read refuses
restore-mismatch.
rollback --restore refuses post-backup-events unless the total is 0 or --events equals it, and
the message names each table with rows. The in-run recount compares the same total. An
events-only store prints the old text. T46 reads every table in schema.sql and fails on a table
in no list or in two.
Filbert approved round 1 in #1679 comment 29372. Follow-ups F1 (task_comment_cursors) and F2
(the refusal text at stack-release.sh:909) are recorded in agents/darkwing/work/queue-181/BUILD.md.
next_activation() takes the UTC second once and tries the base id, then -1 through -9, against
stack-rollback/, backups/stack/ and the post-attempt store, all under the lock. ACT and POST share
the suffix, and with all ten taken it refuses capture-failed with nothing stopped. Adopt uses the
same helper. --restore takes the old and the suffixed form.
Under --plan, a bad --tester-port reports tester-port-invalid through check_refuse and
tester-port-target goes through check_refuse in both modes, so the plan lists every refusal.
Without --plan the output is the usage block, byte for byte as before. webui-service.sh counts the
tester port's digits as written before stripping zeros, so 007333 refuses as serve does.
Round 2 adds subtests C1 (adopt takes the next free id) and C2 (a bad port is usage before any
pointer read) for Dewey's round 1 (#1678 comment 29352). Dewey approved round 2 in comment 29361.
serve --tester-port N starts a second listener on 127.0.0.1:N in the same
process, with a bus caller through TESTER_CLI. N is 1024..65535, not
--port and never 7332, and the flag needs the bus configured. The tester
listener takes only instances.set, routes.set and name.set; settings
save, project-file save, assistant stop, bus message and chat writes
refuse 403 with no bus call. It refuses the main listener's auth header,
and every other listener refuses any request carrying x-mosaic-tester.
/api/config answers tester: true and the page shows a tester banner with
the routes, instances and seat name editors only. tester-off and
tester-required map to 403 in a serve.mjs coreBusStatus wrapper, so
bus.mjs stays pinned (row 164).
The broker lets a tester read credentials (with #secretCheck), routes,
project.files and project.file; project.file.save stays human-only.
webui-service.sh takes --tester-port with serve's checks. stack-release
activate --tester-port N writes the flag to the pointer and the unit,
refuses tester-port-target when the target copy's Console lacks it, and
activate or rollback to such a copy drops the flag and says so in --plan.
docs/TOOLS.md rewords the stale row 175 two-phase step (#1673 F1).
Built by Rocko on 473258a51 (manifest a4c728fc...52c9), approved by Dewey
in round 2 (#1674 comment 29322) after round 1 changes (29309), Sage's
gate green on 473258a51 plus the patch in run 2. Run 1 failed T34's
failed-pm_launched subtest with capture-failed: activate and pm-on name
the activation by the second, so the two ran in one second and collided
on the rollback set. That race is row 169's (the base fails the same way
with the id pinned), and a follow-up row fixes it (Vikunja P19 391).
TESTER_VERBS gains usage, names, limits, plugins, instances, project.list,
thread.list, name.set and project.create. A tester reads limits, plugins
and instances and sends plugins.set, instances.set and routes.set, each
logged with actor tester. The project file verbs refuse a tester
tester-refused. The broker and CLI drop the [mos test]
prefix rule (mos-0872 Q1). The CLI takes --tester on the seven reads and
the W1-W7 write forms and refuses it (exit 4) elsewhere, bus start and
stop included.
project init --tester checks the project area, refuses the area root
itself, binds the tester with one agents read, then commits the layout as
tester (mos-0872 Q2). scripts/mosaic sends plugins, name, names, follow,
threads and thread to packages/cli (sage-1081). The row 164 pins are
untouched.
Built by Dewey on 9e74925c2 (three commits to 989699f7c, manifest
2e30f2a1...29d5f), approved by Filbert in round 3 (#1673 comment 29279),
Sage's gate green on 716ddcf1e plus the patch.
activate ID BUSINESS --pm-after-harness installs the bus without --pm
and writes a pointer with pm false and pmPending true. It refuses
pm-after-harness-target when the target has no harness kind, and
pm-after-harness-set when the business file already sets plugins.harness.
pm-on BUSINESS refuses not-pending and harness-unset, then reinstalls the
bus with --pm on the pointer's copy and runs the full gate. A failure puts
the phase-1 unit back (pm-on-failed, exit 1), or stops both units
(pm-on-down, exit 2).
A plain activate refuses pm-pending. status prints the pending state and
the next step. activate and rollback refuse business-unreadable when the
target's code can't read the business file's plug-ins.
Built by Darkwing on 4b738e2da (patch-id 17a90c4ad795, manifest
c6aaac1f...54af), approved by Filbert (#1666 comment 29263), Sage's gate
green on e7d47c346 plus the patch.
drop_in_override refuses drop-in-override when a unit path, a drop-in
directory or a .conf exists but can't be read, as install_guard in
bus-service.sh would after the stop. A unit path that isn't absolute
refuses too.
plan_store and the rollback --restore event count check is-active again
after reading the store the running bus holds. If the bus stopped
meanwhile, --plan prints "store schema: unknown" with no migration lines,
and rollback refuses restore-mismatch before anything stops.
The gate's copy-check step compares the check's bus line with the copy
this run installed and names both when they differ.
read_units returns 1 when the bus Environment= line or either unit's
ExecStart argv holds a quote or a backslash, so activate and rollback
refuse unit-flags-drift, adopt refuses check-failed and status prints
that it cannot read the units. Nothing parses systemd quoting.
Tests T28 to T31 in packages/cli/tests/stack-release.test.mjs.
`mosaic business instances BUSINESS` reads the role instances, and
`mosaic business instance add|set` writes one add or change through the
broker's new human-only `instances` and `instances.set` verbs. The writer is
packages/business/src/instance-settings.mjs. It takes the caller's revision,
validates the next document, refuses a definition that declares credentials
(organization-credentials-out-of-scope), keeps protected instances as they
are, logs the human as the actor, and says when the running bus needs a
restart. Neither command restarts the bus.
The writer refuses the instance ids human and tester with invalid-request,
because the broker refuses a business whose roles use either name when the
bus starts.
The Console's Settings view shows the instances and, under --send only,
posts to POST /api/instances with the exact Origin and same-origin Fetch
Metadata. A refusal keeps the draft. An answer without the view's shape is
outcome-unknown (503). The page's public/ diff carries the decision 123 go
in mos-0832.
Neither verb is in ORGANIZATION_KEYS, so no agent tool reaches them.
Owner Darkwing, brief in row 165 (#1662). Round 3 rebases round 2 onto
4f45cadc0 (row 156). The public/ +/- digest is 939ecd28...9444, unchanged
at landing. Reviewers on candidate manifest e30b54da...f580: Dewey
approve 29052, Filbert approve 29053. Seat run on 4f45cadc0: 1436/0
singles, 37/37 mutants killed. Sage gate on e8b09735a: GATE_PASSED 25/25,
packages 2282/0, queue node 156/0, script selftests 422/0, 23:59:13Z to
00:05:35Z. Rebased onto 50a57e454 over two SESSIONS-only commits.
Nothing live.
New scripts/stack-release.sh with four verbs. adopt records the running
copy, the unit flags and the store schema in state/stack-active.json; it
stops nothing. activate ID BUSINESS [--pm] [--migrate] stops the units,
checks the stopped store, backs it up, migrates when the target's schema
differs, installs and starts the target, then gates on both units active,
a live bus host whose pid is the bus unit's MainPID with boot ok, Console
/healthz, stack-copy.sh check and one launched journal line. A failed
gate rolls back inside the same run and keeps the attempted store as
bus.post-attempt-<stamp>. rollback [--restore ACT [--events N]] goes back
to the log's previous copy and counts the events written after the
backup. status prints the pointer, the log tail and the copy check.
--plan prints what a run would do and writes nothing; it reads the store
schema from the store the running bus holds, or from a stopped store.
Exit codes: refusal 3, gate failure with rollback 1, rollback failed 2,
usage 4. Nothing is pruned.
stack-copy.sh gets a reachable function split from copy_commit and a
guard so its helpers can be sourced. TOOLS.md "Pinned stack update" and
the cli README pinned-stack paragraph describe the verbs.
Owner Darkwing, brief docs/plans/2026-10-18_stack-release.md (D1).
Reviewer Filbert: r1 approve (comment 28997) on 091693c5, r2 confirm-only
approve (29004) on candidate manifest c213a801...bd15c after row 125
moved the base under TOOLS.md and the cli README. Sage gate on 23622980f:
25 of 25 steps rc=0 on c96a95320 (15 packages + 10 scripts), node pass 2353 fail 0, selftests 422 passed 0 failed, 2026-10-18T20:32:13Z to 20:38:55Z, network sage-r162_default removed, 0 containers.
Nothing live. The 8e7ea89a1 window (repin-8e7ea89a1.md) runs these verbs
on Mos's go with Jason present.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Rocko's round 2 candidate e09313aba4d155a1c5af7bfb227ec397e96c0d57444782cd0b48593102bcc684
(38 paths, base 23533625d), approved by Dewey in #1618 comment 28923 (queue rev 1757).
Packet: agents/rocko/work/queue-124/r2/.
- Schema 3g to 3h: packages/bus/src/migrations/3g-3h.sql adds an append-only
usage_records table; nothing earlier changes. usage_records is in timedTables.
- The transcript usage-source module reads token counts from Pi and Claude
Code session transcripts and follows no symlink.
- `mosaic usage` in the CLI and a read-only usage section in the Console's
Settings (one GET route; 400 on a query string).
Decision 123 go: Mos, mos-0737. Activation (3g to 3h) is a migrating run
with Jason present, in Mos's combined re-pin; landing changes nothing live.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Row 137 round 4, Darkwing's candidate (agents/darkwing/work/queue-137/r4/,
build.patch 0cabe175, manifest 548ee477, 31 paths, base 63c82f1c4).
Filbert approved round 4 (comment 28809) and Dewey approved it (28816)
after round 3 changes (28801, 28805). Darkwing's round 4 ran 9/9 mutant
kills, bus 317, seat 150, land-work 86.
Round 5 is a rebase only (agents/sage/work/queue-137-r5/, build.patch
d6cbaaa8, manifest f73598fe). Row 150 changed docs/TOOLS.md, broker.mjs
and cli/README.md under it. The round 4 patch applied unchanged onto
435d1c616, and with index and @@ lines removed the two patches are
byte-identical. Filbert checked the interdiff (comment 28818).
A landing moves refs/heads/main in <dataRoot>/working/<business>/
<project>.git, never the project root or canonical refactor. The seed now
fetches the root as refs/heads/root and fast-forwards main only when it
is an ancestor, so a landed main survives the next push. Only a
cross-role merge decision lands. Its squash names the real channel:
"via the CLI" for the human, and "as its arbiter, via the broker" for an
arbiter's decision.resolve. Every other class refuses not-authorized
before the human check.
This carries row 139's two items. REQ-LAND-1: a gated merge decision
never lands. REQ-DEC-2: the host land op accepts an arbiter-resolved
merge. land-work's read.mjs stays human-only, and land-work.sh still
accepts only a human CLI resolution.
Sage's landing gate ran on 435d1c616 plus the candidate: 25 steps,
all rc 0 (15 packages, 10 script suites), 20:51:00Z to 20:55:34Z,
network sage-r137_default removed. Cherry-picked onto 5d98fb194, which
added only a docs/SESSIONS.md line.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Row 139 round 2, Dewey's candidate a4c5657f (14 paths) on 5661bd233.
Filbert approved round 2 (comment 28786) after round 1 changes. Dewey's
gate: 14 runs rc 0. Mutants m1-m9 killed. Filbert ran 7 files singly:
0 fail, 0 skipped.
The broker's GATED and the business's GATED_ONLY are now the hard waits.
A cited gated decision goes to the domain arbiter unless it is a hard
wait, which always goes to the human. Under Jason's ruling Q169, a
role.revoke of the assistant is a hard wait. Its end gets past
END_PROTECTED only for the chief of staff, or when the cited decision
was resolved by the human through the CLI. PRD version 1.6 records Q169.
Mos approved the 1.6 text, including the REQ-ROLE-2 sentence on the
chief's end and revoke. scripts/test-land-work.sh adds the not-human
cases for arbiter-resolved merges. land-work's read.mjs is unchanged.
Row 137 lands second, so it carries the gated-merge refusal and the host
land op's arbiter acceptance. Making an end or revoke stop an assistant
run, and configuring the assistant, are row 155 (#1649).
Sage's landing gate ran on 26b78d483 plus the candidate: 25 steps, all rc 0 (15 packages, 10 script suites), 19:23:57Z to 19:28:28Z, network sage-r139_default removed.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Round 2 candidate 7a585aa9606863a0d44a26094b585160914e3d8fd5f13436b56470cd69e6d867
(Rocko, packet fafee2f22), approved by Filbert in comment 28707.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Sage's row 70 round 2 candidate (agents/sage/work/queue-70/r2, manifest
098b9aef...604e), approved by Filbert in comment 28602. Landing gate on
4a34fb0d6 with rows 133 and 70 applied: all 24 suites passed, 0 failed.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The broker stores the highest comment id seen per business and task in an
append-only table, task_comment_cursors. The tasks adapter restores those
ids before its startup reconcile, and the first reconcile reads each
task's comment list even with no cached count, so a comment posted while
the bus was down is found. Cursor rows, snapshots and comment events
commit in one transaction. migrate-schema.mjs takes a stopped store from
3b to 3c offline; the store refuses a 3b database until it runs.
scripts/land-work/read.mjs reads SCHEMA_VERSION from store.mjs.
The live bus is 3b. From this commit on, land-work refuses it with
bus-schema until Mos migrates in the schema window
(agents/sage/work/window-plan/schema-chain-3c-3e.md).
Candidate 87ef1321a1a08be64a20499889fc24b5549b47d6d33abfd86db95f62fb3cb6d0,
Rocko packet agents/rocko/work/queue-49/r1 (ea5e70fa8), base 7b166a0f1.
Filbert approved in 28579 and Darkwing in 28587. Landing gate at
ebbbf62da: 24 suites green, 0 failed. 14 package suites passed 1598
tests (bus 178, tasks 97, business 92, cli 195, webui 112). The 10
script suites passed (land-work 84, queue 156). Follow-ups: P19 tasks 300
(duplicate cursor) and 304 (push a task's cursor only when consider runs
for it).
Co-Authored-By: Claude Opus 5.5 <[email protected]>
packages/plugins holds the kind registry and the loader for in-repo
plug-in modules (REQ-PLUG-1). The first two kinds are usage-source and
limit-check (REQ-LIMIT-4). The business file's plugins key turns modules
on per kind, through plugin-settings.mjs and step 5's write path
(REQ-ROLE-3). A refused load is logged and keeps the kind's old modules.
Any filesystem error other than ENOENT or ENOTDIR refuses as unreadable.
The organization writer validates the bytes it writes as well as the
document. stack-copy ships packages/plugins. Nothing is wired into a
host process yet.
Candidate 466c835f7dce79d20c7ab74c197a52b70e7fdeb0efae0456222dc6d0a633f219,
Dewey packet 80797a539 (round 2), base 0bdd573ff. Filbert approved
round 2 in 28568 and Darkwing in 28570. Landing gate at f7d249634: 24 suites green, 0 failed.
14 package suites passed 1586 tests (plugins 21, business 92,
bus 171, cli 195, webui 112). The 10 script suites passed. Follow-up:
P19 task 293, coded writer refusals.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
launch.max becomes launch.models plus launch.limits (total, providers,
exact provider/model). The launcher re-reads limits on every attempt.
Settings and `mosaic limits` write through one locked, journaled
organization writer. `mosaic limits migrate` is print-only.
Candidate 00b84e311475f97ced0d9a9599fba23a28442971ed15d8d489d9422d84a8812e,
Rocko packet 4b6e50636, Filbert round 2 approve (comment 28542).
Landing gate at 0c56cc2d4: 23 suites green. Decision 123 go from Mos.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Candidate manifest 68c60a79914692f3f6d4923f7bcff41de109ccca33bf6fba687fb88efa24bcac
from Rocko's round 1 packet (a94a943c9), on BASE 72c9ac36c. No
manifest path changed between BASE and the landing target. Filbert
approved round 1 in 28497 with no findings; the TOOLS.md paragraph
break is a doc-only follow-up (decision 137). Sage reran the full gate
at the landing target with the candidate applied and Docker live.
Nothing is installed or restarted; the live switch is Mos's step after
the SetSpark freeze lifts.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Candidate manifest 19ef7133db592787c24fa473357687a5741ccd7823627b970624c930a7611dbc
from Rocko's round 1 packet (a6e4fe747), on BASE 234121b30. No
manifest path changed between BASE and the landing target. The
bus-service.sh drop-in guard now refuses inherited mosaic-.service.d
and service.d drop-ins, the header lists every flag, the unreachable
install-show fakes are gone, and the stack-copy.sh wrapper carries its
copy and lease comments after the line-2 marker. Filbert approved in
28489 with no findings. Sage reran the full gate at the landing target
with the candidate applied.
Co-Authored-By: Claude Opus 5.5 <[email protected]>