Commit Graph
111 Commits
Author SHA1 Message Date
jason.woltje 3723cc56ec Add mosaic dev fixture init, status and stop
Starts the fixture provider's loopback endpoint for a named dev instance and records it under the data root. Refuses the default instance, a configured proxy, provider credentials in the environment, a non-loopback bind and a second fixture. fixtureLauncherOptions hands the endpoint to the launcher as its session proxy context.
2026-11-07 11:30:44 -06:00
jason.woltje 3456d93af0 Implement organization setup commands 2026-11-07 11:17:31 -06:00
jason.woltje 488431976e Keep launch recovery evidence when broker end is unconfirmed 2026-11-06 23:12:02 -06:00
jason.woltje b48396b68e fix(plugins): provider review fixes, admission binding, alias-safe models, no provider names in core (#1858) 2026-11-06 19:52:57 -06:00
jason.woltje ccccac2ade feat(plugins): model providers as plugin modules, cliproxy catalogue on Routing (#1858) 2026-11-06 19:11:13 -06:00
jason.woltje 08b7db413b fix(harness): move harness-specific output handling into the harness plugins (#1855) 2026-11-06 18:27:58 -06:00
jason.woltje 700259aa38 feat: allow agent launches in dev local owner mode 2026-11-06 12:16:36 -06:00
jason.woltje f12021c6d7 fix: dev local owner mode requires the named instance's data-root marker 2026-11-06 12:10:11 -06:00
jason.woltje b73e55b794 feat: dev-only local owner mode for named loopback instances 2026-11-06 11:23:36 -06:00
jason.woltje f23a998eed fix: close project archive admission races (#797) 2026-11-06 02:54:04 -06:00
jason.woltje 1c33c342bc fix(archive): fence new execution and preserve archived reads (#797) 2026-11-06 01:51:08 -06:00
jason.woltje 3e21d239b3 feat(bus): owner project archive and unarchive (#797)
Jason's owner report 2026-11-06: no way to archive or delete projects.
Archive is the reversible half; delete stays out of scope because project
and run records are write-once evidence.

- project.archive / project.unarchive: human-only (project.create's gate
  minus the tester carve-out; tester, user and agent refused). State is the
  latest row of a new append-only project_archives journal (3s->3t, additive;
  the rows are the audit trail), so projects itself never changes and nothing
  is deleted. Repeats refuse project-already-archived / project-not-archived.
- project.list hides archived projects until {includeArchived:true}, which
  flags each with archived:true; a user still lists granted projects only.
- While archived, thread.create, thread.send, room.open and room.send refuse
  project-archived; every existing record stays readable and unarchive
  restores everything.
- Console: new public/project-archive.js (+css) and project-archive-http.mjs
  routes (chatHTTP's write fence); chat.js gains two one-line hooks,
  index.html one script and one link tag; styling only through the shell's
  .project-archive-control / .project-archived-filter hooks.
- CLI: mosaic project archive|unarchive <name-or-id> and list --archived.
- stack-release COUNTED/LISTED gain project_archives (schema order); schema
  step-count pins and migration fixtures updated for 3t.

bus 1601/1601 (Node 24; Node 26 has the pre-existing project-file socket
stall), webui 582/582, plugins 132/132, cli 1191/1194 (two pre-existing
load flakes of the row253 C4 and land_work families; both pass isolated and
the base commit's full suite fails four of the same family).
2026-11-05 23:50:51 -06:00
jason.woltje 647626bdd1 feat(bus): resume product requests through typed role continuations (#1839) 2026-11-04 12:18:10 -06:00
jason.woltje b5a58b48b4 feat(tasks): bind requirement and git admission to product scope (#1839) 2026-11-04 11:24:39 -06:00
jason.woltje c558498062 feat(bus): bootstrap a confirmed new project and admit it at runtime (#1839)
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.
2026-11-03 19:50:32 -06:00
jason.woltje b8f01a189f fix(row 332 R2): proxy first check gates the route the final check picks (Vikunja #774)
Route selection moves into one helper, pickRoute(proxyOf), that both checks call: the
primary preflight, and the fallback with its own preflight only when the primary's
fails, with the same messages. The final check passes proxyFor and is otherwise
unchanged. The first check of a proxy launch passes a stand-in session proxy (marker
key PENDING_ADMISSION_KEY and the configured loopback base URL), which reaches only
the preflights, then runs gate() with a null session proxy on the predicted route only.
The round 1 union over both routes is gone.

The managed fixture takes extra (more harnesses switched on), real (harnesses loaded
unfaked) and hostEnv. Seven tests in proxy-launch-order.test.mjs.
2026-11-02 21:37:48 -06:00
jason.woltje 85ecdfbde5 fix(row 332): proxy first check runs every key-independent refusal; testProxy test option (Vikunja #774)
F1: with system.proxy set, the first launcher check no longer returns
before the account, sandbox, capacity and limit checks. It skips only the
harness preflight and the session proxy key match, which need the key P2
admits in startLocked. A launch that can never start now refuses before
authorizeLaunch, the workspace and checkouts, and modelPreflight. The first
proxy pass accepts only credential "proxy" for a declared account, tries
the fallback model when the primary refuses, and lets mayLaunch
key-quota-no-model-key through so P2 can issue the first key. The final
check is unchanged and still runs before newRun and spawn.

F4: the proxy test option is renamed testProxy and createLauncher throws
test-proxy-refused when it is given with system.proxy.
launch-account.test.mjs is a second caller, so the option stays.

Tests: proxy-launch-order.test.mjs (6), launcher.test.mjs F4 throw test;
the managed launch fixture gains bwrap, admit and trace.ops.
2026-11-02 20:51:51 -06:00
jason.woltje d6dc04e84f Join P3 harness context to landed P2 admission with private same-key delivery 2026-10-26 18:02:58 -05:00
jason.woltje 362893d043 feat: integrate reviewed proxy page and managed model keys
Source-candidate: poe d9a564e6d20f5f0fd75ce45b12cbbf8bb4c9d568\nSource-candidate: magica38ba5762b06716db1dee00d0afec162656488f5c\nValidated321whole-file phase plus whole bus1349/model-proxy100/webui490; final gate tooling checks pending, not landed.
2026-10-26 12:04:21 -05:00
jason.woltje 94cde633e2 WIP row329: preserve P1 draft before required base rebase (#1827) 2026-10-24 18:30:11 -05:00
jason.woltje a41cfd491e row224: draft broker library lookups and typed tools (unrun) 2026-10-24 14:19:17 -05:00
jason.woltje a1b72432cd launchpad: row 217 C2-06 work in progress, UNTESTED, handed to Beakley (mos-1500)
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.
2026-10-24 05:39:16 -05:00
jason.woltje 7e59ba8b3d feat(business): allow businesses without a tracker (#1820) 2026-10-23 18:43:08 -05:00
jason.woltje 156e5c6040 row 298 (#1804): UNTESTED handoff to Boyd (mos-1502). launch.grantScope shape, fallback and match (vocabulary.mjs), the one writer (instance-settings grantScope), broker grants.scope/grants.scope.set gated by #human alone, in-scope close via 'scope' with grant.scope.used, scope-changed recheck, cli grants scope|scope set, business and bus tests. No node run; project-runtime.test.mjs import pin not yet updated; docs and BUILD.md not updated 2026-10-23 17:40:10 -05:00
jason.woltje 712a084124 row 239 (#1745) b1: the fire's and the delete's revoke runs inside writer.write under the lock, after the revision check and the validations; an error after it carries revoked and the bus names it revision-conflict-revoked or outcome-unknown-revoked, with CLI, Console (OPEN, duckworth-0165 C1) and fire-notice texts; the mark sits in a catch around withLock (C2); tests T1-T6, channel-proof re-pins transport.mjs and webui bus.mjs; BUILD.md with mutants M1-M3g and the gate plan; untested, waits for a CLEAR (sage-2792) 2026-10-23 17:00:42 -05:00
jason.woltje 24672fd9d6 row 252: Console inbox Approve and Deny for grant requests, human-only through a console owner proof, confirmation then resolve, via console with human.input before the executor (#1753, Webby N1-N5); tests not yet run 2026-10-23 12:25:39 -05:00
jason.woltje dbbda25373 gizmoduck: row 307 (#1814, Vikunja 598) harness kind gains compactions: pi's stream scan and Claude-history check move to packages/plugins/harness/pi/compactions.mjs, claude-code answers harness-unsupported, core keeps the ledger and checks each answer, readLedger reads the reason only, the launcher passes the loaded module; four old-test edits under mos-1459 2026-10-23 09:37:50 -05:00
jason.woltje 70651f45d8 row 272: retain session recovery state on invalid selection 2026-10-23 08:53:07 -05:00
jason.woltje 490f45f024 row 272: preserve untested session CLI and Console draft (sage-3145) 2026-10-23 08:53:07 -05:00
Rocko 049214486b wip: publish unverified row 219 inspection candidate
Preserve the draft for inspection under sage-3113. Tests and mutants have not run. Old-test adaptations approved in mos-1316 and mos-1317 are recorded in OLD-TEST-CHANGES.md.
2026-10-23 05:37:43 -05:00
jason.woltje 0c8f12ea20 morgana: row 295 r2 rebase on 80793d824 (sage-3256): accessFor comment is stamp-cached (dewey-0871 N3); BUILD.md rebase note 2026-10-23 05:06:14 -05:00
jason.woltje 24f8f5d739 morgana: row 295 r2: wrap the launcher's revoked comment (dewey-0874 nit) 2026-10-23 05:06:14 -05:00
jason.woltje 31da9dcb85 morgana: row 295 r2 (dewey-0871): threadsState ends an expired grant's held claim from the cached read by access-expiry (B1, D7, M16, M11 claim row); access.reload scope as D8 (N1); bus README access.reload, revoked and revocation (N2); tests unrun 2026-10-23 05:06:14 -05:00
jason.woltje ff54a15563 morgana: row 295 FED R4 revocation (#1801): 30 s access timer, access.reload, one-transaction claim end on a loss, threadsState revoked, launcher SIGTERM and no start, CLI reload after grant/revoke; tests unrun (no CLEAR yet) 2026-10-23 05:06:14 -05:00
jason.woltje 52d2a16109 launchpad: row 294 rulings sage-3153 (boot refusal line, owner transport seam G9, C7 follow-up, access.test.mjs unchanged; unrun, #1800) 2026-10-23 01:37:03 -05:00
jason.woltje afef0ea887 launchpad: row 294 FED R6 build and plan, granted-user sign-in (unrun, #1800)
Console granted-user sign-in, a user-cli transport per session, the
per-request grant re-read, the owner-only gate and user page, the notice,
the hub label and peer links, accessContextFor peers, and the bus boot
access wiring (sage-3142). Tests G1-G8 and B1-B3 are written and not yet
run; runs wait for Sage's CLEAR. Choices C1-C9 in
agents/launchpad/work/queue-294/BUILD.md.
2026-10-23 01:37:03 -05:00
jason.woltje 8c28ee7315 gizmoduck: row 270 (264c, #1775) round 3 for duckworth-0226 B4 (sage-3038): one collection opens at most the system config's compactionStreams stream files in name order (default 1024, 32 to 65536, a bad value takes the default and logs), not-collected past it with no cursor for an unopened stream; the missing-stream check uses a Set; readStreams, cap and launcher tests; mutants M22-M24, M10 anchor moved; docs/TOOLS.md has both keys and C1 (N4); BUILD.md round 3 with stream counts, the 231 KB bound, C1 and N5; not run 2026-10-22 21:07:51 -05:00
jason.woltje bce4917154 gizmoduck: row 270 (264c, #1775) round 2 for duckworth-0223 B1-B3 (sage-3030, sage-3031, mos-1352, sage-3033): pi streams read in 1 MiB chunks under a budget from the system config's compactionReadBytes (default 64 MiB, 1 MiB to 1 GiB, a bad value takes the default and logs), not-collected past it; Claude history from before the ledger is harness-unsupported for good; launcher, runtime reader, clear and legacy tests; mutants M13-M21; BUILD.md round 2 with sizes, schema change, rollback hazard, N1-N3; not run 2026-10-22 21:07:51 -05:00
jason.woltje aa8fc490f5 row 271 (264d, #1776): clear context build round 1, not run (slot held). Broker: session.clear, session.cancel and session.operation, the fence on send/open/claim, cancel at arrival for routed messages, the drained receive and the end drain, trusted ops sessionClears and sessionClearExited/Uncertain/Retire/Start. Launcher: clearPass before the threads loop (stop, proof, retire, successor start through check()/start()), waiting on a live row 269 survivor. Old tests per mos-1315, rebased on row 206 (sage-2968): label 3m to 3n, future step 3n to 3o, 3m-3n.sql in the engine copies and file lists, ready lines, later3l and the rows() exclusions gain both tables as 206 did for thread_shares (mos-1292, approved in mos-1336), schema.test counts 25 tables and 96 triggers, COUNTED and T45 LISTED gain both tables after thread_shares (mos-1318, mos-1319), TESTER_VERBS pin (mos-1325), fixtures/schema-3m.sql 2026-10-22 21:07:51 -05:00
jason.woltje 5ddc36ca97 gizmoduck: row 270 (264c, #1775): completed Pi compactions counted into a host ledger beside the session store, keyed (entry id, timestamp) store-wide (sage-2806, sage-2814); launcher collects at run start and end under the workspace lock; session.list rows gain compactions through a runtime-injected reader; not run (slot held) 2026-10-22 21:07:51 -05:00
jason.woltje 721268b084 row 207 (#1705): mosaic access user add|remove on R5's path (proof, lock, revision, checkAccess, receipt user.add/user.remove); remove refuses user-has-grants; --level viewer already in R5; BUILD.md records Q1-Q5 (no access.reload, R4's) and the tests and mutants; tests held for the row 275 manifest check (sage-2790) 2026-10-22 17:28:04 -05:00
jason.woltje 6c80b12904 row 269 (264b, #1774): BUILD.md answers sage-2750 on the recover() change; the survivor log names its pids
The section "recover() change, for a design read" covers three things, with
file:line against aca16404c. Every leftover is still bound and ended as
host-lost, and a survivor only refuses legacy-run-live while it lives. The
5 s wait applies only in the bwrap kill branch. No old test's expected value
changes. The fallback is to revert to the base recover() and leave the
refusal untested. The survivor log line now names the outer and runner pids
so an operator can clear it, and the new test's log assertion matches.
2026-10-22 13:37:34 -05:00
jason.woltje 42fd3edd45 row 269 (264b, #1774): legacy-run-live gets its test (duckworth-0156)
recover() kept a survivor only when a bwrap outer pid outlived SIGKILL, so
the Q2 refusal (BUILD.md:177-179, t1-sessions.md:109) had no test. A leftover
whose runner still ran after its outer pid was gone was ended and dropped.
Now recover() waits on the outer pid and the runner, keeps any leftover where
either still runs, and logs that it still runs. check() reads only the
survivors that still run.

session-launch.test.mjs adds a test where a sessionless leftover's runner is
a sleep child and its outer pid is gone. It asserts the legacy-run-live
refusal with no launch and no session workspace, then one launch once the
child exits. BUILD.md adds mutants M10-M12 and replaces the "no test" note.
2026-10-22 13:37:34 -05:00
jason.woltje 2133c5a0c6 row 269 (264b, #1774): per-session store, workspace and single-writer lock
threadsState gives one row per session with `session` and `legacy`; threadIdle
idles a run against its bound session. Each session gets its own store
(threads/<b>/<t>/sessions/<s>/, or the thread's old store for a legacy-3l
session) and its own workspace (session-workspaces/<b>/<i>/<s>/), held by an
O_EXCL <ws>.lock from before the clones to the run's proven exit. A legacy
session's workspace binds in-sandbox at the old instance path. sessions.json
is v2 and reads v1. New tests: cli session-launch.test.mjs, seat
session-workspace.test.mjs. Not yet run: tests wait for Sage's CLEAR.

Two old assertions change as exact updates:
- mos-1285: end-launch.test.mjs threadsState deepEqual. The old row shape was
  { thread: 'th-1', instance: 'coder', pending: 0, unread: 0, lastMessage: null,
  lastOpen: '2026-10-15T00:00:01.000Z', lastClaim: null, holder: null }; the
  row keeps every key and value and adds session: 'th-1', legacy: true.
- mos-1289: thread-launch.test.mjs:182, old line
  `const store = join(f.dataRoot, "threads", "acme", A);`
  now reads A's default session id from threadsState's `session` key; :183-185
  unchanged; one added assert that threads/acme/<A>/session is absent.
2026-10-22 13:37:34 -05:00
jason.woltje bda4ee6138 morgana: row 277 (#1782) r3: a refused thread.claims prints the role lines and the refusal code (N1), cli README agents usage (N2), per sage-2505 2026-10-22 06:01:09 -05:00
jason.woltje eccd6e276e morgana: row 277 (#1782) build: thread.claims bus verb for human and reader sessions (D1), mosaic agents adds thread lines without --tester or --json (C1/C2), message-filter pin moves to thread.claims (C3), tests T1-T8 2026-10-22 06:01:08 -05:00
jason.woltje d87483d683 bus, cli: #436b Gitea grant path, schema 3j-3k (row 236, #1742)
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.
2026-10-22 03:42:05 -05:00
jason.woltje 4f68485272 honker: row 194 b8 r2 (sage-2289): a fire stop stopRun can't confirm (unknown) reads as lifecycle.end.alive with reason unknown, never killed, and the Console flags it; cli T9a no-runtime-record test, bus T9a reason checks, M56; notes 2026-10-22 03:06:41 -05:00
jason.woltje 5d2c274420 honker: row 194 b8 S6 (sage-2241, sage-2246, sage-2261): fire's kill end goes through row 191's stopRun with the fire's request as owner, killed and alive come back as lifecycle.end.killed and lifecycle.end.alive and the Console flags a run still alive; terminate stays SIGTERM-only (V3); halted, the pass closes launches and regenerates processing-halted and a halt joins a fire's stop; terminate's pass narrows to runs spawned by the end's time (N6); T9a, T9b, T15, N6 2026-10-22 03:06:41 -05:00
jason.woltje 3521c23c3e honker: row 194 b6 (webby-0094, sage-2241, sage-2245): every instance-writer verb answers restart (B1) and the CLI and Console show it for veto; fire runs the writer's checks against the file before step A, so an unloaded keep can't strand an instance firing; a fire of a delisted name revokes (N1); a host service makes no token reference (N2); only the human re-points a kept instance's model (N3); DEFERRED a human escape for a stuck fire (N4); S6 waits on row 191's stopRun contract 2026-10-22 03:06:41 -05:00