Compare commits

...
Author SHA1 Message Date
jason.woltje d952222478 docs: checkpoint row 332 and hand off after T3 crash 2026-10-24 17:49:44 -05:00
jason.woltje c8a9bcf946 docs: P3 amendment for pi's GLM and GPT routes, and the Case 2 proxy unit brief (mos-1616) 2026-10-24 17:13:28 -05:00
jason.woltje 58b2bbb3a5 docs: row 209 brief as the .54 window with its own proxy (mos-1615, Q253) 2026-10-24 17:04:07 -05:00
jason.woltje 95d4991d20 docs: brief template run lists come from imports (mos-1612)
A builder's whole-file run list for a row comes from imports, not a text
grep, and goes in the builder's report before the run. Files on the
mos-1592 list stay off unless Mos approved the run. Row 329 round 2's
path grep matched fixture text and reran case1-accept.
2026-10-24 16:39:32 -05:00
jason.woltje 966ee31ea8 docs: row 330 P4 brief and design D7/J4 for mos-1608
Mos approved the P4 brief with upstream API keys added: a human-only write-only verb, z.ai-only allowlist, apikey-invalid and provider-not-allowed refusals, a canary test and an echo mutant. Account ids hash the proxy's own credential identifier, never a token or key value. Account removal stays out of P4.
2026-10-24 15:54:18 -05:00
jason.woltje 696ea3a3af docs: row 330 P4 brief as the Console proxy page; Q250 amendments to the Vikunja 237 design
Jason's Q46 and Q47 (DECISIONS Q250, mos-1606): accounts are entered in the Console's own proxy page and D8's /proxy/ forward to the upstream panel is dropped. The new P4 brief is its own file so the rows doc blob that rows 329 and 331-333 pin stays unchanged. Design D5-D8, D10, D20, migration step 4, J3-J5, the rows table and the Mos rulings list are amended.
2026-10-24 15:49:37 -05:00
jason.woltje 0ce22dde65 queue: revs 3946-4020. Row 290 (Louie 3947, 3950-3951; Sage request 3952-3953; Webby approve 3954; note and done 3956-3957). Row 225 (Fethry 3946, 3958-3959; Dewey approve 3960; request 3961-3962; note and done 3969-3970). Row 287 (Sage assign and set 3948-3949; Steelbeak 3955, 3963-3964; request 3965-3966; Boyd 3967 and Dewey 3968 approve; note and done 3971-3972). Row 266 (Sage 3973-3977; Fethry 3978-3980; request 3981-3982; Boyd 3983 and Dewey 3985 approve; note and done 3988-3989). Row 227 assign 3984. Row 257 note and done 3986-3987. Row 328 (add 3990, brief 3991; Fethry 3992, 3997-3998; request 4000-4001; Boyd 4002 and Dewey 4003 approve; note and done 4019-4020). Row 224 (Della 3993-3994; request 3995-3996; Dewey approve 3999; note and done 4015-4016). Model-proxy rows 329-333 add and brief (4004-4013), Magica 329 start 4014, 330 blocked 4017 (mos-1602), 331 note 4018. 2026-10-24 14:52:57 -05:00
jason.woltje 36056a5dd9 docs: BUILD-LOG landing entries for rows 257, 266, 224 and 328; Sage session line 2026-10-24 14:45:01 -05:00
13 changed files with 3349 additions and 87 deletions

No files matched your search

+16
View File
@@ -5566,3 +5566,19 @@ claim. Receipts and limitations in agents/lena/work/queue-296/BUILD.md and run-r
2026-10-24 | Fethry | Row328 sage4205 stress stopped at required no-reproduction boundary. M1-50 passed50/50; fallbackM1-1 passed50/50, zero library-sync-busy assertions, no skips/cancels. Fixed50 and whole-file NOT RUN. Absolute19 initial priority then host drift recorded. All100 fresh shell gXXX TMPDIRs29bytes; both mutants restore exact test hash and empty diff/stat+porcelain. No test/assertion/product changes. Receipts/nice/load/plain-text BUILD pushed; slot returned fethry0043. Await Sage/Mos ruling; no in-review/acceptance claim.
2026-10-24 | Fethry | Row328 sage4214/Mos1599 option A GREEN on06c57a7db:8x50 M1-50 produced374 passes/26 expected library-sync-busy assertion failures, exact restore/full diff+porcelain clean, same8x50 fixed400/400, whole library-credential6/6, no skips/cancels or unexpected errors/reruns. Node nice16/19 observed after absolute19; loads and801 receipts retained. Old test staysapproved+4/-3, assertions/product unchanged. Own process sweep empty. Evidence push/slot return and owner review move next; Boyd/Dewey then Sage full bus/scripts gate pending.
2026-10-24T19:44:50Z | Sage | Row 257 (#1762, Q198 S1 pressure parser and rules evaluator, Morgana, Filbert) LANDED 73692e1bb, pushed 17:41:58Z 10-24. Before: refactor at 487500a16. After: Morgana's four commits cherry-picked onto 487500a16 with unchanged patches; the 9 packages/supervisor paths match Filbert's round 2 manifest b176a88f. Filbert r1 c30188 (N1/N2 fixed in r2), r2 APPROVE c30190 rev 3037, request c30189 posted by Sage. Slot result on 1261fa2d8: three files whole 15/0, 29/0, 1/0, supervisor 45/0, M1-M8 killed by assertion. Sage gate: first run RED 17:20:42Z, webui 441/1 on the old row278 sign-out test (timeout at load about 8.5, the row touches no webui path); the webui-only rerun 442/0 was not counted; the full rerun was GREEN 17:41:11Z: bus 998/0, business 283/0, webui 442/0, supervisor 45/0, cli 989 plus the allowed FED R7 skip, all 12 scripts rc 0. Correction: the row278 timing red is an old test, so any change to it goes to Mos (mos-1272). Follow-up: Morgana's carry (sage-3003, CLEAR_HELD entry and a clear-path hold test) binds the row that wires a Q198 hold into a launch refusal. Not re-pinned.
2026-10-24T19:44:50Z | Sage | Row 266 (#1771, C2-10c Console room view, Fethry on Codex, Boyd and Dewey) LANDED 3e5041b43, pushed 18:00:49Z 10-24. Before: refactor at 73692e1bb. After: Fethry's four commits cherry-picked, every patch-id equal to the seat branch; tree is manifest 5f816042 with no other change. Boyd APPROVE c31609 rev 3983, Dewey APPROVE c31610 rev 3985 (N1-N3 non-blocking), request c31608 posted by Sage. Sage gate GREEN first run 18:00:08Z: bus 1000/0, business 283/0, webui 458/0, supervisor 45/0, cli 989 plus the allowed FED R7 skip, all 12 scripts rc 0. Dewey's N2, the old T9 library-sync-busy race, went to Mos and became row 328. Not re-pinned.
2026-10-24T19:44:50Z | Sage | Row 224 (#1725, C2-05b, Della on Codex, Dewey) LANDED 5e77cdd09, pushed 19:18Z 10-24. Before: refactor at 7fe32d722. After: Della's 13 commits cherry-picked onto 7fe32d722. Sage gate GREEN 19:16:37Z on 27624aa66 (base 06f507dbc): bus 1011/0, business 283/0, harness 176/0, cli 990/0 plus the allowed FED R7 skip, webui 458/0, all scripts rc 0. Drift between the gated base and 7fe32d722 is only docs/plans/2026-10-24_model-proxy-rows.md, which no test reads (mos-1601 condition); manifest-r9 952482b4 matches the landed tree. Dewey APPROVE c31619 rev 3999. #1725 closed c31623; note rev 4015, done rev 4016. Correction: the first done move passed --evidence and was refused (rc 2, the round closes on its recorded verdicts); rerun without it. Follow-up: Dewey's N3, the old ask helper can't serve a library business, goes to a later row. Not re-pinned.
2026-10-24T19:44:50Z | Sage | Row 328 (#1826, Vikunja 622, old T9 timer race, Fethry on Codex, Boyd and Dewey) LANDED 8bb5b3c73, pushed 19:40Z 10-24. Before: refactor at 5e77cdd09. After: Fethry's 8 commits cherry-picked onto 5e77cdd09 (same patches); T9's second start passes intervalMs 2147483647 (mos-1594), test-only. Under 8x50 concurrent loops M1 (50 ms back) gave 26 expected failures and the fix 400/400. Boyd APPROVE c31621 rev 4002, Dewey APPROVE c31622 rev 4003. Sage gate GREEN 19:38:54Z on 8bb5b3c73 itself, no drift: bus 1011/0, business 283/0, harness 176/0, cli 990/0 plus the allowed FED R7 skip, webui 458/0, every scripts/test-*.sh rc 0 (Dewey N1). Manifest 1e010468. #1826 closed c31625, Vikunja 622 done (comment 1071), note rev 4019, done rev 4020. Not re-pinned.
## 2026-10-24 — row332 P3 proxy harness configuration: investigation/test placement
Fethry at c8a9bcf94, per Sage sage-4292 and mos-1616 pi-route amendment. Before: every managed session receives instance-wide provider credentials; harnesses have no transient per-session proxy context; pi preflight checks only its binary. Intended after: proxy-mode isolation, Claude proxy env, pi private run-local route config using environment references only, credential preflight, and business proxy account settings. Design/test plan: agents/fethry/work/queue-332/BUILD.md. Initial tests placed before production changes. No tests run: Sage CLEAR is required and has not arrived. No success/acceptance claim, live change, or dependency landing. Existing proxy issue number requested from Sage; not yet received.
## 2026-10-24 — row332 crash stop, documentation-only checkpoint
Fethry stopped under Mos mos-1630/Jason's T3 crash instruction. No production implementation, tests, probes, mutants or acceptance runs occurred; Sage CLEAR never arrived. Explicit route metadata per sage-4293 is recorded in agents/fethry/work/queue-332/BUILD.md; full state and resumption boundaries are in HANDOFF.md there. Safe crash checkpoint commits documentation/historical plain-text import manifest only; four unrun tests and the import-audit script remain uncommitted. No long jobs restarted, protected branch changes, merges, live changes or further thread messages.
+88
View File
@@ -0,0 +1,88 @@
# Row 332 — P3 harness config from the model proxy
## Assignment and boundaries
2026-10-24: Fethry, thread 65673bd9-3bfa-412b-85d5-9b364187d8b6, branch fethry/row332, baseline c8a9bcf94. Sage assignment sage-4292; accepted brief plus full pi-routes amendment c8a9bcf94 (mos-1616). Gladstone first review, Dewey landing review; landing waits for P1/329 and P2/331, rebase on both and Sage's gate. No tests before Sage's CLEAR. No live proxy, host credential directories, real proxy data, management key, cutover, policy edits, or Codex harness changes.
Queue next in canonical checkout returned `nothing` during assignment. Starting row with op fethry-332-start met Sage's queue update lock; retry through the queue only. Root npm ci --ignore-scripts --no-audit --no-fund completed in this worktree (128 packages); no canonical node_modules use.
## Design note (line numbers at c8a9bcf94)
- packages/seat/src/session.mjs:242-247 defines ENV_ALLOW; keep it unchanged. sessionEnv:256-262 gains optional proxy context and drops CLAUDE_CODE_OAUTH_TOKEN, every passed ANTHROPIC_* variable, OPENAI_API_KEY, OPENROUTER_API_KEY and ZAI_API_KEY before adding harness env. Non-proxy results retain current behavior exactly.
- packages/plugins/harness/claude-code/index.mjs:56-67 preflight accepts the session proxy credential; env:119-126 sets ANTHROPIC_BASE_URL and ANTHROPIC_AUTH_TOKEN from that context.
- packages/plugins/harness/pi/index.mjs:33-36 preflight requires its own provider credential or proxy key, never a Claude OAuth token. env:63-70 sets only the session's proxy key as ANTHROPIC_API_KEY and selects the generated provider. Fresh run-local home/.pi/agent/models.json is private (0600; parent directories 0700). Every apiKey is the literal reference $ANTHROPIC_API_KEY; recursively forbid values beginning with !. Nothing stores the key in models.json or a manifest.
- packages/harness/src/bundle.mjs:313 buildBundle accepts transient proxy context; :379 harness.env call needs it plus run location and launch.models. Context must never be added to session metadata, source digests, or manifest. The run-local file regenerates on each launch.
- packages/cli/src/launcher.mjs:391,400 preflight, :412 account checks, :529 bundle creation and :592 child env must agree on the same session credential. Coordinate its acquisition with P2; build/test now against the specified { baseUrl, key } stand-in, not a management client or a key-store implementation.
Exact business setting keys remain launch.models.<selection>.provider, launch.models.<selection>.model, launch.account.name and launch.account.credential (launch.mjs:12-24,81-89). Provider already accepts proxy. Proposed account credential sentinel is the literal proxy (add alongside existing uppercase environment-set syntax), with launch.account.name a human-readable id such as proxy. No new fields. Existing provider anthropic selects the Anthropic route, zai selects GLM, and proxy selects the stack-owned GPT route; send this interpretation to Sage before implementation because the brief doesn't specify route encoding for provider proxy.
## Build-time API choice and pinned binary
P1's committed magica/row329 has CLIProxyAPI 8.0.42 in packages/model-proxy/PIN. Use that commit's fetchPinned({dataRoot:<fresh temporary root>}) implementation, copied from Git objects to this seat's temp tooling directory with its relative dependencies and PIN, until P1 lands. Never inspect another seat's worktree/scratch. It fetches only pinned GitHub release assets and checks archive, executable and panel hashes. No production instance config is needed and nothing under a real dataRoot/proxy is read.
After CLEAR, try actual pinned pi requests with both openai-responses and openai-completions through that binary under unshare -rn, against stand-in upstreams with made-up credentials under 24 characters. Record version, API path, safe request fields, response status and turn result. Choose one shape once from those results and hard-code it; no runtime fallback. Real Codex OAuth cannot be simulated as a real authenticated turn: first real Codex turn remains row209 phase A step7. Distinguish the offline compatibility evidence from that deferred real-auth proof.
The separate offline GLM acceptance script (outside scripts/test-*.sh) uses pinned pi and proxy, checks the upstream sees the model id from /v1/models, and records whether thinkingFormat/zaiToolStream-derived fields survive translation. All configs/auth placeholders belong to its fresh temp root.
## Implementation and test sequence
1. Add tests first for env isolation, Claude proxy env and preflight, pi credential refusal and each generated route/file invariant, and business account acceptance. Do not run until CLEAR; first new-test red is reported afterward, old-test red or second red is reported before changing anything.
2. Implement harness/bundle/env handling against P2's transient interface. Add launcher boundary integration once its exact P2 acquisition seam is agreed. Keep secrets out of session.json and bundle manifests.
3. With CLEAR, run the offline API-shape probe and GLM turn, then whole touched test files. Before each whole-file run report the list derived by parsing imports and traversing local dependencies; include harness plug-in dynamic loading explicitly. packages/cli/tests/case1-accept.test.mjs remains excluded without Mos approval.
4. Kill named mutants; restore production source and verify. Record exact output and nice. Use a fresh shell mktemp -d /mnt/storage/scratch/tmp/XXXXXX TMPDIR for each run, absolute nice 19, and timeout -k 10 for each scripts/test-*.sh. No hidden skips; Sage owns the package/script landing gate.
5. After dependency landings, rebase, complete review and gate stages, update queue only through its CLI, and append session/build receipts. Push only fethry/* when ready for authorized review; no force-push or attribution trailers.
Planned tests:
- Each forbidden environment variable is absent in proxy mode; all existing allowed env is identical without a proxy; two launches receive distinct own keys and no other agent's key.
- Claude env has exactly the supplied proxy base URL/auth token; proxy credential satisfies preflight without host upstream credentials.
- pi refuses no-session-credential for no key or Claude OAuth alone, accepts an own provider key and a proxy key.
- models.json covers Anthropic anthropic-messages at root URL, GLM openai-completions at /v1, and a stack-owned GPT provider at /v1 with the chosen API; routes use configured model ids.
- Every apiKey is $ANTHROPIC_API_KEY; no key value occurs in file; recursively no value starts with !; mode 0600 and private parents; next launch uses changed port/models/key reference with no stale content.
- Business accepts provider proxy and account credential proxy while preserving existing valid and invalid account behavior.
- Launcher/bundle integration keeps context transient and passes only the launch's own key.
- Every new refusal code gets a separate test.
- Offline GLM pinned-pi turn and z.ai compat observation; both GPT API-shape requests recorded with limitations.
Named gate mutants:
1. Proxy mode still passes CLAUDE_CODE_OAUTH_TOKEN (original brief).
2. models.json receives the key value instead of $ANTHROPIC_API_KEY (amendment).
No tests have run. API-shape choice is pending evidence, not claimed.
## Progress 22:27Z
Placed initial RED tests (not executed): packages/seat/tests/proxy-session-env.test.mjs and packages/plugins/tests/proxy-harness.test.mjs. These exercise real sessionEnv and loader-loaded harness exports. Production source remains untouched pending the first authorized RED run. Removed no assertions and ran no tests. Correct baseline bundle harness.env line is 376 (not 379 in the initial design note).
Sage reporting attempts fethry-0001 (including same-key retry) and fethry-0002 all returned `T3 GET /api/orchestration/threads/<sage> timed out after 30s`. Delivery is unconfirmed. Queue move retry also met a Sage queue update lock (sage-333-reviewers-1024a); no bypass.
Additional test-first placement: packages/business/tests/proxy-launch.test.mjs covers existing proxy model acceptance, proposed proxy account credential literal, preserved environment account forms, and rejection of mixed/literal credential strings. Pending Sage's route/account interpretation and CLEAR; no production edits or tests run.
## Import audit and queue status
The non-evaluating import audit uses Node vm.SourceTextModule.dependencySpecifiers, not a text-path grep, plus explicit computed-import edges from the plug-in loader to both harness modules. Source: import-run-list.mjs; output: IMPORT-RUN-LIST.txt (211 entries, including the explicitly EXCLUDED case1-accept file). This is a candidate impact list for the planned source changes, not an executed test list. Before a whole-file run, report the actual authorized subset to Sage. Parsing executes no repository modules and runs no tests. The first audit invocation had a path-depth setup error (ENOENT); corrected the audit's own repository root and regenerated successfully.
At 22:28:19Z the canonical start operation returned `queue: only the owner (sage) may start row 332`. Per assignment, wait at least two minutes before repeating this same op. No queue state was edited manually.
## Design correction after D9 re-read
The initial route-encoding proposal (provider proxy for GPT only) is not sufficient: design D9 explicitly defines provider proxy as any model through the instance proxy. Do not implement the earlier proposal. Two viable encodings need resolving before route-dependent tests/production: exact model-id lookup in pinned pi's provider catalogs (no new business fields, but refuses proxy-only aliases/unknown models), or explicit route metadata in launch.models (additive schema, needs Sage to confirm it is within the approved brief). Recommend exact catalog membership if all intended configured model ids are in pinned pi; otherwise ask Sage to define/approve an explicit route field. Never guess by model prefix or silently choose a wire API. Independent env/preflight tests already placed remain valid.
Reporting recovered: fethry-0004 was accepted by t3_send_message at approximately 22:29:51Z. It delivered the D9 route correction, route-encoding/P2-seam question, import-manifest location and no-tests status to Sage. Earlier failed-message deliveries remain unconfirmed.
22:32:18Z: The start retry issued at 22:30:40Z (over two minutes after first owner refusal) also exited 2: `queue: only the owner (sage) may start row 332`. This is an ownership boundary; row was not started and no code/test execution proceeds through it. Sage's assignment must take effect before the same op can succeed. The full design report fethry-0005 again timed out; fethry-0004 is the confirmed delivered report. git diff --check passed; no test, probe, commit or push has run.
## Route ruling accepted — sage-4293, 22:37Z
Sage settled explicit metadata, superseding both initial encoding proposals and the catalog proposal. Exact new setting: launch.models.<selection>.route; permitted values anthropic, glm, codex, required only when provider is proxy. Nonproxy entries still allow provider/model only. Missing route refuses proxy-route-missing; present unknown/nonstring route refuses proxy-route-unknown. Both get independent code assertions; each valid value gets a test using a proxy-only model id absent from any catalog. The GPT route's generated pi provider will be mosaic-proxy-codex, never openai-codex. Its wire API remains a build-time choice after the pinned-binary probe. P2 passes only {baseUrl,key}; no route belongs to that seam.
A key persistence hazard found during source inspection: launcher.mjs:571 writes bundle.env as session.harnessEnv. Adding the key to harness.env must not retain this behavior for credentials. P3 will keep generated key env transient for spawnSession and omit those credential values from serialized harnessEnv. runner.mjs:390 already inherits the spawn environment before applying nonsecret harnessEnv. Test the on-disk session/bundle boundary, not only models.json.
The old launch-settings.test.mjs already uses provider proxy fixtures without route. Update those fixtures to explicit anthropic routes before any full-file run; preserve their existing authorization assertions. This is the new approved validation shape, not permission to loosen tests. No tests have run and no production edits exist.
Additional test-first placement after route ruling: packages/harness/tests/proxy-bundle.test.mjs exercises real buildBundle with explicit provider proxy entries and proxy-only model ids, three generated providers, run-local file mode, environment references, recursive no-! values, no key in bundle files/manifest, fresh model/port/key on next launch. The exact GPT API assertion must be added from the authorized pinned-binary probe before this test file's first run; it deliberately makes no unverified wire-shape claim now. No skip is introduced.
Canonical queue show returned owner sage and after=331 at 22:40Z; it also warned `view unknown` for the rendered table. No repair or queue bypass attempted; wait for Sage's announced batch. Queue metadata identifies shared proxy Gitea issue #1830.
## STOPPED — mos-1630, 2026-10-24T22:48Z
Jason's relayed crash instruction supersedes active work: no long-job restart, commit/push safe documentation only, handoff in this worktree, no other thread messages, then stop. See HANDOFF.md for complete state, next steps, uncommitted tests/audit script, and reruns needed. No tests or probes ever ran; no production implementation exists. Latest design is explicit launch.models route metadata per sage-4293; earlier catalog/GPT-only proposals are superseded. The original 211-entry import manifest predates the fourth new test file and is historical, not run authorization. Full inline resends still hit T3 timeouts. Crash commit will exclude every unrun test and the audit script.
+51
View File
@@ -0,0 +1,51 @@
# STOPPED — row 332 (P3), T3 crash handoff
Stopped on 2026-10-24 under Mos mos-1630, relaying Jason's instruction: do not restart long jobs; commit/push safe work, leave a handoff, then stop. No further thread messages, tests, probes, queue operations, or implementation will run in this session.
## Branch and completed work
- Worktree: /home/jwoltje/.t3/worktrees/mosaic-stack/fethry-row332
- Branch: fethry/row332, based on refactor c8a9bcf94. No implementation commits, rebases, merges or production source edits.
- Read P3 brief, rules, full pi amendment, gate template, design and named source files. Detailed notes in BUILD.md beside this handoff.
- Root npm ci --ignore-scripts --no-audit --no-fund completed in this worktree only (128 packages). No canonical node_modules used.
- Initial test files written before implementation; none executed. Sage has not sent CLEAR. No proxy fetch, binary probe, offline turn, mutant, or suite has run.
- No real proxy, management key, host auth directory or live instance was accessed. No production service was started/stopped.
- Canonical queue next returned nothing during the assignment. Queue start op fethry-332-start refused on locks, then owner sage, including a retry after two minutes. Latest completed queue show still had owner sage, state briefed, after 331; it also warned that the rendered table was unknown. Did not repair or bypass it. Sage sage-4293 says an assign/after=none batch is running. Queue metadata identifies shared Gitea issue #1830.
## Latest accepted design
Sage sage-4293 supersedes all earlier route proposals: explicit route metadata, never catalog membership or model-prefix inference. Selected spelling: launch.models.<selection>.route = anthropic | glm | codex, required only with provider proxy. Missing route: proxy-route-missing; unknown/nonstring route: proxy-route-unknown. Other providers keep provider/model-only entries. Proposed launch.account.credential literal proxy; existing name/credential field names retained. GPT generated provider: mosaic-proxy-codex, never openai-codex. GPT wire API is still undecided pending the authorized pinned-binary requests. P2's seam stays exactly { baseUrl, key }.
Important implementation finding: launcher.mjs:571 serializes bundle.env into session.harnessEnv. Harness env will contain the session key in proxy mode, so credentials must instead reach spawnSession through transient environment variables and be omitted from serialized harnessEnv. runner.mjs:390 already inherits the spawn environment. Preserve ENV_ALLOW; filter instance provider variables in proxy mode only.
## Uncommitted work, intentionally left for the next session
These are unrun, incomplete tests/audit code, excluded from the documentation-only crash commit:
- packages/business/tests/proxy-launch.test.mjs — explicit routes and refusal codes, proxy account credential, existing nonproxy/account behavior.
- packages/plugins/tests/proxy-harness.test.mjs — Claude env/preflight, own-key isolation, pi preflight and OAuth-only refusal.
- packages/seat/tests/proxy-session-env.test.mjs — instance credential filtering and unchanged nonproxy env.
- packages/harness/tests/proxy-bundle.test.mjs — real bundle generation, all three providers, key reference/no-key/no-! invariants, file modes and launch freshness. Exact GPT API assertion deliberately pending probe evidence; add before its first run.
- agents/fethry/work/queue-332/import-run-list.mjs — non-evaluating static import audit using vm.SourceTextModule plus explicit computed loader edges. It ran successfully after correcting its own root-depth setup error. It is not a test runner.
IMPORT-RUN-LIST.txt is a historical 211-entry candidate impact list, generated before proxy-bundle.test.mjs was added. It includes case1-accept as explicitly EXCLUDED (mos-1612). Regenerate the list after resuming and report the actual authorized run list inline before any whole-file run. Do not treat the historical manifest as a current run authorization.
## Reporting status
T3 reporting repeatedly failed during GET with a 30-second timeout. fethry-0004 was confirmed delivered. Some later short numeric keys returned reused:true unexpectedly; do not rely on them as delivery evidence. A row-scoped detailed design resend and the inline 211-line import manifest also timed out, including the manifest's same-key retry. Sage may not have those messages. This handoff and BUILD.md are being pushed so they can be read with git show; no new thread message is sent under mos-1630.
## Next session, after restart authorization
1. Read this handoff/BUILD.md and recover queue state from canonical checkout. Wait for owner fethry and no after, then retry the same start op. Never bypass a refusal.
2. Recover Sage's slot status. Still NO tests or probes until Sage sends CLEAR. No job needs restarting merely to preserve current state.
3. Review the four uncommitted test files. Add the pinned-proxy API probe and exact GPT assertion before the first relevant run. Initial RED has not happened; production implementation must follow the authorized first RED.
4. Rebuild the import-derived run list and send it inline or in a reviewed pushed commit before runs. case1-accept remains off without Mos approval. Existing launch-settings.test.mjs proxy fixtures need explicit route metadata with their authorization assertions preserved; no old-test red has occurred.
5. Use P1's committed fetchPinned code under an owned fresh temporary root (8.0.42 at the inspected magica/row329 revision), never live proxy assets or another seat's scratch. After CLEAR, try pi's responses and completions requests under unshare -rn against stand-in upstream, record evidence, choose one GPT API at build time. Separately prove offline GLM and record z.ai compat survival. Real Codex auth proof remains row209 phase A step7.
6. Implement transient P2 context, model validation/route propagation, harness config, preflight, spawn env/serialization separation and tests. Named mutants: OAuth token leak; literal key in models.json. No policy or real credentials involved.
7. Land only after 329 and 331 land, rebasing on both, Gladstone first review, Dewey landing review and Sage's required gate. No force-push or merge authority is added by the crash instruction.
All future tests use a fresh shell-created short TMPDIR, absolute nice 19, and timeout -k 10 for scripts/test-*.sh. First new-test red is reportable afterward; old-test red or a second red goes to Sage before changes/reruns. No test outcomes are claimed here.
## Crash commit
Only documentation and the historical plain-text import manifest are committed. The final STOPPED reply records the exact pushed commit. The uncommitted files above remain deliberately available in this worktree because they have never run and test-slot authorization has not arrived.
@@ -0,0 +1,211 @@
packages/bus/tests/access-revoke.test.mjs
packages/bus/tests/broker.test.mjs
packages/bus/tests/channel-proof.test.mjs
packages/bus/tests/chief-of-staff.test.mjs
packages/bus/tests/citation-guard.test.mjs
packages/bus/tests/citation-runtime.test.mjs
packages/bus/tests/creative.test.mjs
packages/bus/tests/credential-verbs.test.mjs
packages/bus/tests/grant-scope-runtime.test.mjs
packages/bus/tests/host-run.test.mjs
packages/bus/tests/land.test.mjs
packages/bus/tests/library-credential.test.mjs
packages/bus/tests/library-lookups.test.mjs
packages/bus/tests/library-sync.test.mjs
packages/bus/tests/library.test.mjs
packages/bus/tests/lifecycle-revoke.test.mjs
packages/bus/tests/limit-checks.test.mjs
packages/bus/tests/messages.test.mjs
packages/bus/tests/processing-runtime.test.mjs
packages/bus/tests/project-runtime.test.mjs
packages/bus/tests/reload.test.mjs
packages/bus/tests/tasks.test.mjs
packages/bus/tests/tester-writes.test.mjs
packages/bus/tests/tester.test.mjs
packages/bus/tests/usage-runtime.test.mjs
packages/bus/tests/usage.test.mjs
packages/bus/tests/workflow-roles.test.mjs
packages/business/tests/access-levels.test.mjs
packages/business/tests/access.test.mjs
packages/business/tests/agent-identity.test.mjs
packages/business/tests/assistant.test.mjs
packages/business/tests/business.test.mjs
packages/business/tests/case1-business-file.test.mjs
packages/business/tests/chief-library-credentials.test.mjs
packages/business/tests/chief-of-staff.test.mjs
packages/business/tests/cli.test.mjs
packages/business/tests/credentials.test.mjs
packages/business/tests/csuite.test.mjs
packages/business/tests/grant-scope.test.mjs
packages/business/tests/hard-waits.test.mjs
packages/business/tests/hosts.test.mjs
packages/business/tests/instance-credential-transitions.test.mjs
packages/business/tests/instance-settings.test.mjs
packages/business/tests/launch-settings.test.mjs
packages/business/tests/library-projects-protected.test.mjs
packages/business/tests/library-seats.test.mjs
packages/business/tests/lifecycle-settings.test.mjs
packages/business/tests/optional-tracker.test.mjs
packages/business/tests/plugin-settings.test.mjs
packages/business/tests/project-repo.test.mjs
packages/business/tests/project.test.mjs
packages/business/tests/proxy-launch.test.mjs
packages/business/tests/record-grants.test.mjs
packages/business/tests/reply-limits.test.mjs
packages/business/tests/resolve.test.mjs
packages/business/tests/role.test.mjs
packages/business/tests/token-limit-settings.test.mjs
packages/business/tests/vars.test.mjs
packages/business/tests/workflow-roles.test.mjs
packages/cli/tests/access-boot.test.mjs
packages/cli/tests/access.test.mjs
packages/cli/tests/app.test.mjs
packages/cli/tests/boot-status.test.mjs
EXCLUDED (mos-1612) packages/cli/tests/case1-accept.test.mjs
packages/cli/tests/case1-hostcheck.test.mjs
packages/cli/tests/case2-install.test.mjs
packages/cli/tests/case2-persona-import.test.mjs
packages/cli/tests/case2-unit.test.mjs
packages/cli/tests/channel-cli.test.mjs
packages/cli/tests/channel-recovery.test.mjs
packages/cli/tests/cli.test.mjs
packages/cli/tests/compactions-launch.test.mjs
packages/cli/tests/config.test.mjs
packages/cli/tests/credentials.test.mjs
packages/cli/tests/federation-acceptance.test.mjs
packages/cli/tests/follow.test.mjs
packages/cli/tests/git-socket.test.mjs
packages/cli/tests/grants-scope.test.mjs
packages/cli/tests/grants.test.mjs
packages/cli/tests/host.test.mjs
packages/cli/tests/hosts.test.mjs
packages/cli/tests/idle-stop-race.test.mjs
packages/cli/tests/instances.test.mjs
packages/cli/tests/launch-account.test.mjs
packages/cli/tests/launch-limit-checks.test.mjs
packages/cli/tests/launch-limits.test.mjs
packages/cli/tests/launch-routes.test.mjs
packages/cli/tests/launcher.test.mjs
packages/cli/tests/lifecycle.test.mjs
packages/cli/tests/limits-tokens.test.mjs
packages/cli/tests/limits.test.mjs
packages/cli/tests/mark-read.test.mjs
packages/cli/tests/names.test.mjs
packages/cli/tests/notifier.test.mjs
packages/cli/tests/optional-tracker.test.mjs
packages/cli/tests/other-tree.test.mjs
packages/cli/tests/processing-cli.test.mjs
packages/cli/tests/project-name-repo.test.mjs
packages/cli/tests/project.test.mjs
packages/cli/tests/publish-socket.test.mjs
packages/cli/tests/reply-limits.test.mjs
packages/cli/tests/revoke-window.test.mjs
packages/cli/tests/session-clear.test.mjs
packages/cli/tests/session-cli.test.mjs
packages/cli/tests/session-launch.test.mjs
packages/cli/tests/stack-copy.test.mjs
packages/cli/tests/stack-instances.test.mjs
packages/cli/tests/tester-reads.test.mjs
packages/cli/tests/tester-threads.test.mjs
packages/cli/tests/tester.test.mjs
packages/cli/tests/thread-cli.test.mjs
packages/cli/tests/thread-launch.test.mjs
packages/cli/tests/thread-revoke.test.mjs
packages/cli/tests/trackers-boot.test.mjs
packages/cli/tests/transport.test.mjs
packages/cli/tests/usage.test.mjs
packages/cli/tests/verbs.test.mjs
packages/control-board/tests/creative-hidden.test.mjs
packages/control-board/tests/discord.test.mjs
packages/control-board/tests/serve.test.mjs
packages/conversation/tests/flows.test.mjs
packages/harness/tests/bundle.test.mjs
packages/harness/tests/claude-gate.test.mjs
packages/harness/tests/claude-session.test.mjs
packages/harness/tests/creative.test.mjs
packages/harness/tests/gate.test.mjs
packages/harness/tests/git-tools.test.mjs
packages/harness/tests/library-tools.test.mjs
packages/harness/tests/mcp-server.test.mjs
packages/harness/tests/pi-session.test.mjs
packages/harness/tests/raise-domain.test.mjs
packages/harness/tests/runner.test.mjs
packages/harness/tests/skills.test.mjs
packages/harness/tests/spec-tools.test.mjs
packages/harness/tests/tools.test.mjs
packages/plugins/tests/channel.test.mjs
packages/plugins/tests/harness-compactions.test.mjs
packages/plugins/tests/harness.test.mjs
packages/plugins/tests/loader.test.mjs
packages/plugins/tests/proxy-harness.test.mjs
packages/plugins/tests/searxng.test.mjs
packages/processing-control/tests/task.test.mjs
packages/seat/tests/compactions-budget.test.mjs
packages/seat/tests/compactions-ledger.test.mjs
packages/seat/tests/compactions.test.mjs
packages/seat/tests/proxy-session-env.test.mjs
packages/seat/tests/sandbox.test.mjs
packages/seat/tests/session-workspace.test.mjs
packages/seat/tests/session.test.mjs
packages/tasks/tests/fields.test.mjs
packages/webui/tests/agents-browser.test.mjs
packages/webui/tests/agents.test.mjs
packages/webui/tests/assistant.test.mjs
packages/webui/tests/board-held.test.mjs
packages/webui/tests/browser-edge.test.mjs
packages/webui/tests/browser.test.mjs
packages/webui/tests/bus-browser.test.mjs
packages/webui/tests/bus.test.mjs
packages/webui/tests/channel-chat.test.mjs
packages/webui/tests/chat-browser.test.mjs
packages/webui/tests/chat-instances.test.mjs
packages/webui/tests/chat-replies-browser.test.mjs
packages/webui/tests/chat.test.mjs
packages/webui/tests/conversation.test.mjs
packages/webui/tests/decide-browser.test.mjs
packages/webui/tests/decide-sso.test.mjs
packages/webui/tests/discord.test.mjs
packages/webui/tests/docs-browser.test.mjs
packages/webui/tests/editor-browser.test.mjs
packages/webui/tests/editor.test.mjs
packages/webui/tests/granted-user.test.mjs
packages/webui/tests/history-return-flow.test.mjs
packages/webui/tests/instances-browser.test.mjs
packages/webui/tests/instances.test.mjs
packages/webui/tests/library-cli.test.mjs
packages/webui/tests/library-routes.test.mjs
packages/webui/tests/limits-browser.test.mjs
packages/webui/tests/limits-route.test.mjs
packages/webui/tests/messages.test.mjs
packages/webui/tests/pinned-copy.test.mjs
packages/webui/tests/preview.test.mjs
packages/webui/tests/processing-browser.test.mjs
packages/webui/tests/processing.test.mjs
packages/webui/tests/project-file.test.mjs
packages/webui/tests/proof-cli.test.mjs
packages/webui/tests/proof.test.mjs
packages/webui/tests/reads.test.mjs
packages/webui/tests/relaunch.test.mjs
packages/webui/tests/return-flow.test.mjs
packages/webui/tests/room-browser.test.mjs
packages/webui/tests/room-http.test.mjs
packages/webui/tests/routes-browser.test.mjs
packages/webui/tests/routes.test.mjs
packages/webui/tests/send-browser.test.mjs
packages/webui/tests/send.test.mjs
packages/webui/tests/serve.test.mjs
packages/webui/tests/settings-form.test.mjs
packages/webui/tests/settings-write.test.mjs
packages/webui/tests/shell.test.mjs
packages/webui/tests/sso-browser.test.mjs
packages/webui/tests/sso.test.mjs
packages/webui/tests/tester-browser.test.mjs
packages/webui/tests/tester-cli.test.mjs
packages/webui/tests/tester-listener.test.mjs
packages/webui/tests/thread-claims-browser.test.mjs
packages/webui/tests/thread-claims.test.mjs
packages/webui/tests/thread-sharing.test.mjs
packages/webui/tests/usage-browser.test.mjs
packages/webui/tests/usage.test.mjs
packages/webui/tests/user-option-swap.test.mjs
packages/webui/tests/views.test.mjs
+4
View File
@@ -1685,3 +1685,7 @@ are never rewritten or removed; corrections are new entries.
2026-10-24 | Fethry14f80e3c | Row328 T9 timer race (#1826) | New fethry/row328 worktree on2ce476d54, owner start rev3992 opfethry-0037. Test-only +4/-3 under Mos1594, no assertion/product changes. Local root npm ci, no links. Static-only stress/M1 preparation and untested push; waiting for Sage CLEAR, then Boyd/Dewey review.
2026-10-24 | Fethry14f80e3c | Row328 T9 race acceptance evidence | sage4214 on06c57a7db:400 concurrent M1 attempts yield26 expected failures, fixed400/400, whole file6/6; exact restoration/clean checks and process sweep empty. All801 receipts/nice/load preserved. Manifest1e010468 one approved+4/-3 old test, no assertion/product change. Earlier aborted and serial non-repro receipts separate. Review handoff Boyd/Dewey, Sage landing gate pending.
2026-10-24 | Sage 1ef1e4f8 | Landings 257, 266, 224, 328; model-proxy rows 329-333 filed | 257 73692e1bb, 266 3e5041b43, 224 5e77cdd09, 328 8bb5b3c73 landed on GREEN gates. Rows 329-333 briefed from 7fe32d722 (mos-1600/1601); 330 blocked on Jason's subdomain answer (mos-1602). Magica holds the slot for 329's builder gate.
2026-10-24 | fethry (65673bd9-3bfa-412b-85d5-9b364187d8b6) | row332 P3 proxy harness configuration at c8a9bcf94 | Started recovery and design; npm ci in isolated worktree; tests held for Sage CLEAR; no live proxy or credentials accessed.
2026-10-24 | fethry (65673bd9-3bfa-412b-85d5-9b364187d8b6) | row332 crash stop (mos-1630) | Documentation-only handoff on fethry/row332; four unrun test files and import audit script left uncommitted; no tests/probes/production edits; no jobs restarted or other threads messaged.
@@ -0,0 +1,82 @@
# Brief: the Case 2 proxy unit, so a hub installs P1's proxy unit
Written 2026-10-24 by Sage for Mos's mos-1616 ruling 1, which approved this row. Mos ruled that Sage
approves the brief if it only adds P1 item 7's unit to `scripts/case2-install.sh` and
`scripts/case2-unit.sh`: the same unit text, the same sha256 refusal and the Wants/After lines. Anything
beyond that goes to Mos. Read the rows doc's P1 brief (`docs/plans/2026-10-24_model-proxy-rows.md`, P1
item 7) and row 209's brief (`docs/plans/2026-10-24_row209-hub-54-window.md`, entry check 2) first. The
rows doc's "Rules for every row" apply here unchanged. Line numbers are at origin/refactor 58b2bbb3a, and
P1's paths are at its round 2 candidate magica/row329 86cb5c221. Check both once P1 lands.
## Brief: Case 2 proxy unit in case2-unit.sh and case2-install.sh
**Why.** A Case 2 hub (.54) installs through `scripts/case2-install.sh` (as the stack user) and
`scripts/case2-unit.sh` (as root, system units). P1 adds `mosaic-proxy.service` only to the user-unit path
(`scripts/instance.sh`, `scripts/proxy-service.sh`, `scripts/bus-service.sh`). `case2-unit.sh` writes the
bus and Console units and nothing else (:3-5, :56-57), and its bus unit has no `Wants=` or `After=` on a
proxy. Without this row, row 209 phase A can't run the proxy on .54.
**What ships.**
1. **The proxy unit, from P1's template.** `case2-unit.sh` renders a third system unit,
`mosaic-proxy.service`, from P1's `packages/cli/systemd/mosaic-proxy.service.in`, which this row doesn't
change.
- It uses the same render as the bus (`render()` :435): the copy for `@REPO@`, the unit PATH, `--node`
for `@NODE@`, and `@CONFIG_ENV@` deleted, because `case2-unit.sh` renders the default instance only.
- It gets the same added lines as the bus: `User=`, `Group=` and the four hardening lines, with no
capabilities and no `EnvironmentFile=`. `WantedBy=multi-user.target` replaces `default.target`, as for
the other two units.
- `check_unit` gets a `proxy` kind. Its fixed lines are those of P1's template: `ExecStart=` exactly
`<node> <copy>/packages/model-proxy/src/run.mjs`, and `NoNewPrivileges=yes`. Every check that applies to
both units today applies to this one too.
- A new test seam `CASE2_PROXY_TEMPLATE`, like `CASE2_BUS_TEMPLATE` (:44, :54).
2. **The sha256 refusal is P1's.** The unit starts P1's `run.mjs`, which checks the binary against PIN
before it spawns it. This row adds no second check and no other way to start the proxy. A test runs the
rendered `ExecStart=` in a temp root, with a made-up config and a binary that doesn't match PIN, and
checks P1's refusal code and exit status.
3. **Only when the instance has a proxy.** Root passes a new bare flag `--proxy` when the instance's config
has a `proxy` section.
- Without it, the render is byte for byte what it is today, and no proxy unit is written.
- With it, the bus unit gets `Wants=mosaic-proxy.service` and `After=mosaic-proxy.service`, in the place
where P1's `bus-service.sh` puts them, right after `Description=`. The Console unit doesn't change.
- Root still never imports copy code or reads the config (:16-21). A wrong flag fails closed: with no
proxy section, P1's runner refuses and the unit stops. With a proxy section and no flag, the proxy
doesn't run and P2's launch preflight refuses. BUILD.md checks both against the landed P1 and P2 code
and names the refusal codes.
4. **Re-install and start.**
- With `--proxy`, the three installed units must name one copy, and each must equal the render once its
copy id is the new one, the same rule as now (:557-571).
- Without `--proxy`, an installed `mosaic-proxy.service` refuses the run. The script never deletes a
unit file.
- Enable all of them, then start the proxy, then the bus, then the Console. A unit that was already
running is reported the way the bus and Console are now (:576-610), and the message names all three as
the units to restart together.
5. **case2-install.sh.** Only its closing "Next:" line (:231) changes, to tell root to add `--proxy` when the
config has a `proxy` section. If the builder finds that line needs no change, BUILD.md says why and the
file stays as it is.
**Out of scope.** P1's template, runner and PIN; the user-unit path; any named-instance render; reading the
config from root; the proxy's config or key; `mosaic proxy init`; any live host, unit or `/etc` write
outside a test's temp root.
**Tests**, in `packages/cli/tests/case2-unit.test.mjs` (and `case2-install.test.mjs` if item 5 changes the
script):
- with no `--proxy`, the bus and Console renders equal today's, byte for byte;
- with `--proxy`, the proxy unit's content, and the bus unit's `Wants=` and `After=` lines;
- each `check_unit` refusal on the proxy kind, by its message;
- P1's PIN refusal through the rendered `ExecStart=`;
- a re-install whose three units name two copies refuses;
- an installed proxy unit with no `--proxy` refuses and deletes nothing;
- the start order through the `CASE2_SYSTEMCTL` seam's log.
**Gate.**
- The builder is a new Codex gpt-6.1-sol thread and worktree off refactor (Q246, mos-1542). The row starts
when P1 (row 329) lands, and the builder rebases on it before any run.
- Boyd gives the first Codex review. Webby gives the Claude review of the root-run unit boundary and the
landing. Sage runs the landing gate.
- The run list for every whole-file run comes from imports and goes in the builder's report before the run.
`packages/cli/tests/case1-accept.test.mjs` stays off unless Mos approves (mos-1612).
- Every touched test file runs whole. Every package suite but queue, plus every `scripts/test-*.sh`, is
green on Sage's landing gate.
- Named mutants: the bus unit loses its `After=` line under `--proxy`; the proxy unit's `ExecStart=` skips
`run.mjs` and starts the binary directly.
@@ -0,0 +1,76 @@
# Brief amendment: row 332 (P3), pi's GLM and GPT routes through the proxy
Written 2026-10-24 by Sage. Mos approved items 4a to 4c in mos-1616 with three conditions, which are written
into the items below. Item 4d is settled there too. This came out of mos-1615 (DECISIONS Q253): on .54 Bean
runs GLM through a Z.ai key and Chet runs GPT through his ChatGPT/Codex login, both through the proxy. The
P3 brief in the rows doc (`docs/plans/2026-10-24_model-proxy-rows.md`, "Brief: P3 harness config from the
proxy", item 4) proves only the Anthropic route. Row 96 proved only that route for pi, too
(`agents/researcher/work/i1-proxy-test/REPORT.md`, S2-pi-A).
The rows doc isn't edited, because rows 329 to 333 pin its blob. This file replaces one line of P3 item 4,
"A non-Anthropic route names that provider's base URL in the same file.", and adds to P3's Tests and Gate.
Everything else in P3 stands. Line numbers are at origin/refactor 58b2bbb3a. Check them before you edit.
## Brief: P3 amendment, pi's GLM and GPT routes
**What pi 0.85.1 does today.** These facts come from the pinned pi's docs and its built-in provider data.
- `models.json` providers take `baseUrl`, `api`, `apiKey` and `models`. A built-in provider can be
overridden with a `baseUrl`.
- `apiKey` takes a literal, a `$ENV` reference, or `!command`, which pi runs as a shell command.
- The built-in `zai` provider is `openai-completions` at `https://api.z.ai/api/coding/paas/v4`, with z.ai
compat fields (`thinkingFormat: "zai"`, `zaiToolStream`).
- The built-in `openai-codex` provider speaks `openai-codex-responses` to chatgpt.com/backend-api with pi's
own OAuth, so it can't be pointed at the proxy.
**4a. One entry per route.** `<run>/home/.pi/agent/models.json` gets one provider entry for each route the
agent's `launch.models` names, each at the proxy's address from P3 item 1.
- Anthropic: as P3 item 4 says now, `anthropic-messages` with no `/v1`.
- GLM: `openai-completions` at `http://127.0.0.1:<port>/v1`, with the model id that the proxy's `/v1/models`
lists for the Z.ai key.
- GPT through the Codex login: a provider of the stack's own, never `openai-codex`, at
`http://127.0.0.1:<port>/v1`, with the model ids that the proxy lists for the Codex credential.
- The builder picks `openai-responses` or `openai-completions` once, at build time, from what the pinned
proxy passes for pi's requests. The harness has no fallback at run time: it writes the one shape the
build chose.
- BUILD.md records the choice and its evidence: the pinned proxy version, the requests tried on each shape
and what came back.
**4b. The key goes by reference.**
- Every entry's `apiKey` is `"$ANTHROPIC_API_KEY"`, the reference P3 item 4 already sets. `ENV_ALLOW`
(`packages/seat/src/session.mjs`:242) doesn't change.
- In proxy mode that variable holds only the session's own proxy key, because P3 item 2 drops the instance's
provider variables.
- `models.json` never holds a key value, and no value in it starts with `!`.
**4c. Tests.** These add to P3's Tests list:
- the `models.json` content for each of the three routes;
- every `apiKey` in `models.json` is the `$ANTHROPIC_API_KEY` reference;
- no key value appears anywhere in the file;
- no value in the file starts with `!`;
- an offline pi turn through the pinned proxy under `unshare -rn` for the GLM route, against a stand-in
upstream, the way row 96 and P1's acceptance run did. It runs from a script outside the gate's
`scripts/test-*.sh` set, and its output goes in BUILD.md as plain text.
The Codex route can't run offline without a real auth file, and no agent touches one. Its first real turn is
row 209 phase A step 7 (`docs/plans/2026-10-24_row209-hub-54-window.md`). BUILD.md says so.
BUILD.md also records whether the z.ai compat fields survive through the proxy, or whether the proxy drops
them, from the offline GLM turn.
**4d. One proxy per user (settled, mos-1616).** Unless P2 item 7 finds that the pinned proxy can limit a
client key to some models, Bean's key can reach Chet's ChatGPT login through the same proxy, and Chet's key
can reach Bean's Z.ai key. Mos accepted that for .54. Q249 sets one proxy per user and their agents, so both
agents and both accounts on .54 are Melanie's. If P1 found no per-key model limit, the bundle's model choice
stays the guard. If P1 found one, P2 narrows each key as P2 item 7 says. This row changes neither.
**Gate additions.** One more named mutant: `models.json` gets the key value instead of the
`$ANTHROPIC_API_KEY` reference. The 4c tests must kill it. The rest of P3's Gate stands: Gladstone's first
Codex review, Dewey's landing review, every touched test file whole, every package suite but queue plus
every `scripts/test-*.sh` green on Sage's landing gate, and the mutant where proxy mode still passes
`CLAUDE_CODE_OAUTH_TOKEN`.
**Start and landing (mos-1616 ruling 5).** P3 may start now on a new Codex gpt-6.1-sol thread and worktree,
building against P2's interface `{ baseUrl, key }` (P3 item 1). It lands only after P1 (row 329) and P2
(row 331) land, and after its own gate (mos-1351). It rebases on both before that gate. The run list for
every whole-file run comes from imports and goes in the builder's report before the run.
`packages/cli/tests/case1-accept.test.mjs` stays off unless Mos approves (mos-1612).
+150
View File
@@ -0,0 +1,150 @@
# Brief: row 330 (P4), the Console proxy page
Written 2026-10-24 by Sage for Mos's mos-1606, which carries Jason's Q46 and Q47 answers (DECISIONS Q250).
Mos approved it in mos-1608, adding upstream API keys (item 4) and the account id rule (item 2).
Read the design (`docs/plans/2026-10-24_stack-model-proxy.md`, amended for Q250) and the rows doc
(`docs/plans/2026-10-24_model-proxy-rows.md`) first. The rows doc's "Rules for every row" apply here
unchanged. Line numbers are at origin/refactor 0ce22dde6. Check them before you edit.
This brief replaces two parts of the rows doc:
- its P4 brief (the `/proxy/` forward to the upstream panel, rows doc :118-182), which is dropped with D8;
- P1's two panel acceptance bullets (rows doc :104-108). P1's finding on the OAuth callback URL for Claude
and Codex still counts, and this row uses it.
The rows doc isn't edited, because every row from 329 to 333 pins that file's blob and row 329 is near its
landing. The P4 brief lives here instead.
## Brief: P4 the Console proxy page
**Why.** Q250: Jason enters accounts in the Console's own proxy page, not in the upstream panel. That
covers both his OAuth accounts and his API keys (Q248 item 1, Q249, mos-1608). The page calls bus routes,
and the bus calls the proxy's management API (D12). The management key stays in the bus (D6). No new
hostname is added. A panel subdomain is a fallback only if our page can't keep up with the
management API across pinned proxy upgrades, and that call is Jason's (Q46).
**What ships.**
1. **Bus verbs.** New broker verbs for the page, for example `proxy.accounts`, `proxy.login.start`,
`proxy.login.submit`, `proxy.login.status`, `proxy.login.cancel`, `proxy.apikey.add`,
`proxy.priority.set` and `proxy.keys`. Settle the names in BUILD.md.
- Every verb is human-only. A tester, agent or granted-user caller refuses `human-required`, the way
the grants admin verbs do (`packages/bus/src/broker.mjs`:3721-3731).
- With no proxy in the validated config (P1 item 3), every verb refuses `not-configured`.
- Each verb calls the management client from P1 (`packages/model-proxy/src/client.mjs`). P4 adds the
calls it needs under P1's rules: the key goes only in the `Authorization` header, only to loopback,
and each call writes a receipt with no body and no secret.
- A proxy that doesn't answer refuses `proxy-down`, with no retry.
2. **Accounts.** `proxy.accounts` lists the upstream accounts from the pinned version's credentials
endpoint (`/credentials` in the 8.0.27 doc,
`agents/researcher/work/i1-proxy-test/docs/management-api-v8.0.27.md`:101).
- The bus copies only allowlisted fields: provider, a display name, status and priority, plus an
account id. Every other field is dropped, so no token can pass through even if the proxy returns one.
- The account id is the first 12 hex of the sha256 of the proxy's own credential identifier, never of a
token or key value (mos-1608).
- Record in BUILD.md which endpoint and fields the pinned version has.
3. **OAuth sign-in** through `oauth/auth-url`, `oauth/callback` and `oauth/status`
(management-api-v8.0.27.md:108-138).
- **Start.** The page picks a provider from an allowlist: `claude` and `codex`. Adding a provider is a
reviewed change. The bus calls `auth-url` and returns the authorization URL and the `state`. The page
opens the URL in a new tab with `noopener` and `noreferrer`.
- **Return.** After Jason signs in, the provider redirects to the callback URL that the proxy named.
P1's acceptance records that URL for each provider. If the redirect reaches the proxy directly, the
status poll shows the result. If it doesn't, Jason pastes the full URL from the address bar into the
page, and the bus POSTs it to `oauth/callback` as `redirect_url`.
- **Checks on a pasted URL.** It must parse as a URL, stay under a size limit, and carry a `state` that
this bus started and that hasn't finished. Anything else refuses `login-state-unknown` or
`callback-url-invalid`. The URL carries the authorization code, so it is never logged, stored or
echoed back.
- **Status.** Only an `ok` from `oauth/status` counts as signed in. An accepted callback with status
`wait` doesn't, because the doc says acceptance isn't completion (:136-138). The bus stops polling
on `ok`, `error`, or after a timeout setting (default 300 s).
- **Cancel** calls `DELETE oauth/session`.
4. **Upstream API keys** (mos-1608). A human-only verb (for example `proxy.apikey.add`; name it in
BUILD.md) adds one upstream API key.
- The provider allowlist starts with z.ai only. Adding a provider is a reviewed change. BUILD.md records
which management endpoint the pinned 8.0.42 uses for it.
- The Console route has the same checks as the other writes (item 8). The page's input is
`type=password` with `autocomplete=off`.
- The value is write-only. Neither the Console nor the bus logs it, stores it, caches it, or puts it in
a receipt or an error. No part of it is echoed, not even the last four characters. The bus passes it
straight to the management API in the request body and then drops it.
- After the add, the key shows in `proxy.accounts` through the same allowlisted fields, and priority
(item 5) works on it.
- An empty value, one over a size limit, or one outside a charset refuses `apikey-invalid`. A provider
outside the allowlist refuses `provider-not-allowed`.
5. **Priority.** `proxy.priority.set` sets one account's priority, an integer in a range the builder
records. Use the pinned version's credential-field endpoint (`/credentials/fields` PATCH in the 8.0.27
doc). Confirm it on the stand-in and record what it changes. A bad account id or value refuses
`priority-invalid`.
6. **Client keys, list only.** `proxy.keys` reads `GET /config/access/api-keys`, maps each value to its key
id in memory and drops the value (D15).
- It joins P2's record to show agent, issue time and state for each key id.
- The sentinel is labelled. A key without this instance's prefix shows as "not stack-managed".
- The page has no key write. Issue and revoke stay with hire and fire (P2).
7. **Usage.** P5's Console view (rows doc P5 item 3) sits on this page. Whichever of P4 and P5 lands
second puts it there. P4 adds no usage source.
8. **The page and its Console routes.** An owner-only `/proxy` page in `packages/webui`, built like the
existing pages, with routes under `/api/proxy/`.
- Each route makes one call over the owner's human transport, the way the Agents section does
(`AGENT_ROUTES` at `packages/webui/src/serve.mjs`:451, `agentCaller` at
`packages/webui/src/console-bus.mjs`:12). `consoleBus` gets a `PROXY_VERBS` list, and the caller
refuses any other verb.
- Writes need a signed-in owner, the Console's own `Origin`, `sec-fetch-site: same-origin`, `--send`
and a named host, as `agentSend` checks (`serve.mjs`:459-470). The routes are refused for a granted
user (`userRoute`), on the tester listener and on a loopback Host.
- The Console never holds the management key, never reads `proxy` from the config, and never opens a
connection to the proxy port.
- Logs record method, route, status and user only. They never record the authorization URL, a pasted
callback URL, a state, an API key or a body.
9. **Upgrade check.** An acceptance script, beside P1's and outside the gate's `scripts/test-*.sh` set,
runs the bus verbs against the pinned binary under `unshare -rn`. It uses a made-up config, key and
data root in a fresh temp root, the same way P1's run does.
- With no network, it checks what can be checked offline. The account list starts empty. `auth-url`
returns a URL and a state for `claude` and for `codex`. A callback with a made-up code never reports
`ok`. A made-up z.ai API key added through the verb shows in the account list, and a priority set on
it reads back. The key list returns ids only.
- It prints the endpoints and fields the page relies on, so a version change shows up as a diff.
- `packages/model-proxy/README.md` records the rule: a PIN change lands only with this script's output
for the new version in that row's BUILD.md, and Sage's landing gate checks for it.
- If the script fails on a new version and the row can't fix the page, the row stops. Sage takes Q46's
fallback to Jason through Mos.
**Tests.** Cover each of these:
- every verb against a fake management server;
- each refusal code by its own test (mos-1590): `not-configured`, `human-required` for the tester, an
agent and a granted user, `provider-not-allowed` for sign-in and for an API key, `login-state-unknown`,
`callback-url-invalid`, `apikey-invalid` (empty, over the size limit and outside the charset, each its
own case), `priority-invalid` and `proxy-down`;
- an API-key canary: a unique made-up value goes through the Console route against the fake management
server. Afterwards every Console and bus log, receipt, response, store file and error output from that
run has zero matches for it, and the fake received it exactly once;
- an added API key listed by `proxy.accounts` with allowlisted fields only, and priority set on it;
- account ids derived from the credential identifier, with a fake whose token values never appear in an id;
- a fake that puts token-like values in every credential field, where no value reaches a response, log or
receipt;
- a fake key list with full values, where only ids come back, the sentinel is labelled and a foreign key
is marked;
- no authorization URL, callback URL, code or state in any log or receipt;
- an accepted callback with status `wait` not reported as signed in;
- the Console routes: owner allowed, and a granted user, the tester listener, a loopback Host, a
signed-out request, a cross-origin request and a request without `sec-fetch-site` each refused, and
every write read-only without `--send`;
- no `packages/webui` module imports the model-proxy client or reads the `proxy` config.
**Out of scope.**
- Removing or disabling an account. Mos is filing a Vikunja task for a later row (mos-1608).
- Every routing setting other than account priority.
- Issuing or revoking client keys (P2), and any usage source (P5).
- The upstream panel, any forward to the proxy port, and the subdomain fallback.
- Traefik, DNS, Authentik settings, and the .54 Console's provider (Q218).
- Any live instance, the management key, and the 8317 proxy.
**Order.** P4 starts when P1 lands, because it needs P1's client and config contract. It rebases on P2
before its gate, for the key join, and lands after P2.
**Gate.** Gladstone gives the first Codex review, and Filbert reviews the landing candidate. The model-proxy,
bus and webui suites run whole, webui with `MOSAIC_REQUIRE_EDITOR_BUILD=1`. Every touched test file runs
whole. The named mutants below are killed. Every package suite but queue plus every `scripts/test-*.sh` is
green on Sage's landing gate. BUILD.md has the upgrade-check output on the pinned version. Mutants: the
accounts verb returns an unfiltered field; the callback verb skips the state check; a `/api/proxy/` route
accepts a granted user; the API-key verb echoes the value in an error or a log.
@@ -0,0 +1,109 @@
# Brief: row 209, the .54 window with its own proxy
Written 2026-10-24 by Sage for Mos's mos-1615, which carries Jason's "Q54: yes" (DECISIONS Q253). Q253:
.54 waits for its own model proxy. Bean's Z.ai key and Chet's ChatGPT/Codex login both go in through the P4
Console proxy page. Chet runs GPT through his Codex login for 10-27, not GLM, which replaces Q186.
This brief replaces row 209's old brief (`docs/plans/2026-10-20_federation-r1-r2-r5.md`, "Brief: FED R8, the
hub window on 10.1.1.54"). That section isn't edited. Phase D below runs it unchanged. Read the model-proxy
design (`docs/plans/2026-10-24_stack-model-proxy.md`, sections 1, 5, 9 and 10), the rows doc
(`docs/plans/2026-10-24_model-proxy-rows.md`) and the P4 brief (`docs/plans/2026-10-24_proxy-page-brief.md`)
first. Line numbers are at origin/refactor 95d4991d2. Check them before you rely on them.
## Brief: row 209, the .54 window: proxy, Bean's and Chet's accounts, then FED R8
**What this row is.** A live window on 10.1.1.54, not a code row. Jason and Mos run it. Nothing here
authorizes a step on any host. Each step waits for the window's go, and Console start and restart stay
with Jason or Mos (Q173).
**Secrets.** The rows doc's rules apply on .54 too. No agent reads `<configDir>/secrets/proxy-management.key`
or anything under .54's `<dataRoot>/proxy/` (`config.yaml`, `auth/`, `logs/`), and no agent reads Hermes's
auth files or Chet's login in any form (D6, mos-1600 ruling 2). Agents read only what a command prints:
hashes, unit state, refusal codes and the proxy page's allowlisted fields.
### Entry checks, all before phase A
1. P1 (row 329), P2 (331), P3 (332) and P4 (330) have landed and passed Sage's landing gate. P3 carries the
amendment for pi's GLM and GPT routes that Mos rules on (sage-4285). Without it P3 proves only the
Anthropic route.
2. **Gap to close first.** `.54` installs through `scripts/case2-install.sh` and `scripts/case2-unit.sh`.
P1 adds `mosaic-proxy.service` to `scripts/instance.sh` only (rows doc P1 item 7). `case2-unit.sh` writes
no model-proxy unit today, and its bus unit has no `Wants=` or `After=` on one. A code row has to add the
proxy unit to the Case 2 install, with the same sha256 refusal, before phase A. Sage files it once Mos
rules (sage-4285).
3. The .54 stack copy is re-pinned to a commit that holds rows 329 to 332 and the item 2 row.
4. .54's Console signs Jason in through Authentik (Q218). The proxy page's writes need a signed-in owner
(P4 item 8).
5. Phase B has a recorded result, or Chet's login waits for phase C as phase B says.
### Phase A: the proxy on .54
Design section 9, for .54 as the `mosaic` user under `/srv/mosaic` (D1).
1. **Fetch.** P1's pinned fetch runs on .54. Sage compares the printed sha256 values with PIN.
2. **Config and key.** Jason adds the `proxy` section to .54's `config.json` in an editor (J2), runs
`mosaic proxy init` in his own terminal (J3) and starts the proxy unit.
3. **Bean's key.** Jason pastes Bean's Z.ai API key into .54's proxy page (J4, P4 item 4) and sets its
priority. The page never shows it again.
4. **Chet's login.** Only after phase B passes. Jason signs the proxy in to Chet's ChatGPT/Codex account
through the page's own OAuth flow (P4 item 3). The proxy holds a sign-in of its own. Nobody copies
Hermes's auth file.
5. **Business settings.** Bean's and Chet's `launch.models` name provider `proxy` (P3 item 5): Bean on his
GLM model, Chet on his GPT model, with the model ids the proxy's `/v1/models` lists. The edit goes in
through the human path that P3's BUILD.md names.
6. **Restart.** Jason or Mos restarts the bus and Console. The bus reconciles, issues a key for each agent
(P2) and runs D17's preflight for each one. Any refusal stops phase A. The fix is to remove the section
and restart.
7. **One real turn per route.** The tester actor launches one pi session for Bean (GLM through the Z.ai key)
and one for Chet (GPT through the Codex login). Each makes one real turn through the proxy. Jason
watches the proxy page's usage section and confirms each request landed on the account he expects (J5).
The result goes into the row's record with who ran it.
8. **Unit cleanup.** Once both turns pass, the bus unit drops the provider env file per design section 9
step 7. The file stays for the 7-day rollback window.
Rollback at any point: remove the `proxy` section and restart.
### Phase B: two clients on one ChatGPT login
Hermes holds Chet's ChatGPT login until #423 step 5. Before that login goes into the .54 proxy (phase A
step 4), a check has to show that two clients on one ChatGPT login don't revoke each other's refresh tokens
(mos-1615 item 3). Row 229's brief named the same risk for a copied token.
- Two separate sign-ins, never a copied file: Hermes keeps its own, and the proxy gets its own through the
page.
- Pass: each client goes through at least one token refresh, and afterwards Hermes still answers on Chet's
login and the proxy page still lists the account as active. Fail: either one drops out or needs a new
sign-in.
- The check is Jason's. It uses the real account, and no agent reads either client's token or auth file.
Agents record what Jason reports and what the page lists.
- **Open before the window.** I don't know how to make each client refresh on demand without someone reading
a token, or how long ChatGPT's access tokens last. Researcher answers from the pinned 8.0.42 docs and
Hermes's docs: how each side refreshes, whether either can be made to refresh, and how long the check has
to run. The answer goes in this row's record.
- If the check fails, or there's no safe way to run it, Chet's login goes in after #423 step 5, when Hermes
has let go of it. Phase A step 7's GPT turn waits for that, and Chet doesn't go live on GPT until it passes.
### Phase C: Case 2 go-live, then Hermes stops
Bean and Chet go live in Case 2 on the proxy (#416). Hermes stops after that (#423 step 5, mos-1615), and
that stays Melanie's choice (`docs/plans/2026-10-20_case2-rows.md`:1231). If phase B didn't pass, Chet's login goes into the proxy here and phase A step 7's GPT turn
runs before Chet goes live.
### Phase D: FED R8
The old brief, unchanged: entry checks, build notes N1 and N2, and its done condition
(`docs/plans/2026-10-20_federation-r1-r2-r5.md`, "Brief: FED R8, the hub window on 10.1.1.54").
### Done when
Phase A's two real turns are recorded, each on the account Jason expected. Phase B's result is recorded
along with who ran it. Bean and Chet are live on the proxy. FED R8's own done condition holds.
### Out of scope
- Any code change. The item 2 gap and the P3 amendment are code rows of their own.
- The dragon-lin default instance and .53. Their cutovers are P7 and row 246.
- Hermes's server and profiles, beyond Jason's phase B check.
- The 8317 host proxy and `~/.local/opt/EasyCLIProxyAPI`.
- Row 229 (Vikunja 428). The proxy route supersedes it, and the queue parks it with that reason. Its live
check is phase B.
+40 -39
View File
@@ -5,6 +5,12 @@ becomes the stack's credential and routing layer, with Q116 and Q127 still in fo
Mos rules it before any code. Its build rows go to new Codex gpt-6.1-sol threads (Q246), and each gets its own
brief once Mos has ruled. Line numbers are at origin/refactor 2ce476d54.
**Amendments.** Mos's mos-1600, mos-1601 and mos-1602 changes live in the row briefs
(`docs/plans/2026-10-24_model-proxy-rows.md`), which win over this design where they differ. Jason's Q46
and Q47 answers (DECISIONS Q250, mos-1606, 2026-10-24) are written into this file: accounts are entered in
the Console's own proxy page, and the `/proxy/` forward to the upstream panel (D8) is dropped. The P4 brief
for that page is `docs/plans/2026-10-24_proxy-page-brief.md`. Text marked "(Q250)" below is that change.
Not to be confused with queue row 237 ("one decision lands once", `2026-10-20_agent-credentials.md`). This is
Vikunja task 237.
@@ -75,11 +81,13 @@ whose sha256 matches PIN. The control panel asset is pinned the same way, with
(`config.example.v8.0.27.yaml`:94-103), and that would be unreviewed code behind Authentik. The stack never
copies the 8317 binary. The first fetch of the release asset counts as external access, so it is Jason's
step J1 or a row Mos approves. For containerized installs the binary and panel go into the proxy image
(section 8).
(section 8). Q250: nothing serves the panel to the Console now. P1 keeps the pin as built, and
removing it is a later cleanup.
D5. **Initial config, then hands off.** The stack writes `config.yaml` once, when `<dataRoot>/proxy/` is
first created, from a template in `packages/model-proxy/`, and never writes the file again. After that the
stack changes the proxy only through the management API, and Jason changes it only through the panel.
stack changes the proxy only through the management API, and Jason changes it only through the Console's
proxy page, which calls the bus, which calls the management API (Q250).
Row 96 point 2 (every management write rewrites the whole file and reorders it) then stops mattering,
because nobody edits the file by hand. The template sets the defaults in section 3 and section 7,
`request-retry: 0` so no hidden retries happen (as in row 96), the client-key list holding only the
@@ -93,31 +101,23 @@ prompt doesn't echo the key. It writes the key to `<configDir>/secrets/proxy-man
the initial `config.yaml`. The proxy hashes it in place on its first start (row 96 point 6). The stack reads
only the secrets file, never the hashed value in config. The holder is the bus process alone (D12). The
sandbox doesn't mount `<configDir>/secrets`, so no session can read the key, and no verb returns it. Jason
types the same key into the panel to sign in. An agent never runs the prompt (Q173).
types the key only at that prompt. The Console's proxy page needs only his Console sign-in, and the bus adds
the key to its own management calls (Q250). An agent never runs the prompt (Q173).
D7. **Upstream credentials.** Jason adds every upstream account in the proxy's own panel: OAuth sign-ins
(Claude, Codex and the others CLIProxyAPI supports) and API keys (for example z.ai). They live in the
D7. **Upstream credentials.** Accounts are entered in the Console's proxy page (Q250). It covers OAuth
sign-ins for Claude and Codex through the management API's `oauth/auth-url`, `oauth/callback` and
`oauth/status`, upstream API keys (z.ai first, write-only and never echoed, mos-1608), and account
priority. The page shows each account by an id, the first 12 hex of the sha256 of the proxy's own
credential identifier, never of a token or key value (mos-1608). The credentials live in the
proxy's `auth/` directory and config and nowhere else. There is no per-seat credential file. The stack never
reads, copies or logs an upstream credential.
D8. **Panel path.** The Console forwards `https://mosaic.woltje.com/proxy/` to `127.0.0.1:<proxy.port>`, for
the panel route and the management routes only. It forwards only after its existing auth-header and
allowed-user check (decision 103, `packages/webui/src/serve.mjs`:453-469) passes. The Console never adds or
stores the management key. Jason types it in the panel, and it passes through the forward. This adds no DNS
record and no subdomain, as Q116 requires. Traefik and the tunnel already deliver mosaic.woltje.com to the
Console (7332), so no infra change is needed. The forward gives no new authority. The management key
is the barrier, and loopback processes can already reach the proxy port. Authentik is the outer layer. The
#385 hole (a loopback process forging the Host and header) applies here the same way and is no worse,
since the management key is still required.
A second Console (.54) forwards to its own instance's proxy, and its Authentik provider settings are Jason's
(Q218).
Checks for the build row, on a stand-in under `unshare -rn` as in row 96:
- the pinned panel works under the `/proxy/` sub-path (rewrite or base-path setting);
- an OAuth sign-in done from the panel through the forward completes. If the callback can't return through
the forward, the fallback is Jason running the proxy's CLI login in his own shell (`-claude-login
-no-browser` and similar), and J3 says so.
D8. **Dropped (Q250).** The design had the Console forward `https://mosaic.woltje.com/proxy/` to the
proxy's own panel. Jason's Q46 and Q47 answers replace it with the Console's own proxy page (D7). The page
calls bus routes, the bus calls the management API (D12), and the management key stays in the bus (D6). No
new hostname is added. A panel subdomain is a fallback only if our page can't keep up with the management
API across pinned proxy upgrades, and that call is Jason's. Each pinned upgrade runs the page's acceptance
script against the new version (P4 brief item 9).
## 3. Priority routing, and how the business routing table maps onto it
@@ -131,10 +131,12 @@ The proxy picks which upstream account serves that model. The two don't overlap:
- Account failover inside one model is the proxy's job. The stack doesn't model accounts per session.
D10. **Priority settings.** Defaults set in the template are listed below (Q222: settings with defaults).
Jason can change all of them in the panel.
Jason sets account priority in the Console's proxy page. The other routing settings keep the template
defaults, and a page control for them is a later row (Q250).
- `routing.strategy: fill-first`. A subscription account is used until it is rate-limited or out of quota, then
the next one (`config.example`:150).
- Each account gets a `priority` (larger first, `config.example`:480). Jason sets the order in the panel (J4).
- Each account gets a `priority` (larger first, `config.example`:480). Jason sets the order in the Console's
proxy page (J4).
- `routing.session-affinity: true`, so a session stays on one account while it works and keeps its prompt
cache (:154-171). Default `session-affinity-rebind-on: quota`, so a transient 5xx doesn't move a session.
- No model aliases or alias pools by default. A pool that maps one name to several upstream models
@@ -270,7 +272,7 @@ D20. **Settings and who changes them.** Every number in this design is a setting
`rotateBy` 30 d, `proxy.rotateGraceMinutes` 120, `proxy.firstOutputSeconds` 120, `usage.cliproxyQueue.pollSeconds`
15, routing strategy fill-first, affinity on. The per-key daily quota and the rotation period guard the human
from agents, so only a human can change them (Q222). The routing settings live in the proxy and only Jason
changes them, in the panel.
changes them. Account priority is in the Console's proxy page, and the rest keep their defaults (Q250).
## 8. Row 157 re-scope (#1652, Vikunja 617)
@@ -297,7 +299,7 @@ changes. Cutover, per instance, with Jason present (Q127):
2. Jason fetches and verifies the pinned binary and panel (J1). ops-01 or Sage checks the sha256 against PIN.
3. Jason adds the `proxy` section to the instance config (J2), runs `mosaic proxy init` (D6), and starts
`mosaic-proxy.service`. The bus isn't restarted yet.
4. Jason signs in to the panel and adds the accounts (J3, J4). No session uses the proxy yet.
4. Jason adds the accounts in the Console's proxy page (J3, J4). No session uses the proxy yet.
5. A Console or bus restart (Jason or Mos, per Q173) picks up the section. The bus reconciles, issues a key
for each listed agent, and runs D17's preflight for each one. Any refusal stops the cutover, and the fix
is to remove the section and restart.
@@ -318,15 +320,14 @@ accounts (J7). The 8317 host proxy and its clients are not part of any step.
- **J2.** Add `"proxy": { "port": <port from the cutover note>, "binary": "<path>" }` to the instance's
`config.json`, in an editor.
- **J3.** In a terminal of your own, run `mosaic proxy init` and type a new management key twice. Keep it in your
password manager. Then open `https://mosaic.woltje.com/proxy/` and sign in to Authentik as jason.woltje.
Paste the management key into the panel's login box.
- **J4.** In the panel's auth or OAuth page, sign in to each subscription account you want this instance to use
(Claude, Codex, and so on). On the API keys page, paste each API key you want it to have (for example z.ai).
Set each account's priority. The highest one is used first, and the next one only when the first is
limited. If an OAuth sign-in doesn't return to the panel, run the CLI login the cutover note gives, in your
own terminal.
- **J5.** Watch the Console while the two test sessions run (cutover step 6), and confirm the panel's usage page
shows their requests on the account you expect.
password manager. You don't type it anywhere else (Q250).
- **J4.** Open the Console's proxy page and sign in to Authentik as jason.woltje. Sign in to each subscription
account you want this instance to use (Claude, Codex). If the sign-in tab doesn't return on its own, copy
the full address from that tab and paste it into the page. Set each account's priority. The highest one is
used first, and the next one only when the first is limited. Paste each API key you want it to have (for
example z.ai) into the page's API-key field. The page never shows it again.
- **J5.** Watch the Console while the two test sessions run (cutover step 6), and confirm the proxy page's usage
section shows their requests on the account you expect.
- **J6.** After 7 days on the proxy, delete `claude-session.env` for that instance.
- **J7.** For Melanie's .54 hub, decide which accounts it uses: hers, yours, or new ones. Then do J2 to J4 on .54
through its own Console's Authentik provider (Q218). Only accounts you entered for that hub go into its
@@ -339,10 +340,10 @@ credentials, so a Claude reviewer (Dewey) gives the second review. Sage runs the
| Row | Piece | Depends on |
|---|---|---|
| P1 | `packages/model-proxy/`: PIN, template, management client, `mosaic proxy init`, the `mosaic-proxy` unit, config `proxy` section, stand-in tests (empty list, `/v1/models` local, 401 shape, panel sub-path, OAuth through the forward) | Mos's ruling on D3 |
| P1 | `packages/model-proxy/`: PIN, template, management client, `mosaic proxy init`, the `mosaic-proxy` unit, config `proxy` section, stand-in tests (empty list, `/v1/models` local, 401 shape, OAuth callback URL; the panel checks are dropped, Q250) | Mos's ruling on D3 |
| P2 | Per-agent keys: `model` store kind, issue, rotate, revoke, reconcile, D17 preflight | P1, rows 194 and 199 |
| P3 | Harness config: Claude Code env, pi `models.json` and preflight, `sessionEnv` proxy mode | P2 |
| P4 | Console `/proxy/` forward behind the existing auth check | P1 |
| P4 | The Console proxy page and its bus verbs (Q250, `2026-10-24_proxy-page-brief.md`) | P1; lands after P2 |
| P5 | `usage` plug-in kind and the `cliproxy-queue` module; key ids in `launch.limits.tokens` | P2 |
| P6 | Row 157 brief amendment (section 8) | Row 157 resuming |
| P7 | Cutover note and per-instance window (section 9) | P1 to P4 landed; Jason present |
@@ -353,7 +354,7 @@ The Codex harness config (D16) goes with the Codex harness row, which isn't on t
1. D1/D3: the `proxy` section in the instance config (a schema change), and the proxy as its own user unit.
2. D6: the management key set by Jason at a human-only prompt and held only by the bus process.
3. D8: the Console forwards `/proxy/` rather than a new Traefik route.
3. D8: ruled. Jason's Q46 and Q47 (Q250) drop the forward for the Console's own proxy page.
4. D13: an implicit per-agent model key with no role-file change.
5. D15: plaintext keys at rest accepted under those limits.
6. D16: proxy mode drops the instance-wide provider variables from every session.
+6
View File
@@ -96,6 +96,12 @@ suite by design and runs through a script puts that entry in the brief's
Gate and in BUILD.md with the row, and the lead adds it to the landing
gate's list. Any unlisted skip stays RED.
A builder's list of whole test files to run for a row comes from imports,
not from a text grep for a path, and goes in the builder's report before
the run. A file on the mos-1592 list (`packages/cli/tests/case1-accept.test.mjs`
for now) stays off the list unless Mos has approved that run (mos-1612,
after row 329's round 2 grep matched fixture text and reran the F7 file).
Any row that builds businessDoc() with a library project sets the chief's
gitea ref in its fixture (mos-1584, after row 285 gave the chief of staff
a read-scoped gitea credential that the validator requires when a business
+14 -8
View File
@@ -33,7 +33,7 @@ Gaps found while working go to `docs/plans/DEFERRED.md`, not here.
<!-- mosaic-queue:begin -->
Generated from `docs/plans/queue.json` revision 3945 by `queue render`. Do not edit between the markers; change the queue with `scripts/mosaic queue`.
Generated from `docs/plans/queue.json` revision 4020 by `queue render`. Do not edit between the markers; change the queue with `scripts/mosaic queue`.
| # | Piece | Owner | Issues | State | After | Gate | Brief | Note |
|---|---|---|---|---|---|---|---|---|
@@ -260,10 +260,10 @@ Generated from `docs/plans/queue.json` revision 3945 by `queue render`. Do not e
| 221 | Case 2 C2-20 Bean and Chet persona import, with a count-only dry run | gosalyn; reviewers webby | #1722 | done | — | Webby approves the manifest. The test file runs green on its own and the cli suite is green on Sage's gate, along with every `scripts/test-*.sh`. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-20 Bean and Chet persona import, with a count-only dry run | LANDED 300766450, pushed. Cand 8f403d0d4, manifest 20f05e3a6ad5, 22 paths, verify-commit ok, patch-id dfbb754c6fb4 equals 62ddc96cc..8f403d0d4. Gate 11:07:50-11:19Z on b1fece6f0: test file alone 11/0, harness 140/0, cli 677/0, all scripts green. Brief Gate met: webby-0073 approve, test file alone, cli, scripts. No live run in the Gate; the import itself waits on Jason. N1 N2 N4 go to C2-20b, N3 to DEFERRED. |
| 222 | Case 2 C2-03a fetch-only sync | megavolt; reviewers dewey | #1723 | done | — | Dewey approves the manifest. The library and bus suites are green on Sage's gate, along with every `scripts/test-*.sh`, and the mutant is killed. A search of the test run's output for the fixture token finds nothing. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-03a fetch-only sync | sage-2024 on megavolt-0089: core.createObject=rename in the fetch argv is accepted as a brief departure, since C2-04 inspectMirror refuses nlink 2. Dewey checks it. The askpass env keys, export SAFE in project/src/git.mjs, bus/tests/library-sync.test.mjs and the SURVEY-RUN user line are accepted. The 5 s client timeout residual goes in BUILD.md and Dewey rules fix or defer. Slot after 197 proof 3 and the 249 gate. |
| 223 | Case 2 C2-07 runner retry on a guard refusal, and the runner's notices | researcher; reviewers filbert | #1724 | blocked (from briefed): Q226: C2-07 folded into C2-06 (row 217). No work here; Jason parks it. | — | Filbert approves the manifest. The harness suite is green on Sage's gate, along with every `scripts/test-*.sh`. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-07 folded into C2-06 | — |
| 224 | Case 2 C2-05b broker lookup verbs and typed tools | della; reviewers dewey | #1725 | in-progress | 216 done | Dewey approves the manifest. The bus and harness suites are green on Sage's gate, along with every `scripts/test-*.sh`. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-05b broker lookup verbs and typed tools | — |
| 225 | Case 2 C2-10b Console chat: replies, citations, write notices and the status line | fethry; reviewers dewey | #1726 | briefed | 217 done | Dewey approves the manifest. The webui suite is green on Sage's gate, along with every `scripts/test-*.sh`. Grep for hash pins on `bus.js` and `serve.mjs` before in-review. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-10b Console chat: replies, citations, write notices and the status line | — |
| 224 | Case 2 C2-05b broker lookup verbs and typed tools | della; reviewers dewey | #1725 | done | 216 done | Dewey approves the manifest. The bus and harness suites are green on Sage's gate, along with every `scripts/test-*.sh`. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-05b broker lookup verbs and typed tools | LANDED 5e77cdd09 19:18Z 10-24 (13 Della commits on 7fe32d722). Gate GREEN 19:16:37Z on 27624aa66, drift docs-only. Dewey APPROVE c31619. #1725 closed c31623. |
| 225 | Case 2 C2-10b Console chat: replies, citations, write notices and the status line | fethry; reviewers dewey | #1726 | done | 217 done | Dewey approves the manifest. The webui suite is green on Sage's gate, along with every `scripts/test-*.sh`. Grep for hash pins on `bus.js` and `serve.mjs` before in-review. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-10b Console chat: replies, citations, write notices and the status line | LANDED 9b6345466 on refactor, pushed 15:55:22Z: fethry r2 c1f9dfd3c cherry-picked onto c63801959, 8 commits equal by range-diff and 3 differ only in log hunks (both sides kept), 13 manifest paths match 517af41b. Dewey APPROVE c31599 rev 3960, request c31600. Sage gate GREEN 15:54:58Z: every package suite but queue 0 fail (webui 442, cli 988+1 allowed FED R7 skip), 12 scripts rc 0. #1726 closed c31604. |
| 226 | Case 2 C2-13 install script and precheck for the host | gosalyn; reviewers webby | #1727 | done | 215 done, 221 done, 222 done, 230 done | Webby approves the manifest. The test file and the cli suite are green on Sage's gate, along with every `scripts/test-*.sh`. The run on the host is a separate window with Jason's go. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-13b install script and library precheck | landed 661890e90 (replay of bfed0aa6c 893b4fd25 f3fabf51b onto 8352da88c, patch-ids equal, four blobs and modes equal to f3fabf51b) and fd3d2a99f (Darkwing 8a6321790 replay, mos-1519), tree 78fc5ad21 equals merge-tree. Webby APPROVE rev 3641. Sage gate GREEN 19:56Z on f3fabf51b: 17 package suites and 10 scripts, 0 fail. Webby N1-N4 DEFERRED e2b873390. #1727 closed. |
| 227 | Case 2 C2-14 end-to-end acceptance on a scratch root | gizmoduck; reviewers dewey | #1728 | in-progress | — | Dewey runs the script and approves. It is green on Sage's gate with every `scripts/test-*.sh`. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-14 end-to-end acceptance on a scratch root | — |
| 227 | Case 2 C2-14 end-to-end acceptance on a scratch root | steelbeak; reviewers dewey | #1728 | in-progress | — | Dewey runs the script and approves. It is green on Sage's gate with every `scripts/test-*.sh`. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-14 end-to-end acceptance on a scratch root | — |
| 228 | Row A: ZAI_API_KEY passes through ENV_ALLOW to sessions, README line, pass-through test (XS, Haiku high) | researcher; reviewers webby | #1729 | done | — | Webby approves the manifest. The mutant is killed. The seat suite and the cli suite are green on Sage's gate with every scripts/test-*.sh. (sage) | `docs/plans/2026-10-20_case2-rows.md` § Brief: row A, ZAI_API_KEY in the session env allowlist | Landed 86249ac55 (pushed 07:25Z) on 59f817c32: the 3 manifest paths from cf18c42b9. Patch-id b6ffe31feb0d equals the candidate's; modes and blobs match; verify-commit ok (3 paths). Sage's combined 228+238 gate on c515273db plus both rows' 6 paths, 07:11:30Z to 07:23:34Z: seat 165/0, cli 640/0, all ten scripts/test-*.sh 585/0. |
| 229 | Row B: per-instance pi agent dir for Chet's Codex login, design only, starts after 10-27 (#428) | gosalyn; reviewers webby | #1730 | briefed | — | A live check, with Jason's or Mos's go, that two clients on one ChatGPT login don't revoke each other's refresh tokens. No build row starts before it passes. Held until after 10-27. (sage) | `docs/plans/2026-10-20_case2-rows.md` § Brief: row B, a per-instance pi agent dir for Chet's Codex login (#428) | — |
| 230 | Case 2 C2-13a unit render and host precheck (case2-unit.sh, case2-precheck.sh) | gosalyn; reviewers webby | #1732 | done | — | Webby approves the manifest. The test file and the cli suite are green on Sage's gate, along with every scripts/test-*.sh. A run on a host is a separate window with Jason's go. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-13a unit render and host precheck | Landed c8bc5cf4c on refactor (base 390ea5261), pushed. Patch-id f4b49eb68997 matches git diff 722136772..96768766c on the 5 manifest paths (manifest fbb0d7e42c67, Webby approve r2 rev 2563). packages/cli/README.md 3-way with row 199, hunks apart. Gosalyn gate on 96768766c: cli 541/0, scripts 429/0, mutants 10/10. Merged tree check: case2-unit 30/0, host 42/0. |
@@ -293,7 +293,7 @@ Generated from `docs/plans/queue.json` revision 3945 by `queue render`. Do not e
| 254 | Library sync follow-up: client timeout, STATUS codes, README (222 deferrals, #1759) | megavolt; reviewers dewey | #1759 | done | 196 done | Dewey approves the manifest; bus, library and webui suites whole and every scripts/test-*.sh green on Sage's slot; the timeout and STATUS mutants killed (sage) | `docs/plans/2026-10-21_library-sync-followup.md` § Gate | Landed 331597709 (candidate b31300d79 blobs and modes on 41b0cf755; patch-id 96216216 equal, range-diff differs only in the message) plus doc eb9672c91 (Dewey N1 README sentence closed; N2 four 502 codes to DEFERRED, binding the Console library routes row). Merged-tree rerun on Sage's slot 23:44-23:55Z: library 77/0, bus 628/0, webui 305/0 with 1 skip, cli 749/0. Megavolt's gate megavolt-0102 covers scripts and both mutants. |
| 255 | Bundled Pocket ID for users with no OIDC provider, design (Q203, #1760) | launchpad; reviewers webby | — | queued | 252 done | Webby approves DESIGN.md; design only, build rows follow after Sage checks it against Q203, O6, REQ-WEB-2 and REQ-INST-1 (sage) | `docs/plans/2026-10-21_bundled-pocket-id.md` § Gate | Vikunja 458, Gitea #1760, mos-1202 item 2. REQ-INST-2 lands in PRD 1.10 as post-v1 (mos-1204). Design only: no install, no download, no .53/.54, dragon-lin keeps Authentik. |
| 256 | the human deletes a creative instance; any other actor refused, fire unchanged (REQ-COS-3, before the v1 tag) | honker; reviewers webby | #1761 | done | 194 done | Webby approves the manifest; touched test files whole plus business, bus, cli and webui suites and every scripts/test-*.sh green on Sage's slot; both mutants killed (sage) | `docs/plans/2026-10-21_creative-delete-human.md` § Brief: the human deletes a creative instance (REQ-COS-3, after row 194) | LANDED f12441d4f ff from 0165be266 (4 Honker commits, patch-id b28e6374). Webby APPROVE manifest-r3 01eb75aa (10 paths), request c30518. Gate 10:33-10:52Z: 4 touched files 31/0, 18 packages 3757/0 (bus 788, business 231, cli 832, webui 335), 10 scripts rc=0, mutants M1-M4b killed; skips named, env only (webui esbuild pin, test-queue root, test-task live x2). Overlap 13/257 clean. Lands before the 10-27 v1 tag. |
| 257 | Q198 S1: pressure parser and pure rules evaluator (post-v1) | morgana; reviewers filbert | #1762 | in-review, round 2, request posted | — | Reviewer approves the manifest; touched test files whole plus the package suite green on Sage's slot; both brief mutants killed (post-v1, MVP keeps slot priority) (sage) | `docs/plans/2026-10-21_post-v1-row-briefs.md` § Brief: Q198 S1 pressure parser and pure rules evaluator | — |
| 257 | Q198 S1: pressure parser and pure rules evaluator (post-v1) | morgana; reviewers filbert | #1762 | done | — | Reviewer approves the manifest; touched test files whole plus the package suite green on Sage's slot; both brief mutants killed (post-v1, MVP keeps slot priority) (sage) | `docs/plans/2026-10-21_post-v1-row-briefs.md` § Brief: Q198 S1 pressure parser and pure rules evaluator | Landed 73692e1bb, pushed 17:41:58Z 10-24: Morgana's 4 commits cherry-picked onto 487500a16, patches unchanged; 9 supervisor paths match Filbert r2 manifest b176a88f (APPROVE c30190, rev 3037). Gate RED 17:20Z (webui row278 sign-out timing, old test, row touches no webui), full rerun GREEN 17:41:11Z, cli skip FED R7 allowed. push-check clean. #1762 c31613, closed. Carry 447286192 lands doc-only. |
| 258 | Email E01: mail PRD addendum draft and schemas (post-v1) | ludwig; reviewers della | #1763 | in-progress | — | Reviewer approves the manifest; the row's named tests whole plus the mail suite and touched suites green on Sage's slot; reviewer-named mutants killed (post-v1, MVP keeps slot priority) (sage) | `docs/plans/2026-10-21_post-v1-row-briefs.md` § Brief: E01 mail PRD addendum draft and schemas | — |
| 259 | Email E03: mail ledger, state and quotas (post-v1) | unassigned | #1764 | queued | 258 done | Reviewer approves the manifest; the row's named tests whole plus the mail suite and touched suites green on Sage's slot; reviewer-named mutants killed (post-v1, MVP keeps slot priority) (sage) | `docs/plans/2026-10-21_post-v1-row-briefs.md` § Brief: E03 mail ledger, state and quotas | — |
| 260 | Email E04: bounded MIME parsing and quarantine (post-v1) | unassigned | #1765 | queued | 258 done | Reviewer approves the manifest; the row's named tests whole plus the mail suite and touched suites green on Sage's slot; reviewer-named mutants killed (post-v1, MVP keeps slot priority) (sage) | `docs/plans/2026-10-21_post-v1-row-briefs.md` § Brief: E04 bounded MIME parsing and quarantine | — |
@@ -302,7 +302,7 @@ Generated from `docs/plans/queue.json` revision 3945 by `queue render`. Do not e
| 263 | Email E07: address and rule evaluator (post-v1) | unassigned | #1768 | queued | 258 done, 259 done, 260 done | Reviewer approves the manifest; the row's named tests whole plus the mail suite and touched suites green on Sage's slot; reviewer-named mutants killed (post-v1, MVP keeps slot priority) (sage) | `docs/plans/2026-10-21_post-v1-row-briefs.md` § Brief: E07 address and rule evaluator | — |
| 264 | T1 item 7: independent sessions, compaction counts and clear context | gizmoduck; reviewers duckworth | #1769 | done | — | The named reviewer approves the manifest. The design's T1-T7 acceptance tests run whole plus every touched suite on Sage's slot; T3 waits on Vikunja 466 (N2, Claude's compaction count format and the managed dataRoot reader). The design's section 6 mutants are killed. (sage) | `docs/plans/2026-10-21_t1-sessions.md` § T1 item 7: independent sessions, compaction counts and clear context | LANDED 84f53540d ff on e479521d3 14:18:23Z, 21 commits = gizmoduck/row264-r13 tip (no rewrite, range-diff identity). Manifest 257408e9 approved Duckworth rev 3214 (c30640). Gate r13 2cc34aef8: 20 files, bus 827, cli 837, webui 345/1 skip, 10 shells; M1-M4 assertion kills (mos-1279 B, M2 4 files). Overlap none (13, 257). N1 actor_run binds row 269; N2 esbuild skip later gate (sage-2695). |
| 265 | Case 2 C2-09b rooms: room.open, room.send with @tags, room.read | goldie; reviewers boyd | #1770 | done | 219 done | Boyd approves the manifest. The brief's tests run whole plus the bus suite and every touched suite on Sage's slot. Grep for hash pins on changed files before in-review. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-09b rooms: room.open, room.send with @tags, room.read | LANDED 200dd396c (cherry-pick of ef4c93853, 50 blobs equal, log appends equal) 05:13Z on full gate 04:57-05:12Z: all package suites except queue 0 fail 0 skip (bus 957, cli 986, seat 218), every scripts/test-*.sh green. Boyd c31501 incl mos-1567 mount read. 22 gzip logs scanned decompressed, clean. #1770 closed c31510. Bundle 02c3c286. |
| 266 | Case 2 C2-10c Console room view: merged timeline and @name completion | researcher; reviewers dewey | #1771 | queued | 225 done, 265 done | Dewey approves the manifest. The webui suite is green on Sage's gate, along with every touched suite. Grep for hash pins on changed files before in-review. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-10c Console room view: merged timeline and @name completion | Haiku high subagent under decision 129. |
| 266 | Case 2 C2-10c Console room view: merged timeline and @name completion | fethry; reviewers boyd, dewey | #1771 | done | 225 done, 265 done | Dewey approves the manifest. The webui suite is green on Sage's gate, along with every touched suite. Grep for hash pins on changed files before in-review. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-10c Console room view: merged timeline and @name completion | LANDED 3e5041b43 18:00:49Z 10-24, patch-ids equal to Fethry b8b26ae4d..6418ec063; gate GREEN 18:00:08Z first run (bus 1000/0, webui 458/0, cli 989+1 FED R7 allowed, 12 scripts rc 0); Boyd c31609, Dewey c31610; #1771 c31615 closed; Dewey N2 T9 race goes to Mos |
| 267 | Case 2 C2-15 hybrid universes: exclusions, pins and the end-to-end crossover | morgana; reviewers filbert | #1772 | queued | 216 done, 217 done, 224 done | Filbert approves the manifest. The brief's tests and the end-to-end crossover run whole plus every touched suite on Sage's slot. Grep for hash pins on changed files before in-review. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-15 hybrid universes: exclusions, pins and the end-to-end crossover | R8 accepted (sage-2218). Webby's R8 noise note (gosalyn-0127) is for the builder. |
| 268 | Case 2 C2-01c playground levels: universe-level prefixes and draft universes | gizmoduck; reviewers webby | #1773 | done | — | Webby approves the manifest. The brief's tests run whole plus the library suite and every touched suite on Sage's slot; the brief's gate grep over packages and docs/case2 finds no library-playground-outside-book. Grep for hash pins on changed files before in-review. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-01c playground levels: universe-level prefixes and draft universes | Landed c27207f6e fast-forward on ce6a96ad6 (1 commit, 9 paths, digest caa0fa4e). r4 is a carry of r3 aca53c4f0: range-diff =, patch-id 2942acc8 equal, blobs equal. Webby APPROVE round 2 on ecd9b35eb stands; carries webby-0112 (r3) and webby-0113 (r4, notes 34e1ab2bf). Gate: Gizmoduck r4 rerun brief 14/14, library 83/83, business 209/209, 0 skips; gate grep empty. 194 rebases next (business.test.mjs). |
| 269 | 264b T1 item 7: per-session native store, workspace and single-writer fence | gizmoduck; reviewers duckworth | #1774 | done | 264 done | Duckworth approves this slice's manifest. Its design tests run whole plus every touched suite on Sage's slot, and its mutants are killed (RULINGS Q1). Tests T1 run half, T2 workspace and path mutants; whichever of 191 and 264b lands second wires 191's admission checks (Q5). (sage) | `docs/plans/2026-10-21_t1-sessions.md` § T1 item 7: independent sessions, compaction counts and clear context | Landed efcc9ea8d fast-forward on 94c33a43c (13 commits, 12 paths, manifest 455c12ee). r3 is a carry of r2 aafcc857c, range-diff = (Duckworth 0194, c30756, rev 3307). Gate r3 18:37-18:50Z all green, 0 skips: bus 834, seat 172, cli 869, case2-unit 43, singles 38. M1-M12 kills carry. Re-pin needs the Console restart by Jason or Mos right after the host. A 264a rollback refuses a v2 sessions.json, see BUILD.md Rollback. |
@@ -323,10 +323,10 @@ Generated from `docs/plans/queue.json` revision 3945 by `queue render`. Do not e
| 284 | Case 2 C2-05c the supporting scope and blob in the lookups | della; reviewers dewey | #1789 | briefed | 224 done, 283 done | Dewey approves the manifest. Library, bus and harness suites and every scripts/test-*.sh green on Sage's gate. Grep packages/*/tests for the scope enum pin and ['canon', 'playground'] before in-review; update each. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-05c the supporting scope and blob in the lookups (sage-2833) | — |
| 285 | Case 2 C2-08b role changes for agent writes and the chief's read grant | magica; reviewers poe, webby | #1790 | done | 213 done, 291 done | Webby approves the manifest. Business suite, test-config.sh and every scripts/test-*.sh green on Sage's gate. Grep for CREATIVE_KINDS and 64-hex pins of changed role files. Sage checks it against mos-1309 item 5. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-08b role changes for agent writes and the chief's read grant (mos-1309 item 5) | LANDED 1f3d0350f 13:33:42Z: candidate 2e4503dc7 (14 commits) cherry-picked onto 25874bc86. Logs kept both sides; otherwise the tree equals the candidate except on 7 base paths. Poe c31568 rev 3919, Webby c31569 rev 3920. Sage gate GREEN 13:28:46Z with its own npm ci: 4236 package tests, 0 fail, 1 allowed FED R7 skip; 12 scripts rc 0. No CREATIVE_KINDS, no role-file hash pins. Roles match mos-1309 item 5. 286 rebases as r5. |
| 286 | Case 2 C2-03b push and per-seat credentials for the library mirror (with R4, mos-1323) | rockerduck; reviewers boyd, dewey | #1791 | done | 222 done | Dewey approves the manifest. Library and bus suites and every scripts/test-*.sh green on Sage's gate, mutant killed. A search of the run output for the fixture token finds nothing. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-03b push and per-seat credentials for the library mirror | LANDED 5d7801dc1 14:37:02Z: r6 75f6d56b1 (19 commits) picked onto d55944edb; logs kept both sides, code equals the candidate. Boyd c31587 rev 3942, Dewey c31588 rev 3943 (r2 c31584/c31585). Sage gate GREEN 14:36:42Z, own npm ci: 4251 tests, 0 fail, 1 allowed FED R7 skip; 12 scripts rc 0; fixture values in 0 of 29 outputs; B285-M1 kills T7/T9. r6 shortened two fixtures after push-check STOP secrets (sage-4112). Chief seed per sage-4100. |
| 287 | Case 2 C2-21 the grant executor for a library project | megavolt; reviewers dewey | #1792 | briefed | 226 done, 285 done | Dewey approves the manifest. Bus suite, Gitea Docker test, install test and every scripts/test-*.sh green on Sage's gate. A search of the run output for the fixture admin and seat tokens finds nothing. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-21 the grant executor for a library project | — |
| 287 | Case 2 C2-21 the grant executor for a library project | steelbeak; reviewers boyd, dewey | #1792 | done | 226 done, 285 done | Dewey approves the manifest. Bus suite, Gitea Docker test, install test and every scripts/test-*.sh green on Sage's gate. A search of the run output for the fixture admin and seat tokens finds nothing. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-21 the grant executor for a library project | LANDED 0e935776e 16:12:35Z 10-24 (cand c2338ed58 + a5370b198 on 9b6345466). Boyd APPROVE c31602 rev 3967, Dewey APPROVE c31603 rev 3968. Sage gate GREEN 16:11:38Z: bus 998/0 (Gitea Docker F-A/F-B + X-G3, minted 4 hits 0), business 283/0, cli 989 +1 allowed FED R7 skip, webui 442/0, 12 scripts rc 0. F-C negative record-only follow-up. Dewey N1-N3 non-blocking. #1792 closed c31606. No P19 task. |
| 288 | Case 2 C2-02 agent writes, the notice, revert and her Console saves | bubba; reviewers webby | #1793 | briefed | 215 done, 282 done, 283 done, 284 done, 285 done, 286 done | Webby approves the manifest. Library, bus and harness suites and every scripts/test-*.sh green on Sage's gate, mutants killed. A search of the run output for the fixture tokens finds nothing. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-02 agent writes, the notice, revert and her Console saves | A2 revert contract (morgana-0199, sage-3596): library.revert is a human verb. Args {project, commit}, strict keys; project is the business.projects key (the chat repo link), not a UUID. Result {project, path, reverted, commit}. Refusals: 409 stale-base, and 409 library-revert-not-agent for an agent caller. Owner Bubba under Q245 (mos-1506). |
| 289 | Case 2 C2-11b Console library pages and her saves (Haiku subagent, decision 129) | researcher; reviewers filbert | #1794 | briefed | 214 done, 288 done | Filbert approves the manifest. The webui suite and every scripts/test-*.sh are green on Sage's gate. Grep for hash pins on bus.js and serve.mjs before in-review. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-11b Console library pages and her saves | — |
| 290 | Case 2 C2-12b the setup sheet rewrite for free chat, supporting folders and saves | louie; reviewers webby | #1795 | briefed | 217 done, 218 done, 285 done, 291 done | Doc only. Webby approves it against the ruling. Before landing, grep packages/*/tests and scripts/test-*.sh to confirm no test reads the file. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-12b the setup sheet rewrite for free chat, supporting folders and saves | — |
| 290 | Case 2 C2-12b the setup sheet rewrite for free chat, supporting folders and saves | louie; reviewers webby | #1795 | done | 217 done, 218 done, 285 done, 291 done | Doc only. Webby approves it against the ruling. Before landing, grep packages/*/tests and scripts/test-*.sh to confirm no test reads the file. (sage) | `docs/plans/2026-10-20_case2-rows.md` § C2-12b the setup sheet rewrite for free chat, supporting folders and saves | LANDED 3d7dff345 on refactor, pushed 14:55:11Z: cherry-pick of 963303403..22510988d onto 18334d713, four commits equal by patch-id and range-diff, SETUP-SHEET.md blob 37b451c6 as approved. Gate per brief (doc only): Webby approve c31596 rev 3954; grep of packages/*/tests, scripts/test-*.sh and tests/ for SETUP-SHEET finds nothing (positive control hits). No suite run: no test reads the file (decision 137). #1795 closed c31597. |
| 291 | PRD 1.16 library.write routes under REQ-LIB-6 (mos-1328) | gosalyn; reviewers webby | #1796 | done | 282 done | Webby approves the text. Jason says yes to the exact text (Mos asks him, mos-1328 step 3); no landing before that. requirements.test.mjs and every scripts/test-*.sh that reads the PRD or requirements.json are green on Sage's gate. Mos gets the landing commit. (sage) | `docs/plans/2026-10-22_prd-1-16-brief.md` § PRD 1.16 library.write routes under REQ-LIB-6 (mos-1328) | Landed 4874d1e83 on e909ef51a: 482e865ac replayed, patch-id equal (cef7de74), range-diff =. Webby APPROVE c30848 on 482e865ac; Jason approved the text in Q229. Gate 16:15Z on the tip tree: every package suite but queue, 0 fail 0 skipped (tasks 100, bus 891, cli 941, plugins 119, webui 392, business 231), every scripts/test-*.sh rc 0 (queue-root and row 244 skips only). PRD 1.16. 1.17 is row 308. |
| 292 | stack-release.sh config_checks runs the target loader on any config (row 270 rollback hazard) | gizmoduck; reviewers duckworth | #1797 | done | 203 done, 270 done, 271 done | Duckworth approves the manifest. The touched test files run whole, the cli suite and every scripts/test-*.sh are green on Sage's gate, and the mutants are killed. (sage) | `docs/plans/2026-10-22_config-checks-any-key-brief.md` § stack-release.sh config_checks runs the target loader on any config (row 270 rollback hazard) | Landed 6aab979e6 (cherry-pick of c902a767d..90be6cccd, range-diff all =, patch-id a45c9ba4 equal). Tested head 0d0021454: stack-release.test 224/224, cli suite r2 red only compactions-launch:229 session-invalid 22 (idle-stop race, Vikunja 588, row 302), r3 rerun 910/910 under mos-1411, ten shells green, M1-M9 killed. Duckworth APPROVE rev 3433 on 2fa7ae17. |
| 293 | 574: maintenance-free test fixture commits (Vikunja 574) | gander; reviewers filbert | #1805 | done | — | Filbert approves. The four whole files, then the seat and cli suites, are green on Sage's gate. (sage) | `docs/plans/2026-10-23_mvp-readiness-rows.md` § Brief: 574, maintenance-free test fixture commits (Vikunja 574) | LANDED e51d11640 03:55Z 10-23 (cherry-pick of gander b23783f39..a9cae2bd6 onto 464010fbe; range-diff 6/6 equal, range patch-id equal). Filbert APPROVE c30982 cdda41f5; run 2 4 files 153/0, seat 202/0, cli 905/0, 312 flagged/0 maintenance children. N1: lifecycle.test needs TMPDIR of 50 bytes or less. Residual: queue store.mjs, discord git.mjs, harness tools.mjs unflagged. #1805 closed c31013, P19 574 c888. |
@@ -364,6 +364,12 @@ Generated from `docs/plans/queue.json` revision 3945 by `queue render`. Do not e
| 325 | Case 1 business file: re-key project to stack to match .mosaic/project.json, plus a project-file test (#414 stage 2, ops-0288, mos-1563) | goldie; reviewers gladstone | #1821 | done | — | New test file and packages/business whole on CLEAR; one key mutant killed; Gladstone review; Sage full landing gate (mos-1455) (sage) | `docs/plans/2026-10-24_case1-project-key-brief.md` § Brief: re-key the Case 1 project to stack | LANDED c5f96836d (ff from 99930362e), tip 3d2569ce2. Gladstone approve c31484 rev 3788 on c5f96836d. Sage gate green 01:31Z on c5f96836d: all package suites 0 fail (business 264, cli 986), every scripts/test-*.sh rc 0. Project key is now stack, matching .mosaic/project.json; new case1-project-key test checks the real project file. Old-test line :70 under mos-1564. |
| 326 | Host run sheet: five operator gaps (B2-2 proof format, 323 N2, pre-install key check, failed-first-install retry, backup SHA256SUMS form) | goldie; reviewers gladstone | #1822 | done | — | Gladstone approves the manifest; every new claim cites its line; no test reads the sheet; Sage's full landing gate green (sage) | `docs/plans/2026-10-24_run-sheet-doc-brief.md` § Brief: five run-sheet gaps | LANDED 33f49f7d5 (cherry-pick of a1b13c60e, patch-id match, sheet e4c14516) in f58049de0 with row 208 on one full gate 04:36-04:51Z, all suites green. Gladstone c31489. #1822 closed c31507. B2-2 closes in DEFERRED. Bundle 9fc7754a. |
| 327 | Push check in the repository: scripts/push-check.sh passes a binary only when an approved review candidate lists its path and sha256, plus scripts/test-push-check.sh (#1825, mos-1572 A) | bradford; reviewers dewey, poe | #1825 | done | — | Poe gives the first Codex review, Dewey reviews the landing candidate; scripts/test-push-check.sh and every other scripts/test-*.sh green on Sage's gate; the mutants killed; Sage's next push runs through scripts/push-check.sh (sage) | `docs/plans/2026-10-24_push-guard-binary-manifest.md` § Brief: push-check.sh passes a binary only when the reviewed candidate lists its path and sha256 | LANDED 68c08b4e7 (pushed 07:18:03Z 10-24): 3 commits on 6a5e12511, blobs equal round 3 d858c9f8b; Poe c31525 rev 3882, Dewey c31526 rev 3883; gate GREEN 07:15:49Z with its own npm ci (first run red on empty canonical node_modules, sage-4023); 6 push-check mutants KILLED; next push 42ba0f5bc ran through scripts/push-check.sh --fetch, PUSH_READY; #1825 closed c31530. |
| 328 | T9 library-credential test: the second broker start passes Node's TIMEOUT_MAX interval so no timer tick overlaps the verb sync; mutant fails a 50-run stress loop (#1826, Vikunja 622, mos-1594) | fethry; reviewers boyd, dewey | #1826 | done | — | Boyd gives the first Codex review, Dewey reviews the landing candidate; touched tests run whole, the 50-run stress loop passes with the fix and M1 fails it; bus and every scripts/test-*.sh green on Sage's gate (sage) | `docs/plans/2026-10-24_t9-library-sync-race.md` § Brief: the T9 verb sync on the second start runs with no timer tick able to overlap it | LANDED 8bb5b3c73 19:40Z 10-24 (8 Fethry commits on 5e77cdd09). Gate GREEN 19:38:54Z on 8bb5b3c73, no drift. Boyd APPROVE c31621, Dewey APPROVE c31622. #1826 closed c31625; Vikunja 622 done. |
| 329 | Model proxy P1: model-proxy package, pinned fetch with sha256 refusal, mosaic proxy init, proxy unit (237, mos-1600) | magica; reviewers boyd, dewey | #1827 | in-progress | — | Boyd first review, re-measuring both release hashes; Dewey landing review; BUILD.md has the acceptance output. Sage's landing gate: every package suite but queue plus every scripts/test-*.sh green, touched test files whole, refusals each tested, named mutants killed (brief Gate). (sage) | `docs/plans/2026-10-24_model-proxy-rows.md` § Brief: P1 the model-proxy package, pinned fetch, proxy init and the proxy unit | — |
| 330 | Model proxy P4: Console forwards /proxy/ owner-only in a CSP sandbox (237, mos-1600) | poe; reviewers filbert, gladstone | #1828 | blocked (from briefed): panel needs localStorage, CSP sandbox forbids it; waits on Jason's subdomain answer, Vikunja 624 (mos-1602) | — | Gladstone first review; Filbert landing review; starts now, lands after P1 rebased on it; webui with MOSAIC_REQUIRE_EDITOR_BUILD=1. Sage gate: all package suites but queue and every scripts/test-*.sh green; brief Gate. (sage) | `docs/plans/2026-10-24_model-proxy-rows.md` § Brief: P4 the Console forwards /proxy/ to the instance proxy in a sandbox | — |
| 331 | Model proxy P2: per-agent model keys, reconcile and launch preflight (237, mos-1600) | sage; reviewers boyd, dewey | #1829 | briefed | 329 done | Boyd first review; Dewey landing review; three named mutants killed. Sage gate: all package suites but queue and every scripts/test-*.sh green; brief Gate. (sage) | `docs/plans/2026-10-24_model-proxy-rows.md` § Brief: P2 per-agent model keys, reconcile and the launch preflight | P2 input from magica-0020 (acceptance-probe-4): 8.0.42 revocation lags ~105ms after v8 PUT (first call 200, then 401); reconcile/revoke must poll to 401, not assume instant. Per-key model objects give 422; no per-key model restriction. |
| 332 | Model proxy P3: harness config from the proxy (237, mos-1600) | sage; reviewers dewey, gladstone | #1830 | briefed | 331 done | Gladstone first review; Dewey landing review; named mutant killed. Sage gate: all package suites but queue and every scripts/test-*.sh green; brief Gate. (sage) | `docs/plans/2026-10-24_model-proxy-rows.md` § Brief: P3 harness config from the proxy | — |
| 333 | Model proxy P5: usage plug-in and per-key limits, per-key count only (237, mos-1600) | sage; reviewers boyd, dewey | #1831 | briefed | 331 done | Boyd first review; Dewey landing review; named mutant killed. Sage gate: all package suites but queue and every scripts/test-*.sh green; brief Gate. (sage) | `docs/plans/2026-10-24_model-proxy-rows.md` § Brief: P5 usage plug-in and per-key limits | — |
<!-- mosaic-queue:end -->
+2502 -40
View File
File diff suppressed because it is too large. Load diff