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]>
Researcher's phase 1 report needs /editor.js and /editor.css route
entries in serve.mjs, and spec/north-star.md doesn't exist. The brief
now owns those two entries only and names
docs/plans/2026-09-27_goals-review.md for the round-trip test.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Decision 96 D track. D1 turns the de352dfaf window scripts and the
release.sh pointer-and-log shape into stack-release.sh adopt, activate,
rollback and status. D2 adds rehearse on a scratch root with launches
disabled and no model calls. A standing staging stack is left to Jason.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
A relaunched merge-gate run has land_work but no message to turn on: the
raising run's poll consumes the approval DECISION. The host writes the
instance's landHolders entries into session.json as landing, and the
runner takes one fixed-template turn per entry before its receive loop.
Row 149's chief-of-staff message stays as the fallback; a second land
gets decision-consumed.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Row 128 round 1, Researcher's candidate (agents/researcher/work/queue-128/,
row128.patch, manifest 9eed6a78, 8 paths, base 0f3eb25ea). Filbert
approved round 1 (comment 28895).
`mosaic project create` and `project list` call project.create and
project.list; `init` and `check` keep their arguments and refusals.
`mosaic threads`, `thread create`, `thread open` and `thread read` cover
the thread verbs, and `mosaic talk --thread` sends thread.send as a
REQUEST and prints only the reply to the sent message. `mosaic follow
--thread` is the same loop without the send. A thread reference is its
id, an id prefix of 8 or more characters, or <project>/<name>; unknown,
short and ambiguous references refuse with exit 2 before any send. Every
verb refuses inside an agent run. There is no default thread, so a plain
`talk assistant` still meets thread-required-use-thread-send.
Acceptance 314 step 1 now creates the project and the assistant thread.
New: packages/cli/src/thread.mjs, packages/cli/tests/thread-cli.test.mjs.
Sage's landing gate ran on 77b1a6e8a plus the candidate: 25 steps, all
rc 0 (15 packages, 10 script suites), 14:44:02Z to 14:48:42Z, network
sage-r128_default removed. The commit sits on 7de8b7270, which adds one
docs/SESSIONS.md line that no test reads.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Answers Darkwing's round 6 review (28884) and Filbert's doc-only
follow-up (28883).
- After docker stop, the rule waits for "no such container" by id,
bounded by the core stop timeout, then rm -f and the same wait; a
container still there refuses exit 1, which the unit retries.
- A name conflict is now only a hand-made container without the store's
labels; it stays exit 3, which the unit does not retry.
- Start order: host.lock, store path, rootless check, leftover rule,
docker run.
- I6 gains two tests: run straight after a stop boots, and a leftover
never removed refuses exit 1.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Answers Darkwing's round 5 review (28880) and Filbert's doc-only
follow-ups (28881).
- connected follows the channel from the wrapper's creation, as a forked
child's does; the entry starts the broker on boot and the notifier on
start, so host.mjs:217 and :244 never wait on a pid line.
- Bus start makes <dataRoot>/bus at 0700 and takes its real path; the
bind source, mosaic.store label, leftover filter and hostStatus all use
it.
- A name conflict refuses with exit 3, names the container and the
client's exit code, gives host.lock back, and removes nothing.
- The host.pids test list names what each test does with the pid.
- I6 gains four lifecycle tests for these.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Answers Darkwing's round 4 review (comment 28877) and Filbert's
doc-only follow-up (28876).
- P: the core container's name is mosaic-core-<16 hex of SHA-256 of the
real path of <dataRoot>/bus>, keyed on the store like writer.lock, so
two data roots with the same business don't collide.
- Q: close() waits CLOSE_TIMEOUT_MS twice (host.mjs:30, 343, 347). The
host passes MOSAIC_CLOSE_TIMEOUT_MS to the entry; the core stop
timeout is two close timeouts plus 5 s (45 s today), used by the
leftover rule's docker stop -t.
- R: {from, pid} start line; connected turns false on the exit line,
client stdout close or exit, or a failed stdin write; host.pids is
null for both forks in containerized mode and adds container; the
pid-signalling host tests stay local, I6 uses docker exec kill.
- Nit: firstReply (129) and ended (148) cited apart from watchChildren
(159-165).
- I6 tests and design section 9 add the slow-notifier leftover, two data
roots, the missing-timeout refusal and connected.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Design section 3 gains "The core container's lifecycle": the fixed name,
labels and --rm; tagged fork lines that carry each fork's replies, kills
and exit codes, so the host's per-child stop, start-failure kill and
watchChildren keep their logic; what the entry does when one fork exits;
the client ending first; SIGTERM; the host dying without closing stdin
(not spiked, I6 measures it); the leftover removal at bus start; and
bus status liveness from the engine instead of the lock's container pid.
B2 now names caps on the entry's engine-relayed stdout. Section 9 and
I6's files and tests carry the new rules. Broker cites move to
0f3eb25ea after row 143; LAUNCH_OPS is process.mjs:5-20.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The 2026-10-14 brief predates rows 121, 142 and 143. This one names the
verbs on the existing broker ops, keeps plain talk asking for a thread
with no default, and targets acceptance 314 steps 1 and 3. Owner moves
to researcher.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Darkwing L (comment 28863): section 3 gains "The host channel, a
boundary change". The bus host starts the core container with
`docker run -i` as its own child; core-entry.mjs forks process.mjs and
notifier-process.mjs with IPC inside it and relays tagged JSON lines over
the client's stdin and stdout. The core container runs with
--log-driver none, since replies carry caps; I6 tests that. The channel
adds no authentication of its own, so it is boundary change B2.
Darkwing M: the registry keeps the docker run client's pid and
startTime, so bindLaunch, runtime.mjs and broker.mjs are unchanged and
I5 changes no file in packages/bus. The human proof's ancestry check
never meets the client, so the mount list carries that boundary and I5
tests that a session can't reach sock/human or sock/relay. recover()
removes the container, kills a leftover client and binds as today.
Darkwing nits: the start check's temp names are patterns from their
writers, five state files, and the git-socket.mjs split across I3, I5
and I6.
Filbert (comment 28864): section 10 states the Console's outbound
reach on the mosaic-console bridge, no wider than today, with the
--network none forwarder as the not-spiked follow-up named on P19 333.
Section 7 says four networks and lists mosaic-console.
Section 11 lists B1 (the Console bind, before I4) and B2 (the host
channel, before I6); I4's and I6's gates name their ruling.
Doc-only: no test reads either file.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Row 143 round 2, Researcher's candidate (agents/researcher/work/queue-143/,
row143.patch aff7cff0, manifest a34136bf, 11 paths, base 8fcd0887e).
Dewey approved round 2 (comment 28862) after round 1's changes (28853).
A human save of spec/north-star.md through project.file.save stores one
notice per pm and cto instance, from _bus in no thread, in its own
transaction after the commit. If the notice can't be stored the save
answers outcome-unknown and the commit stands. pm and cto answer the
chief of staff once, a BLOCK naming each conflict or an INFO beginning
"Accept"; the broker checks a BLOCK's sender, recipient and in_reply_to
notice. The chief's relay that replies to the BLOCK is filed in Jason's
most recently opened assistant thread in the notice's project. With no
such thread the relay is refused and the commit still stands. No other
save, commit or verb sends a notice, and a notice to an unrun role waits
for a claim and launches nobody. No schema change: notices and answers
are messages rows.
Contracts: roles/pm.md and roles/cto.md say how to answer,
roles/chief-of-staff.md says to relay in_reply_to the carrying message,
roles/assistant.md says to tell Jason in its own words that the change
stands. New tests: packages/bus/tests/spec-review.test.mjs and
packages/business/tests/spec-review-contracts.test.mjs.
Sage's landing gate ran on 80a2e442b plus the candidate: 25 steps, all
rc 0 (15 packages, 10 script suites), 13:46:52Z to 13:51:25Z, network
sage-r143_default removed. The commit sits on 970e88bf2, which adds one
docs/SESSIONS.md line that no test reads.
Co-Authored-By: Claude Opus 5.5 <[email protected]>