Commit Graph
12 Commits
Author SHA1 Message Date
jason.woltje 2c38325eca row 66: managed sessions run the unslop check on both harnesses, the operator note on the RESULT, a correction notice on the next turn, and unslop.jsonl counts (#1559)
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).
2026-10-21 13:51:28 -05:00
jason.woltje 98d29769e2 bus, cli: tester reads and the W1-W7 tester writes, recorded as tester; scripts/mosaic sends plugins, name and names to the CLI (row 175, #1673)
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.
2026-10-19 19:04:50 -05:00
jason.woltje c216f47dbb plugins, cli, bus, business, webui: harness, model and thinking from the instance vars, a fallback route, and a harness plug-in kind (row 65, #1558)
Adds the harness plug-in kind (interface 1). packages/plugins/harness/pi
and claude-code hold what core branched on: the adapter, thinking levels,
preflight, version probe, sandbox mounts, builtins line, typed tool names,
gate timeout, bundle files, adapter env, turn end and session-files path.
Core reaches a module only through the loader.

A session's route is the instance's harness, model and thinking vars, or
the three fallback. vars; a missing one refuses no-route, and the system
file's execution keys are never read for a session. The launcher checks
the primary route, then the fallback: harness-off, harness-refused,
thinking-unsupported, then preflight. A failed preflight falls back when
a fallback is set, and any refusal of the fallback names the primary's
failure too. Account checks run
only when the route's module counts an account. The manifest records
route, routeReason and harnessVersion, replacing piVersion and
claudeVersion. pi gets --thinking, Claude Code --effort, both from
MOSAIC_THINKING.

The business file refuses a partial fallback. routes and routes.set are
human-only bus verbs outside ORGANIZATION_KEYS; checkRoutes is shared by
routes.set, instances.set and limits.set and checks only changed routes.
The chief of staff changes an instance's model, and the assistant's whole
vars (Q169), through limits.set, so its route write runs the same checks.
A model outside launch.models refuses unknown-model, primary or fallback,
and routes.set passes that code through.
A new run binds only on a switched-on harness module name and records
its transcript path, which the usage reader uses. Settings gains a
Routing table with six selects per instance and loses the Role models
fieldset; it posts changed rows to /api/routes. webui/src/bus.mjs is
unchanged.

Until Jason's `mosaic plugins set` adds "harness": ["claude-code"], a new
launch refuses harness-off.
2026-10-19 11:27:19 -05:00
jason.woltje ca15d73e9f limits: a daily token quota for the account the stack uses, and bus schema 3h to 3i (row 126, #1620)
The business file can name the account claude-code launches use,
`launch.account` = {name, credential}. `name` is an identifier and
`credential` names one login set's environment variables, never a value.
`launch.limits.tokens.daily.<account>` = {limit, since, reset, timeZone}
sets a daily quota for that account. A daily key that isn't the account's
name refuses the business read.

The new plug-in limit-check/daily-quota (interface 2, pure) starts a day at
the first instant at or after `reset` on that local date in `timeZone`. Across
DST that makes a 23- or 25-hour day, and a reset in a skipped hour starts at
the gap's end. It counts the account's known records of all four kinds since
the later of the day start and `since`, and counts unknown turns apart.

The launcher refuses account-credential-missing, account-credential-ambiguous
and account-is-credential (an account name equal to a session credential's
value). Messages name variables, never values. The account rides mayLaunch,
bindLaunch, the usage records, mustStop and the launch record. A pi launch
has no account, records NULL, and no daily quota covers it. `mosaic limits`
and the Console's Settings show one fixed line when a daily row shows:
"Daily quotas count only this stack's own use of the account, not its use
anywhere else."

Bus schema 3h to 3i: 3h reserved usage_records.account as
CHECK (account IS NULL). The new step 3h-3i.sql rebuilds the table in one
transaction, keeping every row's seq and the sqlite_sequence value, and
recreates the three append-only triggers. All of sqlite_master equals 3h's
apart from the account line. A 3h engine refuses a 3i store.
packages/bus/tests/account-migration.test.mjs covers all three, with a
step that fails partway and leaves 3h intact. 3i goes live only through
`stack-release.sh activate ... --migrate` with Jason present (P19 371); the
activate path takes the pre-migrate backup, and the way back is restoring
it (agents/dewey/work/queue-126/MIGRATION.md).

Mos's go mos-0835, six conditions: (1) one transaction, account-migration
test 2 and mutant D29; (2) sqlite_master against 3h, test 1 and mutant D28;
(3) account is never a credential, the launcher's account-is-credential
refusal (launch-account.test.mjs) and the business name pattern
(token-limit-settings.test.mjs); (4) MIGRATION.md, accepted by Mos in
mos-0837; (5) the packet's DESIGN.md "no schema change" line corrected;
(6) the public/ digest below.

The public/ change in bus.js (the daily line under the token-limit table)
carries Mos's decision 123 go mos-0833 on the +/- digest 03e6d9da...ba78,
unchanged at landing.

Owner Dewey, brief docs/plans/2026-10-14_prd-1.2-build.md, "Daily quota for
the credential the stack uses today". Review round 2 rebases the round 4
build onto 1df04f52f (row 167). Reviewer: Filbert approve 29068 on round 1
(manifest d18314f7...8e65); Filbert approve 29080 on
round 2 (manifest f332db76...6fa6).
Seat run on round 2: touched 158/0, singles 1388/0 with 1 esbuild skip,
test-land-work.sh 86/0, 30/30 mutants killed.
Sage gate on 54319f552: GATE_PASSED, 2474+422/0, all 15 packages, the queue
suite and 10 script selftests.

Nothing live.
2026-10-18 20:35:02 -05:00
jason.woltjeandClaude Opus 5.5 aa625565f6 bus, cli, webui: token limits per instance, model, provider and key (row 125, #1619)
Adds token limits under launch.limits.tokens (instances, providers, keys,
models.P.M). Core (packages/bus/src/limits.mjs) reads the organization
file and the per-turn usage records row 124 writes, then asks every
switched-on limit-check plug-in; the first refusal wins. A limit no
switched-on check reports reads "not enforced". The limit-check kind is
interface 2 (mayLaunch, mustStop, report); a v1 check is refused at load.
The shipped token-limit check is pure and counts known end records only;
unknown turns add nothing and are shown as their own count.

The launcher refuses limit-reached through the host's mayLaunch op, or
limit-check-failed naming the check. The broker asks mustStop after a
usage end and stops the run at its next receive or state. Settings stamps
since on a new or changed limit and runs reset; launch.mjs and
business.mjs validate the shape. Readers: mosaic limits and mosaic limits
reset, the bus limits view, the Console /api/bus/limits route and the
Settings token table with Reset. Key limits stay "not enforced" until
row 126 names accounts on records.

Owner Dewey, design under lead decision 150.
Reviewer Filbert: r1 changes (comment 28965), r2 approve (28981), r3
approve (28996) on candidate manifest 8b71c405...fe56 after the rebase
onto row 164 (37 of 38 paths with identical +/- lines, TOOLS.md:621
bracket). Decision 123 go on the bus.js hunk from Mos (mos-0814). Sage
gate on b6827d19e: 25 steps, all rc 0 (15 packages, 10 script suites), 2295 node tests and 422 script selftests, 0 failed, 20:03:25Z to 20:08:08Z, network sage-r125_default removed.

Live stays as pinned. Not part of the 8e7ea89a1 window.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 15:21:49 -05:00
jason.woltjeandClaude Opus 5.5 008746b6ed plugins: channel kind for the CLI and Console chat paths (row 164, #1661)
Adds plugin kind `channel` (interfaceVersion 1, dispatch(request, {call}))
with cli and webui modules. Project and thread surfaces and thread
talk/follow in the CLI and the Console chat go through the selected
channel. An empty or absent channel selection is off: the CLI exits 3 and
the Console answers 503, each naming `mosaic plugins` and `mosaic plugins
set` with the business selector. Management plugins and plugins.set stay
on the core transport. The loader gains a synchronous snapshot(kind)
getter; loaded(), modules() and last-good handling are unchanged. No lock
is held across dispatch. serve.mjs, public/ and the bus are untouched.

Owner Rocko. Reviewer Dewey: r1 changes (comment 28980, B1: the recovery
sentence was never asserted), r2 approve (comment 28984) on candidate
manifest ae2fcfda...1fc8, the B1 assert killing mutant D1. Design accepted
by Mos (mos-0768, mos-0773). Fixture rewrite at project.test.mjs:47 acked
by Mos (mos-0789) on Dewey's line-by-line check: lines 48-51 identical,
one added assert. Sage gate on e5b10d275: 25 steps green, 2081 package tests, 156 queue node tests, 422 script selftests, 0 failed.

Live stays as pinned. The re-pin that takes this live puts `mosaic
plugins set` in Jason's window right after activate (mos-0768).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 14:24:42 -05:00
jason.woltjeandClaude Opus 5.5 70504d23a4 bus, cli, webui: token accounting per run, schema 3h usage_records (row 124, #1618)
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]>
2026-10-18 11:08:17 -05:00
jason.woltjeandClaude Opus 5.5 fba879f6a1 mosaic plugins set: a patch changes only the kinds it names; null removes a kind (vikunja:19/309, row 145)
Jason-approved merge, rebased: git diff f4d7b91a9..0e7d1d8b8 from
work/vikunja-19-309, stacked on 305. Business reviewer verdict dfd44af2
approve on 0e7d1d8b8; Jason resolved merge decision 12a20e47 via the CLI.

No conflict. packages/plugins/README.md, which refactor also changed,
merged with the source commit's +/- lines; the other four paths are the
source blobs. Filbert reviews the rebased diff.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 17:50:59 -05:00
jason.woltjeandClaude Opus 5.5 467a313c7d plugins: mosaic plugins and the plugins verbs switch a module through the human-only path (vikunja:19/305, row 145)
Jason-approved merge, rebased: git diff 813671596..f4d7b91a9 from
work/vikunja-19-305, stacked on 295. Business reviewer verdict 57d7f0b7
approve on f4d7b91a9; Jason resolved merge decision 0eebf83f via the CLI.

Conflict resolution only. packages/bus/src/broker.mjs conflicted with
row 123 (89fd2d6fe): both sides extend the limits branch of request().
Kept row 123's organization.set role path and ORGANIZATION_KEYS, and
added 305's plugins and plugins.set to the verb list and its keys lines.
plugins and plugins.set take the human-only path as in 305: role is true
only for organization.set, the actor is the human, and the verb reaches
the organization writer unchanged. organization.set is unchanged.
packages/plugins/tests/searxng.test.mjs conflicted with 307: both add a
test at the end of the file. Kept 307's AbortSignal test, then 305's
hasModule test. Three other paths that refactor also changed merged
without conflict, with the source commit's +/- lines; the other six
paths are the source blobs. Filbert reviews the rebased diff.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 17:50:59 -05:00
jason.woltjeandClaude Opus 5.5 ae74c25fdd web verbs: grant before the long wait, abort signal to the backend, one query limit (vikunja:19/307, row 145)
Jason-approved merge, rebased: git diff 813671596..6219c5c8c from
work/vikunja-19-307, stacked on 295. Business reviewer verdict 84c9c4be
approve on 6219c5c8c; Jason resolved merge decision 17bb9efc via the CLI.

Conflict resolution only. packages/harness/src/tools.mjs conflicted with
row 132 (0e947c216): both sides add a constant after TASK_PAGE_MAX. Kept
row 132's ORGANIZATION_KEYS, then 307's WEB_QUERY_MAX. Three other paths
that refactor also changed merged without conflict. For each, the +/-
lines on the new base equal the source commit's. The other nine paths are
the source blobs. Filbert reviews the rebased diff.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 17:50:59 -05:00
jason.woltjeandClaude Opus 5.5 e9f4431ec1 harness: web_search and web_fetch as broker-served tools, search-source plug-ins and the assistant's web grant (vikunja:19/295, row 145)
Jason-approved merge, rebased: git diff 07c12b51b..813671596 from
work/vikunja-19-295, its seven commits as one (9ede6935b through
813671596, which include task 296's searxng check). Business reviewer
verdict 51c71b46 approve on 813671596; Jason resolved merge decision
29ff6589 via the CLI.

Conflict resolution only. packages/harness/src/tools.mjs conflicted with
row 132 (0e947c216): both sides add a block after review_verdict. Kept
row 132's end_run and change_organization block, then 295's web_search and
web_fetch block, each with its own closing brace. Seven other paths that
refactor also changed merged without conflict. For each, the +/- lines on
the new base equal the source commit's. The other 20 paths are the
source blobs. Filbert reviews the rebased diff.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-15 17:50:59 -05:00
jason.woltjeandClaude Opus 5.5 eaeb5ebf2b plugins: the plug-in layer, kind registry and loader (row 131, #1626)
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]>
2026-10-15 11:57:54 -05:00