- A checkout an earlier launch left for a project the instance may no longer
work in is covered by an empty tmpfs inside the sandbox; the host copy stays.
- The launcher rechecks every prepared project against the reloaded document
after preparation, and the bus's final admission takes the instance and
checks the broker's current unions.
- A project define whose vars changed since boot refuses its copy until the
next start.
- Instance-name collisions are recomputed at each reload from the frozen root
claims and the current project defines; every claimant refuses.
Each root agent an organization does not exclude, and each agent a project
defines, becomes a copy when the organization's bus boots. The root file is
read once, through loadRootAgents, at the cli boot step; the snapshot is fixed
until the next boot. A bound copy joins the organization document's roles and
goes through validateBusinessDocument and checkRoles with the organization's
own credential map. A copy whose role needs a credential service is unbound
and refuses at launch by name and service (credential-unbound); a copy the
organization refuses is copy-refused; every agent in a project whose union
refuses is project-refused, naming the project. A project agent launches
only with its own project's mounts and takes a thread only in its project
(project-agent-elsewhere). Refusal events carry the code alone. The bus's
instances read carries the copies with their running runs, and the Agents
grid shows each copy's real status and reason.
channel-proof re-pins webui bus.mjs for four STATUS entries; no proof or
transport change. packages/business gets the agent-copies.mjs re-export.
Six review findings, one round:
- A selected task-tracker module that fails to load or has no factory refuses boot with tracker-config.
- The expect digest covers the task revision, so archive and unarchive invalidate an old token.
- Position exhaustion and an occupied explicit position refuse task-position-full; no rebalancing yet.
- The store adapter reads roles from the broker's current business document (Broker.taskRoles), so a role added by reload works.
- Only newly requested assignees are checked against live roles; stored ones survive edits, archive and delete.
- Human tasks.create requires a requirement citation (REQ-AREA-N); tasks.edit accepts one.
PRD 1.20 REQ-TASK-1, REQ-PLUG-1, REQ-WS-8. Each organization keeps its
tasks in its own bus through the new task-tracker plug-in kind. The
default module is the built-in store; Vikunja is the optional module
and a Vikunja organization keeps today's path.
- bus schema 3u to 3v (migration 3u-3v.sql): store_tasks, append-only,
one row per write, each citing its events row; seven guard triggers.
- broker: the eight role verbs on the store with the slice 1 field
table checked twice (module, then a before/after field diff); the
person's tasks.create/edit/archive/unarchive/delete as human.input
events; the tasks read returns store rows in board order (group,
position), filtered and paged like tracker rows.
- runtime: each business gets its module at start (organization file
plugin, else vikunja with a tracker entry, else store); a store
business with a Vikunja tracker refuses the boot (tracker-config).
- plugins: task-tracker kind with store and vikunja modules.
- cli: the launcher's tracker flag covers store organizations; trail
prints store writes.
- pins: schema.test counts, the bus migration tests, stack-release #811
and T46 (store_tasks on the always list; COUNTED unchanged),
budget-supervisor accepts 3v.
Rebased onto SYS1 by the lead: SYS1 took 3t-3u, so this step is 3u-3v.
Adds the system-type kind with five modules (coding, creative-writing,
marketing, montage, business-management), an org-level enabled list
validated fail-closed, project selections limited to the org's list,
read verbs, and bus migration 3t-3u. REQ-SYS-2 toolsets are designed and
deferred: they need a role authority contract.
Adding an agent with a store credential on an instance with no
<configDir>/secrets/agents left the bus unable to start
(credential-file): Credentials refuses a missing store root, and only
issue() made it, which needs a running bus. Start now makes the root
(0700) the same way issue() does, only when some reference has
store: true. Credentials' own refusal (credential-store T1) is unchanged,
and a root with loose modes or a symlink still refuses start.
Tests: two new credential-verbs tests; the creation test fails on
483eccb3d with credential-file. All 171 bus test files run one at a
time: 1713 pass, 0 fail.
git mv packages/business -> packages/organization (@mosaic/organization). The
old package stays as one-line re-export shims of each moved module, with
src/business.mjs re-exporting src/organization-config.mjs and src/cli.mjs
forwarding to the moved executable. BusinessError is OrganizationConfigError
(one constructor, name kept BusinessError); OrganizationError stays distinct.
The bus adapter gains organization-context.mjs (busOrganization), with
business.mjs (busBusiness) as the same function.
Import consumers, manifests, the lockfile, scripts/mosaic, stack-copy.sh
COPY_PATHS (both roots), seat sandbox RUNNER_FILES and the copy closure
walker (organization-imports.mjs, both roots required) move to the new path.
v1 serialization, v1 writers and the stage A fixtures are unchanged; the stage
A contract tests stay where they were and pass as before.
readCandidate called readPrdMaterial with the org data root directly, so
prd.submit and the Console PRD draft kept working while project.files refused
the same conflict. It now resolves through recordArgs like the file adapters.
Fixes the P2 from the E2E4 review.
BUILD-LOG.md: append-only union, refactor entries first, then the branch's.
docs/SESSIONS.md: append-only union, refactor entries first, then the branch's.
packages/bus/src/runtime.mjs: keep the organization usage timer and refactor's halted/invalid startup-recovery gate.
packages/harness/src/first-output.mjs: keep the branch's harness-neutral markers; refactor's empty-length rejection moves into the Pi monitor (packages/plugins/harness/pi/model-stream.mjs).
packages/harness/tests/runner.test.mjs: keep refactor's length-continuation cases and the branch's output-policy cases.
packages/plugins/harness/pi/index.mjs: keep the documented GLM limits and the branch's transport-based bundle.
Suites: 6356 pass, 32 fail; all 32 fail identically on both parents
(node_modules symlink EISDIR in pinned-copy and stack copy/release tests,
missing Python jsonschema in two conversation tests).
Review round 1 on 4048e0f60 found two defects.
Startup recovery ran unconditionally. A continuation retry now refuses
while processing is halted, so a broker restart with a waiting
continuation failed with processing-halted. Startup recovery now waits
while processing is halted or invalid, as the periodic pass does;
processing.resume schedules it again.
#continuationStarting matched any launch without an end, so an older
launch whose end was lost (#1851) hid every later run's end. Only the
target's latest lifecycle event counts now.
Both regression tests fail on 4048e0f60 and pass here.
Lifecycle Task 2 (#797). A confirmed new-project selection now becomes a
usable product: the code checkout, the organization mapping, the records
repository with the original intent as the owner's spec commit, the chat
association and the working repository, each journaled as its own receipt
(bootstrap:<plan_digest>:<step>) and recoverable after a kill.
- business: addProject is a private exact-add writer under the existing
organization lock and receipt discipline; hold runs a synchronous check
under that lock; findAddition recovers a prepared receipt. Ordinary
writers still refuse every project change.
- bus: prepareBootstrap and executeBootstrap; activateManagedProject
reloads only a receipt-backed additive root and admits it to the broker
after readiness; request.admission host IPC op for the launcher.
- #800: the bound organization revision and association are re-verified
inside the organization lock at the start of execution; a mismatch
records request-plan-stale and performs no effect.
- cli: trackerFor skips reserved products; the launcher refuses to clone a
product the bus has not admitted.
- seat: initializeWorking seeds the working repository, host-only, with no
work ref or push authority.
- schema: append-only migration 3o to 3p widens the request_events kind
list with bootstrap.stale and bootstrap.completed.
Ruling 1: the bus runtime passes launchSettings a key lineage lookup read
from its own credential records (ids only). A new daily key quota takes the
earliest stored since among the old document's daily key quotas in its key's
lineage, and now only when there is none. A reset still sets now, a
caller-supplied since still refuses, and a quota removed and added back in a
later write is new. A failed or malformed lookup refuses proxy-key-refused; a
write that adds no new daily key quota never calls it.
Ruling 2: every limits refresh updates the remembered orphan set, an empty
set when no daily key quota is left, so a quota removed and added back logs
again. In memory only: a restart is a fresh observation.
Ruling 3: pollSettledAfterTick yields on the real setImmediate, captured at
load, inside its deadline.
Tests: p5-key-lineage (writer move counts 160, reset restarts, lookup
failure, orphan remove and re-add), p5-runtime (exhausted on A, moved to B
through the real runtime, refuses), p5-background (barrier with every timer
mocked), token-limit-settings (earliest, no match, re-add, caller since,
malformed answers, default refusal). READMEs: business, plugins, daily-quota,
cliproxy-queue.
Ruling 1: model records keep a bounded previous list (64 ids, oldest dropped)
of ids that left by rotation, grace expiry or re-issue; a fire removes the
record. A tokens.keys leaf matches and counts every id in the lineage that
holds it. Lineage ids are unique host-wide. An orphaned leaf limits nothing,
logs one value-free line when it becomes orphaned, and the Console usage
view lists it.
Ruling 2: an agent with no model key under a key quota refuses
key-quota-no-model-key, passed through the broker, launcher and stop reason.
Ruling 3: covered by the lineage; no mayLaunch change.
Ruling 4: the usage module receives a frozen { readUsageQueue } only.
Ruling 5: every telemetry fixture wait races a 5 s real-timer deadline.
Commits the 18 product paths of the row 333 R1 repair exactly as the reviewed overlay. Packet hashes: source-tests.patch sha256 a78bc385801b64be270fb9d6e84672c443738a5fce8eb68f7d2a01359a57a770 (40623 bytes), INDEX.json sha256 3eb9b8d10445aa328be3b854385e4792dda2c5712b19d443d485d1b00a18d0f8, changed-source-tests.json sha256 42f770fc3e2384362efd1e416091355c064b6cca22dd40f3b5ef8f7b67e43a52. The committed bytes were checked by applying source-tests.patch to 503b91e56 in a scratch tree and comparing the 18 paths. The approvals are source only: R2 (APPROVE source-only, 2026-10-26 23:32:39Z) and Boyd's first review (APPROVE, source only, 2026-10-27T00:27:55Z), both on HEAD 503b91e56 plus this overlay. No test has run on these bytes yet.
Source-candidate: poe d9a564e6d20f5f0fd75ce45b12cbbf8bb4c9d568\nSource-candidate: magica38ba5762b06716db1dee00d0afec162656488f5c\nValidated321whole-file phase plus whole bus1349/model-proxy100/webui490; final gate tooling checks pending, not landed.
Guard, limits, M11 fence, broker guard/page store/check event, BusError
reason, runtime wiring and the CLI replies verb. No runner work, no tests,
nothing run. BUILD.md lists the rulings, the row 225 contract and what is left.