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]>
The Console binds 0.0.0.0 in its own namespace behind a host-loopback
publish (a decision 107 enforcement change, reach unchanged). It mounts
businesses/ and its other mounts at their host paths, checks bus-host/
against an allowlist, turns the queue panel off, and answers 404 on every
board route. The git socket's bundles and land logs move to git-host/.
recover() still ends leftover runs host-lost. RESOLVED_VIA gets a
human-socket entry, and every container kind gets mount-list and
hardening tests. Spike citations are corrected, and the root case and
two-network setup are marked as not spiked.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Dewey's F5 on comment 28853: nothing tells the chief of staff to relay a
BLOCK or an accept in_reply_to the message that carried it, and the bus
refuses a relay without that link. Row 143's brief now owns one bullet in
roles/chief-of-staff.md.
Dewey's F1: the assistant is the threaded instance, so a plain talk is
refused thread-required-use-thread-send, and no CLI code creates a project
or a thread before row 128. Acceptance 314 adds row 128 to its
prerequisites and a step that creates and opens Jason's assistant thread
in the project.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Row 87, the I1 design. The design turns decisions 105 to 108 into
interfaces: one rootless endpoint named on every call, three images,
two broker listeners with a human-socket via value, a host relay with a
peer-pid check, sessions as hardened containers, file-held tokens,
egress only through an allowlist proxy, and the Console in a container
on the human socket. Every container claim cites spikes S0 to S9 or HP.
Mos ruled on the host-process reading (mos-0657): routes open to a
process under Jason's uid are decision 105's accepted limit; the
other-uid reach to the Console port goes to Jason as P19 333, default a
documented limit, and only I6's limits section waits on it.
The rows file holds the I2 to I6 briefs on the template, each with
owner, reviewers, files, what ships and gate. Doc-only: no test reads
either file.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Dewey 0572: organization.set's instances field only sets the model of an
instance the business file already declares (launch-settings.mjs:46-52),
and business.mjs:130 refuses a launch.instances name the roles don't
declare. The row 149 brief said chief's organization change adds the
merge-gate and security-reviewer instances, and acceptance 314's
before-the-run list repeated it. Both now say Jason adds them by editing
the business file and validates it. Doc-only; no test reads either file.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Filbert's row 135 round 3 note 1: step 8 ran mosaic trail with no
argument, but the CLI takes <task|decision>. The step now lists the
tasks and reads each task's trail, which includes the decisions filed
under it and the spec commit each cites. Doc-only: no test reads
docs/acceptance/314.md.
Co-Authored-By: Claude Opus 5.5 <[email protected]>