Compare commits
129
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6f41eddb20 | ||
|
|
1de685ccad | ||
|
|
1648af7d4e | ||
|
|
6dd4f92b0a | ||
|
|
8830030412 | ||
|
|
c558498062 | ||
|
|
138171ca0d | ||
|
|
bec3583286 | ||
|
|
3b071cac7b | ||
|
|
1e1357cb6e | ||
|
|
831d15f0b4 | ||
|
|
63bd48a5f8 | ||
|
|
260f2ce7ed | ||
|
|
a34f79692e | ||
|
|
930d77eeca | ||
|
|
7e849a7b0b | ||
|
|
ec5354bcc2 | ||
|
|
7024e35f59 | ||
|
|
cbc43c6edc | ||
|
|
e71222d1a0 | ||
|
|
18a0bd47d7 | ||
|
|
a702076576 | ||
|
|
4d1d5ee8ee | ||
|
|
bd79daffdd | ||
|
|
1bf83078b4 | ||
|
|
0c6aa1a1e2 | ||
|
|
b9811c492f | ||
|
|
d27fe0ea95 | ||
|
|
b8f01a189f | ||
|
|
e6ba6eb8dc | ||
|
|
3c7a7740c4 | ||
|
|
180fb8ab00 | ||
|
|
42c72d781b | ||
|
|
d3b6ab11da | ||
|
|
a605e44d1e | ||
|
|
85ecdfbde5 | ||
|
|
2ba22b4cbf | ||
|
|
5fbf3d2b51 | ||
|
|
0e7e203db8 | ||
|
|
38cfa72335 | ||
|
|
3dc824ea12 | ||
|
|
1ff45c4ad6 | ||
|
|
9c2f391a90 | ||
|
|
a13050012a | ||
|
|
8cf2eda9ff | ||
|
|
f65faf9df8 | ||
|
|
728442fcef | ||
|
|
1977f4ffc6 | ||
|
|
9944100ade | ||
|
|
1009bbfaf9 | ||
|
|
fe3ef5128d | ||
|
|
0be9e024cf | ||
|
|
7e0d3c93f3 | ||
|
|
3692fca522 | ||
|
|
9256129228 | ||
|
|
31222d81d7 | ||
|
|
3d00efe39c | ||
|
|
9f817e6961 | ||
|
|
80c4a37396 | ||
|
|
259e59d401 | ||
|
|
b37cc50878 | ||
|
|
ea02c061e4 | ||
|
|
dca9bc8691 | ||
|
|
9a9c60d9c0 | ||
|
|
c0c291cda2 | ||
|
|
0ef269da9b | ||
|
|
abc66a5988 | ||
|
|
12eba4b599 | ||
|
|
5df0e9d6fa | ||
|
|
bd76d43453 | ||
|
|
a8e71be034 | ||
|
|
da1f0ceda6 | ||
|
|
04e1ce24cc | ||
|
|
6e9f3d7231 | ||
|
|
39eadf8ba8 | ||
|
|
fddae79ef6 | ||
|
|
a6acbbe14d | ||
|
|
46cd8d5835 | ||
|
|
aba5cc505f | ||
|
|
8545057275 | ||
|
|
068d868a99 | ||
|
|
4ff4f44c98 | ||
|
|
b9ea9304fd | ||
|
|
6bad02612a | ||
|
|
158205c5cc | ||
|
|
cab3ef3e8f | ||
|
|
ddf20567ee | ||
|
|
3b88ef399d | ||
|
|
1eb8b68e44 | ||
|
|
abe37ab27a | ||
|
|
4ef251e1a7 | ||
|
|
36a70ea9c1 | ||
|
|
8eb37bed32 | ||
|
|
82ca1d3db4 | ||
|
|
54328cfae5 | ||
|
|
ddb3e961fb | ||
|
|
46c07df75f | ||
|
|
4ac6f13bcf | ||
|
|
c012b2e0a3 | ||
|
|
2627321f64 | ||
|
|
c78f225433 | ||
|
|
c1e9841d36 | ||
|
|
6951fb494f | ||
|
|
5514457dde | ||
|
|
fbf8d61a4c | ||
|
|
2b3e3ec83b | ||
|
|
418f00bce2 | ||
|
|
a7a433e271 | ||
|
|
664d8ef3d3 | ||
|
|
f7d16e9a8d | ||
|
|
484aef7e2a | ||
|
|
d0ddfa8de2 | ||
|
|
ab2bc23c7f | ||
|
|
1d6dae6fe4 | ||
|
|
7fff6a20e6 | ||
|
|
a19b936a8c | ||
|
|
ee151685e9 | ||
|
|
155cb8c3e5 | ||
|
|
9936a1be1a | ||
|
|
4cf888c04c | ||
|
|
eabeb1aa82 | ||
|
|
569765f6de | ||
|
|
d6dc04e84f | ||
|
|
503b91e561 | ||
|
|
4c49919e9b | ||
|
|
c4bba5d2a3 | ||
|
|
5a0c801cb8 | ||
|
|
2a728da86c | ||
|
|
6df8b0fd8a |
No files matched your search
@@ -1,5 +1,6 @@
|
||||
# build/deps
|
||||
node_modules/
|
||||
.turbo/
|
||||
|
||||
# runtime credentials — never commit, never copy into the image
|
||||
.env
|
||||
|
||||
+195
@@ -5583,6 +5583,17 @@ claim. Receipts and limitations in agents/lena/work/queue-296/BUILD.md and run-r
|
||||
|
||||
2026-10-24 — Magica row329 R2 (#1827): B1 ASCII-only management key fix verified with complete-tree refusals and positive auth control; package66/66,30bus readers261/261,49CLI readers726/726,config55/55, no required skip/failure. N1 corrects R1 bus total to1019; N3 stale-lock guidance and N4 34-code inventory corrected. Two over-selected file runs are recorded separately, with no F7 inference; cause unknown/Vikunja625. Old502 test/helper files byte-identical, slot returned to Sage. Evidence agents/magica/work/queue-329/BUILD.md.
|
||||
2026-10-24T23:37:46Z | Sage | Row 329 (#1827, P1 pinned model proxy, Magica) LANDED 61ebf2c34, pushed 23:31:27Z 10-24. Before: refactor at 669cdf42c. After: Magica's 4 commits (94cde633e, c65fb34ee, d1f6f2b19, 61ebf2c34) cherry-picked onto 669cdf42c, diff vs the gated tree limited to drift paths, range-diff in scratch. Gate: one unchanged full landing gate in /mnt/storage/scratch/sage-r329l/wt (gate.sh 8b4978887 c8a9bcf94), started 23:08:12Z at load 14.35, GATE GREEN 23:29:14Z at load 8.67, no rerun, no test or timeout edit (mos-1634). Host note: two Codex workers cleaned T3 worktrees from about 23:14Z (mos-1639, Vikunja 632). Approvals: Dewey r2 c31643 rev 4047, Boyd r2 c31642 rev 4048. #1827 comment 31650, closed. Vikunja 237 comment 1109 (stays open for P2-P7); C4 P10 red filed as Vikunja 631. Queue: note rev 4063, done rev 4064, committed b24d917ec. DEFERRED: N2 and R2-N1 bound to row 331, N1 bound to P7. Overlap: row 284 (packages/bus/src/broker.mjs) and row 157 (scripts/mosaic-config.mjs) rebase onto 61ebf2c34 before their gates.
|
||||
## 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.
|
||||
|
||||
2026-10-24 — Fethry row332 P3 UNRUN implementation checkpoint: optional proxy route per sage-4325 (default Anthropic), transient preflight/bundle/spawn context and serialization split, pi private model file/provider credential requirement. Existing initial RED evidence precedes source changes; only specifically authorized old fixtures updated. GPT wire API value PENDING until separate offline CLEAR/evidence; P2 seam remains injected context, no real proxy/auth access. Not GREEN, not accepted or landed. Details agents/fethry/work/queue-332/BUILD.md.
|
||||
|
||||
2026-10-24 — Fethry row332 P3 checkpoint ef0939e35: required explicit route restored per sage-4293/4328; openai-responses chosen by Sage sage-4331 as reasoning-based tie-break, not evidence-decided (both offline shapes passed). Rehashed pinned8.0.42 single active-tool isolated GLM turn confirms thinking/tool_stream survive to stand-in;bundle7/7,proxy-harness5/5,no skips. Real Codex auth proof remains row209 phaseA step7. P2 landing/rebase,mutants,reviews and full gate still pending; no landing claim. Plain evidence/limitations in agents/fethry/work/queue-332/BUILD.md.
|
||||
2026-10-25T00:15:48Z | Sage | Row 284 (#1789, C2-05c library.get scope, Della) LANDED ce0b6ed41, pushed 00:09:52Z 10-25. Before: refactor at 9e2689dff (row 329 landing docs). After: fast-forward to Della's 7 rebased commits 78b932feb..ce0b6ed41; 8 paths, manifest-r4 de505cfd matches the landed tree. Gate: one unchanged full landing gate in /mnt/storage/scratch/sage-r284l/wt (the 329 gate.sh with D and the compose project renamed), started 23:51:19Z at load 1.62, GATE GREEN 00:09:04Z at load 5.20, no rerun, no test or timeout edit. Counts: bus 1020/0, business 283/0, cli 999 pass 1 allowed skip (FED R7), harness 177/0, library 156/0, seat 218/0, webui 458/0, every scripts/test-*.sh rc 0; queue 34 and task 87/93 skips are the standing ones. Della's whole-file runs on ce0b6ed41: library-lookups 12/0, library-tools 5/0, query 34/0. Approval: Webby round 2 delta c31654 rev 4070 (round 1 rev 4062). Overlap sweep: rows 13, 157, 309, gyro/row310 and fethry/row332-p1 clean. #1789 comment 31655, closed. No Vikunja task for the row. Queue: note rev 4071, done rev 4072, committed 7c8dc2033. DEFERRED: Webby N1 (whole-tree listing per get) bound to the next library read-path row; N2 needs nothing; N3 is this gate.
|
||||
2026-10-25T00:18:35Z | Sage | Follow-up tasks for mos-1647 item 3 (Q109): Vikunja 633 (P7 cutover, CLIProxyAPI 8.0.42 startup Grok-npm and antigravity version refreshes, from row 332 isolated runs) and 634 (row 284 Webby N1, library get lists the whole tree). DEFERRED gains the 633 entry and the 634 number for row 284 N1. Filing script and receipt in agents/sage/work/vikunja-setup/.
|
||||
2026-10-24T22:15:07Z | Herb | row 214 #1715 C2-11a focused evidence | Before: wikilinks are ordinary editor text; raw/sig retention keeps no-edit bytes, but the model has no inert node. After: inert inline wikilink atom preserves spelling through neighbouring edits; invalid attrs share HTML/entity escaping. On herb/row214-r2 base487500a16, grant sage-4286 lane B: baseline10/10 roundTrips equal (outcome A); baseline structural0/1 expected red; four whole editor files40/0, both mutants killed0/1 and restored1/0, whole webui69 files455/0 in174.189s with MOSAIC_REQUIRE_EDITOR_BUILD=1, nice19, no skips/cancellations. A mistaken preliminary7-file subset28/0 is logged and excluded from gate evidence. CSS byte-identical, final process sweep0, scratch TMPDIR removed. Filbert candidate review and every scripts/test-*.sh gate remain pending; no click, target resolution or library save change.
|
||||
@@ -5816,3 +5827,187 @@ Before: agents can read the library; supporting-path and push-credential depende
|
||||
2026-10-26 | Sage | mos1884/#662 scope after330/331landing | ReadQ222/Q261/Q263 and659/660/662; posted bounded human-only factory settings/triage/defaulttwo-roundmandate/trackedno-exemptionflake scope with10acceptance criteria, task662comment1338 exactwholebody/author13GETverified. No implementation/review/gate launched.660c1335notready(review/merge, noVM); gatefacts1329/1334 retained; target integration/fullrunner confirmation follows readiness, no localfallback. Landedproduct/evidence unchanged;657/658backlog.
|
||||
|
||||
2026-10-26 | Sage | Mos1909/1915/1917 real postlanding reviews | Boyd/Dewey/Filbert/Gladstone real authored candidate52ba verdictfiles independently byte/hash-verified, allAPPROVE scoped; Dewey656broaderPARTIAL retained. Formal330R1/331R4 requests failedpre-send/no comments or approvals; no borrowed/copied/mintedkeys. LegacyhelperGETname jason.woltje is NOT ownJarvis, ownslotabsent; rows tracking-open/#436, files cited via normalqueue. NewFilbertNEW-330-01 filedtask665 exactreadback, notlandingreopen/gate. Repair646-648/652-656 remainOPEN untilactualcomments;1917 conditionalbacklog routing retained. #662scope1338posted;660PR405REVISE/notready. Product1968inputs unchanged; no source/helper/test/gate edits/runs; peerjournal prefixes preserved.
|
||||
|
||||
2026-10-28T22:18:42-05:00 | Codex FIX-A4-001 project19 #710 BEFORE/AFTER | Isolated branch work/q284-web-fetch-ipv6-ssrf at exact base09a847ed; source pine5a7b647 and A4 report39380B/5ee6f798 verified. Focused web test baseline7/7; regression-first exact mapped-IPv6 literal/DNS/redirect run6pass/4fail; canonical-bit implementation then10/10pass. Changed only web source/test plus append-only receipts; no live/internal probe, scratch, dependency/install, heavy/full gate, commit, push, PR or API mutation. Full CI/cross-family/PR/release remain parent-owned.
|
||||
|
||||
2026-10-29 | Sage | #710 independent-review follow-up | Claude source approval of 4cf888c04 records LOW NAT64 policy disclosure: canonical classification refuses exact 64:ff9b::/96; the old text prefix also refused some addresses outside that range. Added explicit boundary tests; production source unchanged. Zone-suffixed inputs also fail closed. Other IPv6 transition/special-use ranges remain a separate deployment-dependent follow-up, not resolved here. Prior author no-commit statements describe that earlier session; local commit and Mos PR1834 publication followed. No native/CI/merge claim.
|
||||
2026-10-28T22:29:01-05:00 | Vikunja-19 FIX-156 legacy worker mounts BEFORE (late phase receipt) | Isolated worktree clean at exact base09a847edaa25b609bac7728ff83f224708a29399, branch work/vikunja-19-156-q284-worker-mounts. Required queue probe refused in linked worktree and was not bypassed. A2 SHA/whole report, I1 direction and legacy task/interactive/probe callers traced. Focused baseline13/13; TDD RED17 total=13 pass/4 intended failures for absent typed mount builder/per-path task argv. Receipt appended after first source pass rather than backdated; no container/native/live/provider/full-gate/API/PR/commit/push operation.
|
||||
|
||||
2026-10-28T22:36:00-05:00 | Vikunja-19 FIX-156 legacy worker mounts AFTER/source-verified | Static Compose root/control mounts removed; typed task/interactive/probe builder emits fixed per-file RO task/mission/user/SOUL/skill/control/fork inputs, only selected workspace/session RW, private mode0600 per-container prompt and no root/run-evidence/sibling/broker path. Unsupported/missing inputs refuse before runtime registration. Exact-base parsed Compose characterization fails with /var/lib/mosaic and /var/lib/mosaic/control present; focused RED13pass/4fail then user-file narrowing RED7pass/2fail; final two-file18/18 pass, syntax/diff checks and direct user+mission prompt mode600 check pass. Author self-review found no remaining Critical/Important source issue; no independent review by explicit no-children scope. No native confinement/container/provider/full gate or generic credential read; no commit/push/PR/API/release.
|
||||
|
||||
2026-10-28T22:35:03-05:00 | Correction to immediately preceding FIX-156 AFTER receipt | Its 22:36 timestamp was rounded one minute ahead; actual clock checkpoint was 22:35:03-05:00. Substance and evidence are unchanged.
|
||||
|
||||
2026-10-28T22:41:42-05:00 | Vikunja-19 FIX-156 atomic-control continuation BEFORE | Parent intake found the per-file `control/processing.json` bind pins the inode that `state.mjs` later replaces by temp-file rename, allowing a post-mount halt/generation change to escape final entrypoint admission. Exact branch/base remain work/vikunja-19-156-q284-worker-mounts at 09a847edaa25b609bac7728ff83f224708a29399; source-only TDD repair will restore a narrow rename-visible read-only control view without the data-root root, evidence, sibling state, socket, native/container/full-gate/API/credential operations, or integration authority.
|
||||
|
||||
2026-10-28T22:44:07-05:00 | Vikunja-19 FIX-156 atomic-control continuation AFTER/correction | Source trace confirmed `state.mjs` publishes `.state-<uuid>` with `renameSync` over `processing.json`; a file bind can retain the old inode. The typed launch now mounts exactly `<dataRoot>/control` at `/var/lib/mosaic/control:ro`, preserving rename-visible final halt/generation admission while leaving the data-root root, run/evidence/workspace/session trees and `bus/broker.sock` absent. Audited source-produced contents are `processing.json`, transient `.state-*`, and `runtimes/`, `stops/`, `run-stops/` runtime/stop metadata with transient `.receipt-*`; no socket producer targets `control/`. This supersedes the 22:36 per-file-control/no-runtime-receipt wording and clarifies the 22:41 "sibling state" phrase: read-only shared runtime/stop metadata is intentional, while sibling data trees remain absent. Focused TDD RED was 10 pass/1 intended fail (missing directory mapping) after real writer halt/clear inode replacements; standalone GREEN 11/11 and final two-file source GREEN 19/19, node checks 4/4, shell syntax and diff check all rc0. Existing native read-only mount negative and container CI were not run and remain required; no Docker/Podman/bwrap/native/live/provider/full gate, credential, commit/push/PR/API/release action.
|
||||
|
||||
2026-10-29T00:29:45-05:00 | Vikunja-19 FIX-156 R3 review repair BEFORE | Independent review report 12437B/SHA256 70daa15fdddfc83654821c99149dc84210a9bd7078614b60ff8e630e4fcb8a77 read in full. Branch is clean at published ee151685e9e15511407904397d73e4d82c37c85b, original base/merge-base 09a847edaa25b609bac7728ff83f224708a29399. F1 source trace confirms only the session-fork file bind is selected from inside a worker-writable directory and remains daemon-resolution TOCTOU; task/mission already use host-owned current-run write-once snapshots. Focused baseline19/19. Controls will require no-follow bounded descriptor copying to same-run evidence, original/foreign source refusal, immutable bytes after original substitution, and probe unsafe-user refusals; no native/container/full gate, install, credential, API, commit/push/amend or review dispatch.
|
||||
|
||||
2026-10-29T00:33:07-05:00 | Vikunja-19 FIX-156 R3 review repair AFTER/source-verified | F1 fixed without a new schema: newest session fork is opened O_NOFOLLOW/O_NONBLOCK, fstat regular/current-uid checked, capped at 16777216 bytes before allocation, copied from that descriptor only after stable size/mtime/ctime checks, and published `wx` as current `runs/<id>/session-fork.jsonl`; `workerLaunch` accepts only that exact same-run snapshot and refuses shared-session/foreign-run sources. Real fixture substitution after snapshot cannot change mounted bytes; newest symlink copies/mounts no target; oversize refuses before publication/Docker. F2 documented honest unselected-tree boundary and retained selected managed-business/discord namespace collision; parent follow-up must choose dedicated legacy prefix or explicit collision refusals/migration. F3 probe symlink/nonfile/colon refusals documented and fixture-covered. F4 exact deferred #660 list now includes `scripts/test-darkwing-launch.mjs`; list not run. INFO dispositions: I1 stale comment and unused Docker-client MOSAIC_DATA_ROOT removed with 9pass/1RED then10/10; I2 raw basename comparison eliminated by same-run slot; I3 accepted RO control metadata unchanged; I4 worker-owned private prompt unchanged; I5 gated placeholders unchanged; I6 incomplete predispatch run pattern unchanged; I7 external-path Pi fork remains native #660 evidence; I8 pre-existing Claude adapter env gap unrelated/unchanged. Baseline19/19; principal RED18pass/5intendedfail after one fixture-only setup correction; F1 GREEN23/23; final23/23, four Node checks and diff check rc0. No full package, shell suite, Darkwing compatibility, build, Docker/Podman/bwrap/native/live/provider/network/credential/API/PR/review/commit/amend/push/merge/release action; #660/native/cross-family gates remain.
|
||||
Q284 / #470 source-only security fix 2026-10-29T03:33:00.640624+00:00: pin worker base Node24.22.2 multi-platform indexsha256:c86ecead9e55a5210ac1727de38a4ca840bf03dcaf34dc9749addbf383b1920c, official registry metadata retained under docs/security/q284-node-base. Hash/digest/platform references checked; no image pull/build/runtime/test/CI/deploy. Current deployed Node states remain UNKNOWN. No frozen packet change; dedicated CI and cross-family merge review pending.
|
||||
|
||||
2026-10-29 | Sage | #470 independent-review repair | M1 binds preparation/verification baseDigest to exactly one literal digest-pinned Containerfile FROM; stale cached tag metadata cannot be substituted. Focused fixture TDD: 0/3 RED then 3/3 GREEN, fake build/inspection only, no Docker command or image operation. L1 docs corrected. L2 additive registry config hash/version binding retained; prior metadata receipt preserved with correction. Earlier no-commit statement describes initial source session; Mos then published PR1837. #660 admitted runner and fresh independent review remain required; frozen H1/packets unchanged.
|
||||
2026-10-29T03:27:31Z | Codex implementation sub-agent | #385 OIDC-only writer preparation on exact base 09a847edaa25b609bac7728ff83f224708a29399 | Added fail-closed CLI, programmatic and service-render refusals for `--send` without `--sso`; retained read-only header preview/proof; migrated inventoried writer tests to real in-process OIDC login/callback sessions and updated docs. Focused regression 5/5 and selected service cases 4/4 pass; syntax and diff checks pass. The broader writer suite is blocked before execution because the clean checkout has no `node_modules` and exact pinned `[email protected]` is unavailable; no install, commit, push, PR, queue move or green/completion claim.
|
||||
2026-10-29T05:49:53Z | Codex Daybreak Blue xhigh implementation sub-agent | CORRECTION and Mos2255 #385 review repair R2 | The 03:27:31Z dependency/no-commit statements are historical: exact pinned `[email protected]` is now materialized through the ignored `node_modules` fixture with no install, and original preparation is committed at `9936a1be1a37fdb30ba53cf2f14b7897225c3e4a`. On that unchanged HEAD, uncommitted R2 source/tests/docs make Case 2 library preview read-only until #412, drop inherited non-SSO `--send` during release planning, and refuse duplicate service `--send`. Focused RED was 0/2, 0/1, 0/1; focused GREEN and selected T53/T55/T57/T58 fixture blocks pass. No root/native/live/full-suite/CI action, commit, push, PR/API, merge or frozen/live-pin change.
|
||||
2026-11-02T18:03:53Z | Claude Opus 5.5 implementation sub-agent (lead T3 c5c1e8ba) | #385 PR 1836 repair R3 on ab2bc23c7 | R2-F1: `scripts/stack-upgrade.sh` `read_args` now scans the serve argv after `--` and refuses `args-unreadable` before anything stops when the profile is library (no `--profile`, or the last one says library, as `case2-unit.sh` reads it) and `--send` is present; the message names the remediation, and the args file is never rewritten. `do_upgrade` and `do_rollback` both call `read_args` first, so rollback is covered; factory and tester paths are unchanged. RED on ab2bc23c7: new stack-upgrade case 0/1 (exit 2 rollback-failed, A4 and render-old failed, both units stopped), controls 1/1; GREEN 2/2. R2-I1: one component case runs the real `sso_for_target` then `send_for_target` on a legacy preview `--send` pointer, carried after `--sso` and before `--tester-socket`. R2-I2: TOOLS.md says a same-copy plain activate on a legacy pointer refuses already-active and needs `--no-send`. R2-I3: no code change; `uninstall`/`status` with `--send --send` exit 1, not 4, fail-closed either way. host-run-sheet section 7 gains the migration step. Whole files, one at a time: stack-upgrade 23/23 (69 s), stack-release 225/225 (608 s; a first run was cut by my 600 s background limit at 221 passing, its orphan fixture holder killed), case2-unit 48/48 (73 s). No root, systemd, container, network, push, PR or live action.
|
||||
2026-11-02T18:19:04Z | Claude Opus 5.5 implementation sub-agent (lead T3 c5c1e8ba) | #385 PR 1836 repair R4 on d0ddfa8de | R3-F1 fixed fail-closed, no migration: `scripts/stack-upgrade.sh` adds `legacy_console`, called right after `read_args` in `do_upgrade` and `do_rollback`. For the library profile (same default and last-wins rule as R3), an installed Console unit under the driver's UNIT_DIR whose ExecStart has a `--send` token after `serve` refuses new code `console-unit-legacy` (exit 3, nothing stopped). A missing unit is left to `read_old` (`units-unreadable`). The R3 args refusal stays. `case2-unit.sh`, factory, tester, stack-release.sh and OIDC/#412 untouched. Tests in stack-upgrade.test.mjs run the real base renderer (`git show 09a847eda` of case2-unit.sh and both templates) in the module fixture with fake getent/systemctl to make the legacy unit, prove the current case2-unit.sh refuses it, then drive upgrade and rollback with the real current renderer as A4's RENDER. Controls: read-only library unit, factory host, missing Console unit. RED on d0ddfa8de code 24/25 (the main case exits 2 rollback-failed, both units stopped), GREEN 25/25 (70.1 s). host-run-sheet section 7 now gives a read-only grep of the unit and says stop and report when it carries `--send`. TOOLS.md lists the code. No hash pins on changed files. stack-release.test.mjs and case2-unit.test.mjs read no changed file and were not rerun. One local commit, no push.
|
||||
|
||||
2026-11-02T18:58:01Z | Q284 lead: FIX-156 release bump to 0.0.13 | The lead gate on lead/q284-land 418f00bce failed scripts/test-task.sh "mission and private prompt paths delivered to adapter" twice (94 pass, 1 fail). Cause: the local worker image mosaic-poc-agent:0.85.1-r0.0.12 was built 2026-10-21 from pre-#156 source; its baked src/run-agent.sh:39 exports MOSAIC_SYSTEM_PROMPT_FILE=/var/lib/mosaic/system-prompt.md over the launcher value. The test is right. #156 changes the image contract both ways: its run-agent.sh refuses when the launcher does not set MOSAIC_SYSTEM_PROMPT_FILE, which no pre-#156 launcher does, and its launcher with an old image drops the user context directory and the private prompt path. Rebuilding the shared 0.0.12 tag would break the live pinned copy and every rollback target, so RELEASE moves to 0.0.13 and the new image gets its own tag (compose builds it from source on first use; release.sh ensure aligns an instance). No code change. Live activation of 0.0.13 belongs to the next re-pin. |
|
||||
2026-11-02T18:55:26Z | Claude Sonnet 5.5 implementation sub-agent (lead T3 c5c1e8ba) | #385 PR 1836 repair R5 on 484aef7e2 | Test-only fix; no product file changed. The asset test in packages/webui/tests/chat.test.mjs still fetched `http://127.0.0.1:PORT/chat.js` bare, but since 9936a1be1 its `setup()` runs `sso: auth.sso`, and `serve.mjs:726` answers any non-public Host with 403 `public Host required` (the lead found it in the landing gate on lead/q284-land). The server is right, the test was stale. The test now fetches chat.js and chat.css through `c.get` on the public Host with the signed-in session (new `asText` option on the test `http()` so an asset body is not JSON-parsed), asserts 200, the content type and a non-empty body, asserts the same asset on the loopback Host gets 403 `public Host required`, and adds one line pinning that an unauthenticated public-Host request gets 303 to `/auth/login?return=%2Fchat.js` (`serve.mjs` 736-739), so the asset is not public. RED on 484aef7e2 29/30 (403 !== 200 at chat.test.mjs:350), GREEN 30/30. Whole packages/webui run 495/495, 0 fail (65 s). A first whole run gave 487/8, all 8 in pinned-copy.test.mjs: `fixtureRepo` copies `git ls-files -co --exclude-standard`, and a symlink named `packages/webui/node_modules` is untracked and not ignored (`node_modules/` matches directories only), so cpSync refuses it. That is an artifact of the symlink; the rerun used a real ignored directory of links. Observation, not changed: in `c.get` the `host` option is overridden by `baseHeaders.host`, so the existing POST assertion passing `host: 127.0.0.1:PORT` sends the public Host and exercises the Origin fence. No hash pins on changed files. One local commit, no push.
|
||||
2026-10-25 — Rockerduck row334 (#1832), before: Case 2 renders bus/Console only. Plan: reuse P1 proxy template/runner under --proxy, enforce three-unit re-install checks and proxy→bus→Console starts, cover refusals and both named mutants. Tests held for Sage CLEAR; design in agents/rockerduck/work/queue-334/BUILD.md.
|
||||
|
||||
2026-10-25 — Rockerduck row334 (#1832), RED evidence: whole case2-unit.test.mjs against baseline has 48 pass/33 expected new fail; whole case2-install.test.mjs has 27 pass/1 expected new fail. All 74 older tests pass. Implementations restored. Sage sage-4390 authorizes seat-branch candidate commit/push before GREEN; GREEN/mutants held until separate CLEAR after row331. Per-failure evidence: agents/rockerduck/work/queue-334/red-results.txt.
|
||||
|
||||
2026-10-26 — Rockerduck row334 Mos1961: integrated old candidate onto 09a847eda using documented rebase after diagnosing merge queue-guard refusal; old RED preserved. Whole case2-unit 81/81 and case2-install 28/28 pass; named After and direct-ExecStart mutants killed, restored tests 2/2 pass; all nice19, private temp roots, zero skips. No source edits after integration beyond temporary restored mutants, no push/live action. Source c4bba5d2a; evidence agents/rockerduck/work/queue-334/BUILD.md. Full landing gate belongs to Sage; live behavior UNVERIFIED.
|
||||
|
||||
2026-11-02T19:10:25Z | Claude Sonnet 5.5 implementation sub-agent (lead T3 c5c1e8ba) | row 334 (#1832) R2 on lead/r334-land at 2b3e3ec83 | F1: the test "row334 no-proxy renders stay byte-identical to the pre-row renderer" took its baseline from `git show 78b69e1e6:scripts/case2-unit.sh`, which still requires `--send`; #385 removed `--send` from the library flags, so the merged tree failed `1 !== 0` ("case2-unit: serve flag --send is required"). The baseline is now the frozen fixture `packages/cli/tests/fixtures/case2-unit-pre-row334-renderer.sh.txt`, the bytes of `418f00bce:scripts/case2-unit.sh` (git blob d669e8cbd), and the test checks the fixture blob id before it runs. The fixture ends in `.txt` and is mode 0644, so no `*.sh` listing picks it up; stack-copy and stack-release already exclude `packages/*/tests`, and COPY_PATHS does not name it. F3: the re-install refusal in `scripts/case2-unit.sh` now also names `--proxy`; the pinned regex at case2-unit.test.mjs:593 follows it, and one new test covers adding `--proxy` to a no-proxy install (refuses, bytes unchanged, no systemctl call). F4: the "both units" comments (header, re-install comment, and the WantedBy comment near line 467) now name the bus and Console units, and the proxy unit under `--proxy`. No product logic changed. RED on 2b3e3ec83: the one test fails `1 !== 0`. GREEN: that test passes; case2-unit 83/83 (82 s), case2-install 28/28 (11 s), each run once; the three row253 C4 clock tests passed on the first run. Hash pins: the grep over `packages/*/tests/*` and `scripts/test-*.sh` found one pin in a file that names case2-unit.sh (case1-accept.test.mjs:802, which hashes case1-accept.sh); none on a changed file, and case1-accept.test.mjs was not run. F2 (stack-upgrade.sh and `--proxy`) is not touched. One local commit, no push.
|
||||
2026-11-02T19:04:01Z Lead sub-agent (Claude Sonnet 5.5) ROW 173 R3 #1671 (Seen-intent test fix on lead/landing-batch1, base 09a847eda): BEFORE `MOSAIC_REQUIRE_EDITOR_BUILD=1 node --test packages/webui/tests/board-held.test.mjs` gave 4 tests, 3 pass, 1 fail ("a Seen or Unsee click that waited out a Board read keeps its meaning"), timing out at board-held.test.mjs:207 on the sessions table and held rows before any click. CAUSE: the row 173 test called setup(false), which starts the page with Show machine sessions off, so table.sessions never renders; its sibling at :168 uses setup(true). Not base drift: the same single test fails identically on a detached checkout of dewey/row173-r2 tip 6d15eb5fc20a (based on 78b69e1e6). The test had never run (BUILD.md: "no runs yet"). FIX: board-held.test.mjs:198 setup(false) to setup(true), one token; app.js unchanged. AFTER the test passes (1/1); whole board-held file 4 tests, 4 pass, 0 fail; whole webui package `node --test tests/*.test.mjs` 491 tests, 491 pass, 0 fail, 0 skipped. Teeth check: with app.js reverted to the pre-row-173 behavior (no intent check, seen: !r.seen) the test fails at the announce wait; app.js restored byte for byte. Hash-pin grep (packages/*/tests/*, 33 hex lines, positive control account-migration pin found): no pin names board-held.test.mjs or app.js. Comparison worktree and links removed. Not run: scripts/test-*.sh (lead gate). Corrects the r2 BUILD.md claim of no runs; no earlier entry edited.
|
||||
2026-11-02T19:27:10Z Claude Sonnet 5.5 (child of lead c5c1e8ba) row 267 (C2-15, #1772) R2, F1 search hits carry their source universe: BEFORE `search()` in packages/library/src/query.mjs returned hits without `universe` in both shapes (normal and excerpt_too_long); find already carried it; hybrid.test.mjs reduced search hits to paths and passed. AFTER both shapes carry `universe: file.universe` after `scope`, as find does; hybrid.test.mjs asserts the source universe under both exclude forms (own file and a source's canon) plus a new oversized-line case through the hybrid; the broker C2-15 case asserts it on library.search; query.test.mjs:178 shape pin gains universe. RED 4 of 21 failed on the missing field. GREEN the two files 21/21, library 182/182, business 284/284, bus 1351/1351 (see correction). Mutants: universe off the normal hit killed by 3 tests, off the excerpt_too_long hit killed by 2. F2 (hybrid source exception ignores source scope in reader and guard) not touched, lead files it. Correction recorded honestly: the first bus run in a checkout without node_modules failed 3 tests in model-hire-ownership.test.mjs, also failing on base 09a847eda, and pass with node_modules linked; a second bus run with the link failed 1 test in model-final-completion.test.mjs that passed 3 of 3 alone on this tree and on base; a rerun was 1351/1351. No push.
|
||||
2026-10-26 — Fethry Mos1961 P3/P2 actual join on09a847ed: metadata-first/one actual modelPreflight key through harness,private spawn,binding and stall;explicit provider-identity mapping preserves existing zai/anthropic;proxy strict route. TDD new RED→GREEN plus117/117 targeted wholefile checks,zero skips;original653/655 bodies/assertions/deadlines and runtime/process/modelkeys unchanged. Preserved nonproxy fixture-key RED and exact127 /usr wrapper→unmounted /opt ELF failure;minimal approved fake-key prerequisite/proper executable pin,focused andwholefile recheck. No P5 overlap,#662,fullgate,push or live-provider claim. Full evidence agents/fethry/work/queue-332/join1961/.
|
||||
|
||||
2026-10-26 — Fethry row332 named mutants3/3 killed on unchanged d6dc04e84 source: OAuth-only env leak1/1RED→restored2/0;literal models-file key5/2RED→restored7/0;serialized session key1/6RED→restored actual-context7/0. Exact anchors/all6 source SHA restoration,private/nice19/originalbound receipts andcleanup0. HeavyM3 after227SLOTBACK only;directSLOTBACK toSteelbeak+Sage afterward. Receipts-only localcommit,no push. Fresh review/fullgate/live acceptance still pending;not fullacceptance.
|
||||
- 2026-10-24 — steelbeak — #1728 / row227 before: transplanted Gizmoduck's unrun C2-14 driver and packet onto refactor487500a16 (471717c59/8039fc1a9). Recovered one-driver/sync-retry/read-only-store choices; replacing no-launcher stand-in with landed row217 harness. Landed-row skips need activation; row288 write/revert/save dependency remains open. Static only under sage-4166; no Node/npm/tests before CLEAR. Notes: agents/steelbeak/work/queue-227/BUILD.md.
|
||||
|
||||
2026-10-26 | Steelbeak | Mos1961 row227 preparation: rebased UNTESTED56233337b onto09a847eda, local HEAD5a0c801cb; append-only log conflicts retained both sides. Reconciled actual save/project, editor.user and lookup tuple APIs; added operation-local push credential/result assertions and observed managed library_get before C2-06 reply adapter. All17 original names/order/assertions/deadlines retained; private driver HOME/config. Whole five-file script manifest and177-file literal-import closure prepared. Static shell/whitespace/source checks only; no Node/npm/run/tests/push/dispatch. Await serial227 slot after334/332; parent owns gates/review/landing. No662/657/658 code,331 tracking not a product hold.
|
||||
|
||||
2026-10-26 | Steelbeak | Row227 first whole targeted acceptance RED beforeS1a, exit1/0.49s: credential-format. Isolated npmci root/webui0; rawstdout281bytes SHAefd9e00b7b292f96e62d8672a09ffcfdfe31182bb82b45277b22836e39e61479; pins beforeafter identical. Source diagnosed fixture13/12/13 vs credentials minimum16; fixture-only18/17/18 remediation prepared, not rerun. Additional observed strictnice failure bash-4/driver16 despite outer nice19 remains UNRESOLVED, no scheduler/deadline changes. Observed owned survivors0, private root removed. Full first-run evidence agents/steelbeak/work/queue-227/runs/first. No GREEN/fullgate/admission/push/dispatch; SLOTBACK to parent.
|
||||
|
||||
2026-10-26 | Steelbeak | Row227 authorized owned native-priority gate prerequisite: Python self/preexec19 plus quiet Node own set/getPriority preload, separate receipts. Probe Node/directchild native19 exit0/no drift. Corrected whole acceptance then STOPPED exit143/0.288s beforeS1a on measured post-preload drift e2ePID2598465 native19 then16; bash-4. No daemon attribution proven/no scheduler remediation/rerun. Rawstdout36bytes SHAa695ba02e8fcfe4b103fba373fb7b7eabb3736086eccde37fb3df7797c0a1a27, pre/postpins unchanged, survivors0/private roots removed. FirstRED immutable; separate runs/priorityprobe and runs/corrected1. Parent boundary report, no global/fullgate/live traffic.
|
||||
|
||||
2026-10-27 | Steelbeak | Row227 R1 CHANGES static response, reportSHA30bc5f1f... verified/fullread. APPEND-ONLY CORRECTION: actual fake lengths14/13/14->19/18/19; earlier13/12/13->18/17/18 metadata wrong, existing valid current values unchanged. Prior packet39f149fb and consumed evidence immutable. Prepared owned PID/start ancestry monitor without global nice/argv scan or Node exemption, fail-closed pins/capture/receipts/cleanup, real launcher/bwrap/runner/adapter identity-release preload route through fixture-only seam; added own made-up ZAI fixture key for joined real P3 preflight plus leak/history guards. No product/preflight/ENV_ALLOW authority edits, Node/parser/tests/priority execution, commit/push; fresh independent R2 review and1014 admission still required.
|
||||
|
||||
2026-11-02 | Lead sub-agent (Claude Opus 5.5, under T3 c5c1e8ba) | Row 227 R2 (#1728): test-case2.sh now runs standalone. Removed every tie to the R1 slot controller (ROW227_CONTROL_ROOT, nonce and permits, priority.mjs, owned bwrap wrapper, controller cleanup marker); leak check reads fixture-credentials.mjs; driver under env -i with TMPDIR in the sandbox; cleanup bounded to 3 s then SIGKILL. R1 red 0.294 s confirmed; all 17 steps passed with no step fix; two green runs 4.96 s and 5.74 s; mutants m1-m5 red at S2b, S3c, S4, S5b, S6, m6 (requireCitation) survived and is a follow-up; tip check on fddae79ef green 5.05 s, no conflicts. Code 04e1ce24c; record in agents/steelbeak/work/queue-227/BUILD.md "R2".
|
||||
|
||||
2026-11-02 | Lead sub-agent (Claude Opus 5.5, under T3 c5c1e8ba) | Row 227 R3 (#1728): test-case2.sh sandbox guard. A failed mktemp, mkdir or output redirect now exits 2 before any path, trap or process; the root must be a new empty directory of this user, kept as its physical path with its device:inode, and sweep_sandbox and remove_sandbox in scripts/case2/sandbox.sh refuse on their own unless it still matches. The kill sweep compares cwd targets as strings (root or root plus "/"), so *, ? and [ are literal, with one find over 1031 links in 56 ms. A TMPDIR whose tools.sock path would pass 107 bytes is refused at entry (TMPDIR plus 64, so at most 43 bytes). R2 red shown on dummy links only; failure controls green inside a fresh PID namespace; bracket control killed 3 sandbox sentinels and spared 4 lookalikes; plain runs 5.64 s and 5.20 s; TERM and INT closed in 130 to 1247 ms, a held driver in 3.07 to 3.10 s; tip check on 5df0e9d6f green 5.18 s, no conflicts. Code abc66a598; record in agents/steelbeak/work/queue-227/BUILD.md "R3: the sandbox guard".
|
||||
|
||||
## 2026-11-02, Vikunja #780 and #781: two gate flakes made deterministic
|
||||
|
||||
Before: project read.test.mjs "path history is bounded at 100" failed with a raw ENOENT on .git/objects/pack/tmp_idx_*,
|
||||
and webui preview.test.mjs:209 got 200 where it expects 502. Code 7e0d3c93f (#780), 1009bbfaf (#781), not pushed.
|
||||
|
||||
Causes, each confirmed
|
||||
- #780: the fixture git helpers ran a bare git commit. Git 2.55 then starts a detached "git maintenance run --auto"
|
||||
that repacks the fixture repository and creates and removes tmp_idx_* and pack temp files while inspectGit walks
|
||||
.git (trace2 capture shows the spawn). inspectGit lists a name, the file is gone at lstat, raw ENOENT escapes.
|
||||
SAFE already carried maintenance.auto=false and gc.auto=0 for product git calls, so only the test helpers and
|
||||
inspectGit's own walk were exposed.
|
||||
- #781: leasePort ignored {closed:true}. Without a lane it probed an ephemeral port and closed it, so nothing held it
|
||||
and a parallel test file could bind it and answer. With a lane the per-port lock was held but no socket was.
|
||||
|
||||
Design
|
||||
- #780: the project, bus spec-fixtures and webui tester-fixture git helpers pass -c maintenance.auto=false
|
||||
-c gc.auto=0. inspectGit maps ENOENT from a listed entry's lstat or a directory readdir to ProjectError
|
||||
project-repository "git metadata changed during inspection": it refuses, never skips or retries, because the
|
||||
metadata did not hold still. A missing .git keeps its own error. The pin test replaces fs.readdirSync
|
||||
(syncBuiltinESMExports) and removes the named entry inside the call, file and directory. No production hook.
|
||||
- #781: leaseClosedPort holds a bound, non-listening socket in a perl child until the test's after hook. Connects get
|
||||
ECONNREFUSED, other binds get EADDRINUSE, the kernel's bind(0) skips it (checked over 200 allocations). Lane mode keeps
|
||||
its band and per-port flock and releases the socket before the lock. The child exits on stdin EOF, so an abrupt death
|
||||
releases it. leasePort now refuses a closed option, so a stale call cannot get the unheld port again.
|
||||
|
||||
Choices and tradeoffs
|
||||
- Rejected a listener that resets on accept: the client sees ECONNRESET or UND_ERR_SOCKET depending on timing, and
|
||||
service.test.mjs:473 asserts "unreachable (ECONNREFUSED)". The bound socket keeps every assertion unchanged.
|
||||
- preview, webui serve and service (4 sites) take leaseClosedPort(t), which needs perl and fails closed naming it without.
|
||||
stack-release freePort, control-board getFreePort and tester-cli freePort listen on the port themselves, keep leasePort
|
||||
and drop the ignored option. Those keep a probe-then-bind window; closing it needs the caller to bind, out of scope.
|
||||
- The first mutant run hung: my new tests did not release holders on a failed assertion. They now drain in t.after.
|
||||
|
||||
After (pass/fail/skip): project 42/0/0 1.2 s; webui 496/0/0 69.5 s; control-board 130/0/0 0.8 s; stack-release.test
|
||||
225/0/0 628 s; gate-lane-fixtures 13/0/0; gate-lane 13/0/0; bus and harness spec-fixtures importers 100/0/0 15 s; library
|
||||
sync, mirror, case2-install 69/0/0; read.test.mjs 10 of 10 green. No hash or size pins on any changed file. Mutants, each
|
||||
restored by git checkout with a clean status: closed lease probes and closes again, and holder released immediately, each
|
||||
killed by three gate-lane-fixtures tests; leasePort accepts closed again, killed by its refusal test; inspectGit mapping
|
||||
removed, killed by the read.test.mjs vanished-entry test.
|
||||
|
||||
## 2026-11-03, Vikunja #780 R2: fresh recursive lstat restored; corrections to the R1 entry above
|
||||
|
||||
- The R1 walk change was broader than the ENOENT mapping. Passing the parent's stat into the recursive walk dropped the
|
||||
fresh lstat at recursive entry: a directory replaced by a symlink after its listed stat passed the stale check and
|
||||
readdirSync read through the link; one replaced by a regular file leaked a raw ENOTDIR (GPT review P2).
|
||||
- The tester-cli freePort helper (packages/webui/tests/tester-cli.test.mjs:21) has no callers and binds nothing; the
|
||||
active tester CLI test uses a private Unix socket. R1 wrongly counted it among the callers that listen themselves.
|
||||
- stack-release.test.mjs:2051 and control-board serve.test.mjs:78 still probe, close, then bind: a known risk, and
|
||||
the lead files a follow-up.
|
||||
R2, code 1977f4ffc, not pushed: walk(directory, root) stats with root ? lstatSync : statEntry and recurses walk(path),
|
||||
the reviewer's control shape; .git keeps its raw lstat, the mapper stays ENOENT only. Two read.test.mjs tests swap a
|
||||
.git/objects directory, inside its listed lstat after the real stat, for a symlink to a fixture-only outside directory
|
||||
or a file; both refuse "expected local .git directory", and were red on 9944100ad (symlink resolved, raw ENOTDIR).
|
||||
Mutant walk(path, entry) using the passed stat: killed by both. project 44/0/0; read.test.mjs alone 11/0/0 5 of 5.
|
||||
## 2026-10-26 — row333/P5 Mos1961 implementation begins (Codex)
|
||||
|
||||
Base 09a847eda on isolated t3/model-proxy-p5-quota-usage includes landed 362893d04. Accepted scope: human-only per-key quotas and optional value-free usage queue polling; no 657/658/662 work, live proxy/accounts/credentials, broad gates, queue mutation or push. Parent owns independent review and landing. Runtime overlap coordinated with Sage: collector wiring/tick/close at createUsage; Fethry owns launcher/proxy context. Evidence: agents/codex/work/queue-333/BUILD.md.
|
||||
|
||||
## 2026-10-26 — row333/P5 Mos1961 scoped candidate verified (Codex)
|
||||
|
||||
Implemented human-only model-key quota settings and human-only optional usage plugin/poll changes, native per-key accounting with trusted current/retiring run attribution, bounded management queue reads with immediate client/upstream value hashing, append-only telemetry isolated from quota decisions, and proxy-labelled Console numbers. No schema/deadline/role/launcher/harness/session/business-route changes. Parent-authorized additive usage registry inventories retain every old entry/assertion. Original limit-stop exact subject assertion caught an extra-run regression; retained RED18, reported before retry, corrected production through separate internal context without changing that assertion. Further missing-context and supplied-ID bypass tests fail closed.
|
||||
|
||||
Final scoped current whole-file proof: 174/174 PASS across 24 files, serial nice19/private config and tmp roots, unchanged budgets. Upstream-value mutant killed (4 failures), restored byte-identically, positive restoration plus final GREEN. Evidence and 202-input source freeze: agents/codex/work/queue-333/BUILD.md, source-inputs.sha256 and receipts/24-final-current-wholefiles-green.txt. Own scratch cleaned; worktree retained. Parent owns fresh review and admitted combined/full/browser gates under1014.Q264. No queue mutation, remote post, push, merge or landing.
|
||||
|
||||
## 2026-10-26 — row333/P5 independent R1 CHANGES repair begins (Codex)
|
||||
|
||||
Same isolated branch at503b91e; original history preserved. Verified complete real review SHA2567c95672a30c0d5c39189c7c7d610ada89cd539dcb9413617071fbb81200fd008; findings: P1 foreign-listener queue drain after identity refusal; P2 plain twelve-hex legacy account reinterpretation and empty-check metadata lookup; P2 startup blocked on optional first poll. All source-confirmed. Sequential RED→GREEN repairs in P5 ownership only; receipts/review/response at agents/codex/work/queue-333/r1-repair. Parent retains new independentR2 and heavy/full/browser/combined gates. No queue mutation/push/landing.
|
||||
|
||||
## 2026-10-26 — row333/P5 R1 local test priority STOP (Codex)
|
||||
|
||||
Mos1971 priority correction applied: earlier R1 nice-only behavior receipts01–06 are priority-unverified. First own-native setPriority/readback attempt07 observed real drift: testPID2643590 entered19, finished16; wrapper2643577 entered19, finished16. Exit78 UNVERIFIED/STOP; six behavior assertions do not establish GREEN. Node test-runner root did not run the forwarded preload, so direct-child handshake capture was incomplete too. All local test execution stopped; no scheduler change/retry. Continue only authorized source/regression preparation for admitted runner, preserving503 and everyrawreceipt. Detailed evidence agents/codex/work/queue-333/r1-repair/RESPONSE.md.
|
||||
|
||||
## 2026-10-26 — row333/P5 R1 source packet preparation (Codex)
|
||||
|
||||
All3 R1 fixes authored without subsequent local execution: serialized fresh/sticky instance identity fence before queue drain; shared validated daily-model leaf classification restoring plain12hex account semantics and no-check bypass; initial optional poll moved to the same supervised background singleflight path as interval polling. Current controls cover matching/foreign/no-issued-key identity, native current/retiring attribution, legacy matching/report/chief reset and old/new daily fences, held-response native readiness/work/release/failure and unchanged5000ms close deadline. Existing503 cumulative-model fixtures retargeted to accepted daily leaves or plain legacy-account semantics; pre-P5/base assertions/deadlines remain.
|
||||
|
||||
Owner directed static-only fallback after actual nativepriority drift: no new product commit, original503 HEAD retained, R1/rawhistory preserved. Full source/test diff, original503+controls baseline and fixed overlays, exact bytes/SHA256/size/Gitblob pins, static dependencies and24+4 whole-file list are prepared under agents/codex/work/queue-333/r1-repair/packet. Static pins are not consumed-source/runtime provenance; all current controls need admittedrunner native root+actualtestchild strict19 evidence and realRED/GREEN before any productcommit. Parent owns pending1014 gate entry/profile, independentR2 and later integration/full/browser/landing; no source freeze will be silently changed.
|
||||
|
||||
2026-11-03T00:12:08Z | Claude Opus 5.5 implementation sub-agent (lead T3 c5c1e8ba) | row 333 (#1831) R3 rotation fix on t3/row333-r3-fix, product commit 3692fca52 on b37cc5087 | Ruling 1: a daily key quota follows the agent's key lineage (current, retiring, then up to 64 earlier ids kept in a new optional `previous` field on the model record), so rotation and re-issue keep the quota and its count; an id in two lineages refuses proxy-key-refused; a fired agent's leaf is orphaned, limits nothing, logs limit-key-orphaned once and is listed in the Console usage view. Ruling 2: key-quota-no-model-key for an agent with no model key under a key quota, passed through by name. Ruling 3: covered by the lineage, no mayLaunch change. Ruling 4: the usage module gets one frozen object holding readUsageQueue only. Ruling 5: every telemetry fixture wait rejects by name at a real-timer deadline. Runs: bus 1393/1393, plugins 132/132, business 293/293, webui 499/499, cli stack-release 225/225, stack-release-external 25/25, stack-upgrade 25/25 and launch-limit-checks 5/5; no skips, the model-final-completion flake did not appear; mutants M1 to M4 and M4b each killed. Departure: the human settings writer still stamps a new since on a renamed leaf, so a moved leaf restarts its count; follow-up recommended, not built. No migration, push, queue or PR action.
|
||||
|
||||
2026-11-03T01:27:26Z | Claude Opus 5.5 implementation sub-agent (lead T3 c5c1e8ba) | row 333 (#1831) R4 since carry fix on t3/row333-r4-fix, product commit f65faf9df on fe3ef5128, BUILD.md R4 section a13050012 | Ruling 1: the bus runtime passes launchSettings a key lineage lookup read from its own credential records (ids only); a new daily key quota takes the earliest stored since among the old document's daily key quotas in its key's lineage, now only when there is none, so a quota moved from a rotated or re-issued key keeps its count; a reset still sets now, a caller since still refuses, a quota removed and added back later is new, and a failed or malformed lookup refuses proxy-key-refused. Ruling 2: every limits refresh updates the remembered orphan set, empty when no daily key quota is left, so remove then re-add logs again; in memory only, a restart observes afresh. Ruling 3: the poll barrier's last yield is on the captured real setImmediate inside the deadline. Ruling 4: BUILD.md records the 64-id bound as a limit and corrects R3 departure 4 (a late queued event loses telemetry attribution to the reconcile log; not a quota bypass). Runs: bus 1397/1397, plugins 132/132, business 295/295, webui 499/499 (run 1 498/499 with editor-browser.test.mjs:93 timed out under load, the file 16/16 alone, then 499/499 twice), cli stack-release 225/225, stack-release-external 25/25, stack-upgrade 25/25, launch-limit-checks 5/5, harness tools 23/23; no skips, the model-final-completion flake did not appear; mutants M1 to M4, M4b and M5 each killed. Not run: 19 cli files that import bus runtime.mjs without pinning it. No migration, push, queue or PR action.
|
||||
|
||||
2026-11-03T02:41:07Z | Claude Sonnet 5.5 implementation sub-agent (lead T3 c5c1e8ba) | row 333 (#1831) follow-ups on t3/row333-followups, base 1ff45c4ad, commits 3dc824ea1 (#783), 38cfa7233 (#778), 0e7e203db (#779), 5fbf3d2b5 (#782) | #783: a failed lineage lookup now keeps only the remembered orphan ids the refreshed document still holds and adds none, so a leaf removed and added back during the failure logs again; quota decisions are unchanged and a failed lookup still refuses. #778: createProxyUsage counts, per business and in memory, a batch the proxy gave up and the bus did not write; the Console shows the count only above 0 and the log code stays proxy-usage-read-failed. Departure from the brief rule (a read that throws drained nothing): a proxy-client-response error counts as a drop, because the client had already taken a 2xx answer off the queue; down, redirected and non-2xx answers do not. #779: the business-imports helper reads imports with a scanner, no parser dependency; comments are blanked, string and regular-expression contents are not matched, a spaced dynamic import counts; a non-literal dynamic import, an unterminated construct, a missing or non-file target and a real path outside the repository throw; 13 tests on small trees, 8 fail on the old helper; the real-tree output is unchanged. #782: the control-board refusal test holds its own listener for the whole test; stack-release T-I4 takes a closed lease because its port only reaches refused installs. The other 22 freePort callers hand a port to stack-release.sh rehearse, which probes it and starts a Console later; that needs a script change (accept --port 0, start serve on port 0, read the bound port from the Console line, run the reserved and holder checks after that), so it is a design, not built, and no retry was added. The remaining window is a process outside the lanes taking the probed port between probe and listen; lanes use 61000-61255, outside the ephemeral range. Runs: bus 1402/1402 plus its 1-test file, webui 500/500, control-board 130/130, cli stack-release 225/225, stack-release-external 25/25, stack-upgrade 25/25, launch-limit-checks 5/5, business-imports 13/13; no skips; neither known flake appeared. Mutants: keep the whole remembered set killed by the #783 test in p5-key-lineage; count a pre-read failure as a drop killed by two proxy-usage tests; drop the containment check killed by the #779 outside-repository test; startServer opening a loopback socket before refusing passes the old control-board test and fails the new one with EADDRINUSE. No push, queue or PR action.
|
||||
|
||||
2026-11-03T03:00:17Z | Claude Sonnet 5.5 implementation sub-agent (lead T3 c5c1e8ba) | row 333 (#1831) follow-ups R2 fix on t3/row333-followups-r2-fix, product commit d3b6ab11d on 2ba22b4cb | #779 scanner findings: a dynamic import inside a template substitution (${...}) now throws "unsupported import inside a template substitution" naming the file, so the existence and containment checks no longer miss it; a substitution is read as code to its closing brace (strings, comments, nested templates and braces handled), refused only if it holds a dynamic import, `${import.meta.url}` and `${x.import}` stay allowed, and a substitution with no import is dropped as before; a template nested in a substitution is now read to its end instead of misread. A slash after `++` or `--` is division when the character before the pair ends an operand (`n++ / 2`) and a regular expression when it does not (`x = ++/re/.lastIndex`); the one rare form still misread, a prefix `++` applied to a regular expression member right after `)`, `]`, a word or a line break, is named in the header. Real-tree output byte-identical (6 files, sha256 b5772c3a). 6 new tests: 4 fail on 2ba22b4cb (two substitution refusal tests, the unterminated-substitution test, the postfix test) and 2 guard tests (allowed substitutions, regular expressions after operators and prefix ++) pass on both. Runs: business-imports 19/19, stack-release-external 25/25, no skips; M1 (no import check) and M2 (no postfix rule) killed, extra M3 on the prefix guard killed. Not run: stack-release and stack-upgrade (they import the helper, no pin on it; the landing gate runs them). No push, queue or PR action.
|
||||
|
||||
2026-11-03T03:15:55Z | Claude Sonnet 5.5 implementation sub-agent (lead T3 c5c1e8ba) | row 333 (#1831) follow-ups R3 fix on t3/row333-followups-r3-fix, product commit 180fb8ab0 on 42c72d781 | #779 P2 from the R2 re-review: the lookbehind in DYNAMIC and in the dynamic branch of IMPORT excluded any dot before `import`, which also skipped the last dot of `...`, so `${({...import(target)})}` returned [] for an existing, a missing and an outside target and `{...import(name)}` in plain code was neither found nor refused. Both patterns now build from one fragment, IMPORT_WORD = (?<![\w$])(?<!(?<!\.)\.)import: a word character or $ before it, or a single dot (x.import, x?.import), still makes it a property call; a dot after a dot is a spread and counts. `1..import(` is a valid property call on a number that now reads as an import, which errs toward refusal; confirmed by a probe and named in the header, as is the spread rule. Real-tree output byte-identical (cmp, 6 files). 11 new tests: 9 fail on 42c72d781 (spread in a substitution for an existing, a missing, an outside target and array spread; spread in plain code found, found as array spread, reaches the missing-target check, refused when not a plain string in object and array form), each with a returned [] or no exception; 2 guards (x.import and x?.import in plain code and in a substitution) pass on both. Runs: business-imports 30/30, stack-release-external 25/25, no skips. Mutants killed: M1 old lookbehind in DYNAMIC only (6 tests), M2 old lookbehind in IMPORT only (3 tests), M3 dot dropped from the exclusion (4 tests). Not done: `x. import(` with a space after the dot already read as an import before this round and still does. No push, queue or PR action.
|
||||
2026-11-03T02:52:45Z | Claude Opus 5.5 implementation sub-agent (lead T3 c5c1e8ba) | Vikunja #774 F1 and F4 for row 332 (model proxy P3, 5df0e9d6f) on t3/proxy-launch-774, product commit 85ecdfbde on 1ff45c4ad | F1: with system.proxy set the first launcher check no longer returns before the account, sandbox, capacity and limit checks. It skips only the harness preflight and the session proxy key match, which need the key P2 admits in startLocked; it runs harness-off (already first on the tip), the account declaration with credential proxy only, sandboxProblem, limitHit, mayLaunch and admission, so a launch that can never start refuses before authorizeLaunch, the workspace and checkouts, and modelPreflight. Added beyond the reviewer's list: the account-is-credential match against host credential env values and the admission generation re-check, both key-independent. The first proxy pass refuses only when the primary and the fallback model both refuse, with the primary's reason, and lets mayLaunch key-quota-no-model-key (row 333) through so P2 can issue the first key. The final check is unchanged, still before newRun and spawn; modelPreflight did not move. F4: rename path. The option is testProxy and createLauncher throws test-proxy-refused when it comes with system.proxy, because launch-account.test.mjs is a second caller (three row 332 R2 tests). Tests: proxy-launch-order.test.mjs 6 (capacity-full, limit-reached, sandbox-unavailable, upstream account credential, final-check key match, daily key quota with no key yet) and the launcher.test.mjs F4 throw test; on 1ff45c4ad five order tests fail, the key-match test passes by design and the F4 test fails on a business-file error. Runs: cli run 1 1112/1114 with 1 fail and 1 skip (case2-unit row253 C4 member query read outer-timeout for inner-timeout under host load; the file alone 83/83), cli run 2 1113/1114 with 1 skip (FED R7); bus 1397/1397, the model-final-completion flake did not appear; launch-limit-checks 5/5 (it reads launcher.mjs). Mutants M1 (early return before limitHit), M2 (no sandbox check in the first proxy pass) and M3 (no testProxy throw) each killed. No push, queue, Vikunja, Gitea or PR action.
|
||||
|
||||
2026-11-03T03:41:28Z | Claude Opus 5.5 implementation sub-agent (lead T3 c5c1e8ba) | Vikunja #774 R2 for row 332 (GPT review P2 on round 1) on t3/proxy-launch-774-r2-fix, product commit b8f01a189 on a605e44d1 | Correction to the round 1 entry: its first proxy check refused only when the primary and the fallback both refused, so a healthy primary at capacity zero passed it and was refused only after modelPreflight. Both checks now pick the route through one helper, pickRoute in check(): the primary when its harness preflight passes, else the fallback through its own preflight. The first check calls it with a stand-in session proxy (PENDING_ADMISSION_KEY "pending-admission", a fixed non-secret marker, on the configured proxy port) that reaches only the preflights, then gates the picked route only, gate() still given null; no union and no retry. The final check calls it with proxyFor; its body is the round 1 code moved into the helper (proxyFor renamed proxyOf, two spaces less indent). Nothing reads the first check's route: startLocked takes model and account from the final check. Fixture options extra, real and hostEnv load the real claude-code harness with a pi fallback. Tests: 7 new in proxy-launch-order.test.mjs (healthy primary at capacity zero, fallback launch, failed primary at capacity zero, fallback at capacity zero, both preflights fail, no fallback, stand-in key absent from the launch log, bus events, session.json and the data root); on a605e44d1 the four refusal tests fail on modelPreflight 1 !== 0 and the three live tests pass. Runs: cli 1120/1121 with 1 skip (FED R7), 768 s; bus 1397/1397, 52 s; launch-limit-checks 5/5; neither known flake appeared. Mutants M4 (fall back on any primary gate refusal, test 1), M5 (first check never falls back, tests 2, 3, 4a, 4b, 6), M6 (no predicted preflight, tests 3, 4a, 4b, 5), the reviewer's unconditional throw at the helper's fallback decision (tests 2, 3, 4a, 4b, 6) and M7 (stand-in key written to the launch log, test 6) each killed. No push, queue, Vikunja, Gitea or PR action.
|
||||
2026-11-03T04:07:40Z | Claude Opus 5.5 implementation sub-agent (lead T3 c5c1e8ba) | editor-browser.test.mjs:154 under Chromium 156 (Vikunja #784) on t3/editor-chromium-156, test commit 0c6aa1a1e on 1ff45c4ad | Case 2, no product defect: Chromium 156 checks script-src-attr when an inline handler attribute is created, also in a document with no window (WPT PR 62762; PR 64290 later skips such documents and 156 lacks it). All four reports come from prosemirror-view readHTML's innerHTML parse into a new createHTMLDocument (editor.js:8212:19, target the page document, one per pasted handler: img onerror, a onclick, a onmouseover, svg onload); no on* attribute reaches the live page and injected stays null; Chromium 153, 151 and Brave 154 report none for the same paste. Fix is test-only: the page's CSP record sets aside a script-src-attr report whose sourceFile is /editor.js, whose line is readHTML's parse (computed from the bundle, with a guard pinning those lines and detachedDoc) and whose target is the document; quiet(), inert(), injected, errors, rejections and the Console CSP are unchanged. New test: after a hostile paste, a handler set on a live editor paragraph, one parsed into a page-owned element never attached, and one set through prosemirror-view's attributes prop each still fail quiet(). editor-browser 17/17, editor plus editor-provenance 11/11, no skips; 4 mutants killed (all script-src-attr, target only, target only without the paragraph case, editor.js at any line). Residual: an element from that parse attached to the page after its report was sent would not be caught by the CSP record; on 156 its listener is never set. Full webui suite not run (bundle not rebuilt); Chromium 152 not on the host. No push, queue or PR action.
|
||||
2026-11-03T04:12:57Z | Claude Opus 5.5 implementation sub-agent (lead T3 c5c1e8ba) | Vikunja #415 and #416, .53 and .54 Console writes, on t3/console-writes-53-54, fix commit bd79daffd on 1ff45c4ad | Factory: scripts/case2-unit.sh takes the paired bare --sso --send (the lane b00019548 serve_flags rule), refuses either alone, still refuses the preview set and the proof pair, and before any unit write a bounded query run as the stack user, through the existing config-query supervisor, checks for console.sso. Library: unchanged and still read-only. Library --send with forward-auth and proof is not done: since #385 the tip's Console refuses --send without --sso (packages/webui/src/cli.mjs:63, serve.mjs:681), and reverting that is more than about 40 lines across the webui, service, release and upgrade scripts and reopens a reviewed security boundary, so it goes back to the lead. docs/guides/case1-business.mosaic-stack.json launches claude-opus-5-5 with provider proxy, route anthropic, under account factory with credential proxy. Tests: 5 new in case2-unit.test.mjs (4 RED on base) and 1 updated; case1-business-file.test.mjs 1 updated (RED on the base document) and 1 new. Runs: cli case2-unit 88/88, stack-upgrade 25/25, case1-accept 53/53; business case1-business-file 8/8, case1-project-key 3/3, chief-library-credentials 3/3; no skips. Mutants: factory --send without --sso and library without --proof-header required, each killed. Not done: scripts/case1-accept.sh still refuses --sso and --send in the args file (out of scope). No push, queue or PR action.
|
||||
2026-11-03T04:36:00Z | Claude Sonnet 5.5 implementation sub-agent (lead T3 c5c1e8ba) | editor-browser.test.mjs paste test, round 2 for Vikunja #784 on t3/784-r2, test commit e71222d1a on 0c6aa1a1e | GPT review of 0c6aa1a1e found that the CSP filter (directive, editor.js, readHTML line, target document) also sets aside a handler-bearing element that is attached to the live page and removed before its report is sent, because Chromium then targets the document too. The reviewer's insertion after editor.js:8212 (append reviewNode to body, put it back) passed the paste test and the live-handler test; reproduced here, editor-browser 17/17 with it. Fix is test-only: the page record now runs a MutationObserver on the live document (subtree, childList, attributes) that notes an added element, or a descendant of one, carrying an on* attribute and any on* attribute set in the page, without reading CSP events; h.quiet() asserts window.__live is empty; the live-handler test gains a case for a handler attached and removed in one turn and checks per case that the observer saw the handler (not for the page-owned element never attached). Runs: the reviewer's insertion now fails the paste test and the live-handler test with 'added a with onmouseover'; a variant that attaches a handler-bearing parent fails the same two; the four earlier weakened-filter mutants (all script-src-attr, target only, target only without the paragraph case, editor.js at any line) each fail the live-handler test, as does the observer pointed at a detached node; mutants in editor.js at another line and in app.js fail; one appended to the readHTML line fails the pin guard at load. Unmutated: editor-browser 17/17 (13.3 s), editor 5/5, editor-provenance 6/6, no skips; every mutant restored, git status empty. The earlier #784 BUILD-LOG and SESSIONS lines are on 1bf83078b, not on this base, so a merge keeps both appends. No push, queue or PR action.
|
||||
|
||||
2026-11-03 | Lead Codex, request-to-product discovery (Vikunja #797, Gitea #1839) | Before: pomodoro request has no product project/approved requirement; Console resolves only grant decisions with buttons although REQ-WEB-2 requires each option; broker and task adapter both use Stack PRD 1.19 baked catalogue. Scope: prepare the concrete lifecycle/authority design before any schema or role change. No runtime/config change. Claude Sonnet discovery delegate failed 503 auth_unavailable/account rate limit; no provider substitution.
|
||||
|
||||
2026-11-03 | Lead Codex, request-to-product design handoff (Vikunja #797, Gitea #1839) | After: docs/plans/2026-11-03_request-to-product-design.md proposes general Console answers first, durable pre-task intake and three modes, typed project bootstrap, project-scoped approved PRDs and automatic continuation through reviewed delivery; original pomodoro is the acceptance case. Opus independent builder check also failed Claude rate limit; lead self-check only, no independent approval. Await owner decision on concrete authority/schema scope and temporary GPT implementation delegation while Claude is unavailable. Documentation only; product behavior and acceptance not claimed.
|
||||
|
||||
2026-11-03 | Lead Codex, #797 / Gitea #1839 implementation start | Jason reports CLI Proxy API leaves Claude accounts unauthenticated and authorizes GPT agents for these tasks. Execute the staged design with GPT coding and independent review; general Console buttons first under existing REQ-WEB-2, detailed lifecycle/PRD plan in parallel. No further Claude calls or production-host changes.
|
||||
|
||||
2026-11-03 | Lead Codex, terminology migration discovery (#798, Gitea #1840) | Before: user-facing prose, role contracts, owner principal, config human key and events/transports use legacy human terminology; a separate user principal already means a granted user. Jason explicitly includes internal identifiers in the enhancement. Created #798 and #1840; Luna will inventory a compatible staged rename after #797, with no change to authority or immutable historical evidence.
|
||||
|
||||
2026-11-03 | Lead Codex, #798 / Gitea #1840 inventory outcome | Luna read-only report completed with compatibility concerns. Lead verified owner-vs-granted-user principal split, business config key, optional restricted role messaging and human.input schema/trigger; recorded corrected scope and staged migration in docs/plans/2026-11-03_user-terminology-migration.md. No runtime/code/config rename performed. Implementation follows #797; stronger GPT review required for schema/proof/history readers. Queue refusal in linked inventory checkout was not bypassed.
|
||||
|
||||
2026-11-03 | Lead Codex, #797 / Gitea #1839 lifecycle plan integration | Integrated Astra planning commits as 260f2ce7e and 63bd48a5f; eight bounded implementation tasks and proposed exact PRD addendum, no production code. Lead checked project-map/runtime/requirement/continuation interfaces and retained the exact PRD adoption gate. Preserved the original pomodoro wording and owner-reported event/message IDs from the original conversation item as an explicitly labeled quotation export, not a raw runtime row/live receipt. Console implementation remains a separate active task; lifecycle implementation follows its review/integration.
|
||||
|
||||
2026-11-03 | GPT-6.1 Sol implementation sub-agent | #797 / Gitea #1839 stage 1 before | Prepared checkout t3/b15e72fa at 7e849a7b0b635d34950a5c5c2e4b78c4238fe651. Console answers currently require two-option grant requests. Scope: ordinary 2–9 choices through existing preview/confirmation/resolve, preserved grant and identity gates; no tracker/role/PRD/runtime changes. Baseline bus 12/12; initial WebUI 12 pass/5 fail from missing oauth4webapi@3.8.8, restored with locked npm ci --ignore-scripts, then WebUI 17/17 including Chromium. Intended RED: broker 14 pass/3 fail decision-not-eligible; HTTP/browser 12 pass/5 fail ordinary confirmation 503 or absent option panel; real SSO browser 0 pass/1 fail zero buttons instead of three. Owner continuation asks for user in changed prose, technical identifiers retained for #798.
|
||||
|
||||
2026-11-03 | GPT-6.1 Sol implementation sub-agent | #797 / Gitea #1839 stage 1 after | Ordinary user-routed decisions now expose authoritative kind/options through the existing two Console verbs; confirmation uses the selected key/text and ordinary receipts say Recorded. The digest binds the complete decision row and raise authorization/grant context; stale membership/context refuses transactionally. Grant approve/deny/summary and one-use executor path, OIDC/session/origin checks, role attribution and authority remain intact. Cancellation, navigation, reload, closure and changed-context refresh drop UI confirmations without replay. Added real fake-OP signed-in Chromium -> HTTP -> broker third-option coverage: one resolution, verified-subject audit, raiser notice and zero grant activity. RED-to-GREEN also checked project/spec digest binding. Targeted broker 17/17 and WebUI 25/25; final full bus 1407/1407 and WebUI 509/509, zero failures/skips. First full runs: bus 1406 pass/1 fail at unchanged host-run T27 sweep (expected one removed dir, got []), isolated T27 group 4/4 and full rerun green without changing it; WebUI 507 pass/1 fail/1 skip due absent package-local esbuild@0.28.2, restored with its lockfile, isolated build/provenance 7/7 and full rerun green. A newly added SSO test transport initially used nonexistent broker.release; corrected to disconnect after diagnosing its timeout, without weakening assertions. No independent reviewer launched; controller provides review. No tracker, role JSON, PRD, host/service/config/secrets changes, push, merge, PR or deployment. Internal identifier migration remains #798 / Gitea #1840.
|
||||
|
||||
2026-11-03 | GPT-6.1 Sol implementation sub-agent | #797 / Gitea #1839 Console fix round 1 before | Fix base 7b51dbbba4778e7cb4d171dbf4c6e10f011b926e in the original prepared t3/b15e72fa checkout. Verify Important I1 in the existing Chromium harness: an obsolete A inbox/trail read (including kept-data fallback on error) must not replace shared answer state behind B controls. Scope is the decision state/render generation boundary only; controller supplies re-check. M1 editor-build warning remains deferred; no bus, lifecycle, rename, dependency, tracker or live operations.
|
||||
|
||||
2026-11-03 | GPT-6.1 Sol implementation sub-agent | #797 / Gitea #1839 Console fix round 1 after | Verified Important I1 with three real Chromium regressions on 7b51dbbba: delayed A inbox, delayed A trail and failed delayed A trail with cached fallback all left B displayed but sent A confirmation URLs (0 pass/3 fail, no fixture/module errors). Root cause: decisionView mutated shared answer before render discarded obsolete HTML; fallback could start after a newer render too. Pass the originating render validity closure (generation, exact route, signed-in state) through both live and kept-data view paths and check before decision answer-state mutation; use the same check before committing page HTML. Small decision-state fix only; no renderer cleanup. GREEN I1 3/3; covering browser/SSO/HTTP 28/28; full WebUI 512/512, zero failures/skips/cancellations. Full output retains M1 ignored-bare-import warning at unchanged prosemirror-transform mark.ts import; deferred per controller. No bus file changed or bus suite rerun, no lifecycle/editor/rename/dependency/tracker/live changes, no subagent or reviewer, no push/merge/PR. Controller supplies fresh re-check. Prior evidence preserved; round 1 logs/report under /mnt/storage/scratch/tmp/mosaic-797-.
|
||||
|
||||
2026-11-03 | Lead Codex, Console stage 1 integration (#797, Gitea #1839) | Squash-integrated reviewed worker range 7e849a7b0..95b867cf8 onto refactor 831d15f0b. Only BUILD-LOG/SESSIONS conflicted; preserved canonical bytes and appended worker deltas. Every non-log changed file byte-matches reviewed 95b867cf8. Independent R1 found I1 delayed-read answer-state race; fix 7b51dbbba..95b867cf8 has real-browser RED 0/3 then GREEN 3/3; independent R2 I1 ADDRESSED, no new breakage. Fresh sequential integrated suites: bus 1407/1407 and WebUI 512/512, no failures/skips (scratch mosaic-797-integrated-{bus,webui}.log). M1 unchanged editor-build warning deferred; original T27 transient retained as an unproven timing observation. No approved-PRD/role/schema/config/host/deployment change. Broader lifecycle remains open.
|
||||
|
||||
2026-11-03 | GPT-6.1 Sol implementation sub-agent | #797 / Gitea #1839 lifecycle Task 1 before | Prepared t3/0c734dbd checkout at assigned base 1e1357cb6e97825f6080bee15ab45efce794b137. Scope: durable pre-task intake journal, strict 3n→3o offline migration, trusted input provenance, host lifecycle foundation and authorized request.open/get/projects/propose. Three enumerated choices remain user-gated via project.bootstrap in both closed action lists only. Later resource creation, PRD activation, scoped tasks, launches and delivery remain outside this unit; absent host preparation/admission capabilities must leave a durable setup wait. Controller owns queue/tracker coordination and independent review. Red tests precede implementation; local tested commit only.
|
||||
|
||||
2026-11-03 | GPT-6.1 Sol implementation sub-agent | #797 / Gitea #1839 lifecycle Task 1 after | Added host-only createRequestStore/createRequestLifecycle, strict CAS transition reduction, byte-preserving intake from existing user-origin human.input/message records, immutable mode/association plan bindings, latest-evidence effect reservations, and broker-derived authorization for request.open/get/projects/propose. Autonomous/guided/existing are enumerated selections; existing stages a filtered software-project picker and a separate exact-association confirmation. PM preparation uses existing message.send authority and rechecks its live claim after awaits; only the owner resolves the user-routed nonblocking project.bootstrap decisions, with null task/requirement refs. No resource creation, PRD activation, scoped tasks, role launch or artifact execution. Missing preparation/admission/bootstrap/attachment remains an explicit setup wait; oversize full resource displays retain source bytes and wait at the existing decision size limit. Added five append-only lifecycle tables, immutable new 3n→3o migration, strict source/digest/version checks and fixture-only offline CLI/old-engine refusal evidence. Existing migrations, approved PRD, role JSON, Console code/verbs, queue/tracker and live config/service/secrets untouched. Minimal collateral: older migration test expectations advance to 3o; role Markdown names the newly gated action; stack-release restore counting includes all five new timed tables. RED intake 0/12; further binding RED 15/16, origin/association RED 21/23, setup/display RED 23/25 and receipt/path RED 23/25. Final intake 26/26; required intake/schema/store/hard-waits 41/41; full bus 1433/1433; full business 296/296; bounded CLI restore/accounting 7/7; sandbox import closure 1/1, all zero failures/skips. Prior full bus 1389 pass/30 fail comprised 27 changed-schema/closed-vocabulary expectations and three managed-launch failures traced to harness-binary-missing; restored existing pinned dependencies with npm ci --ignore-scripts, lockfile unchanged, then full bus 1425/1425 and final 1433/1433. Prior business 295/296 required the two existing hard-wait prose lists to match the closed vocabulary. Test fixture setup mistakes (tester switch, halted-before-launch and incomplete library mapping) were corrected without weakening assertions. Retained evidence: /mnt/storage/scratch/tmp/mosaic-797-task1-logs/; report: /mnt/storage/scratch/tmp/mosaic-797-lifecycle-task-1-report.md. Controller owns independent review and integration; local commit only, no push/merge/PR/deployment.
|
||||
|
||||
2026-11-04T00:20:48Z | Lead (Claude Opus 5.5, T3 c5c1e8ba) | #797 / Gitea #1839 lifecycle Task 1 landing | Review R1 (GPT-6.1 Sol): Needs fixes, I1 PM self-citation reachability, I2 existing route lost after setup waits, I3 stale association confirmed after async admission. I1 deferred to tracker #799 as a security follow-up (MVP rule). Fix round 1 (Sonnet 5.5 xhigh) bec358328: RequestState.route from selection.staged; staleCode recheck before admission and inside the recording transaction for propose and resume; 12 regressions that fail on 3b071cac7. Gates on bec358328: intake 38/38, full bus 1445/1445, business 296/296, zero skips (/mnt/storage/scratch/tmp/nlR5yC). Review R2 (GPT-6.1 Sol): I2 resolved; I3 partly resolved, an in-process change in the continuation after the final awaited inventory read still reaches proposal or confirmation (repro /mnt/storage/scratch/tmp/C5CJ6q). Lead decision: land 3b071cac7+bec358328 without a second round; residual is tracker #800, and the Task 2 executor must re-verify the association at execution. Tradeoff: confirmation records consent, not freshness, until #800 lands. Plan doc RequestState gains route.
|
||||
|
||||
2026-11-04T01:50:11Z | Claude Sonnet 5.5 implementation sub-agent, t3/request-lifecycle-bootstrap | #797 / Gitea #1839 lifecycle Task 2 after | Protected project bootstrap that becomes usable at runtime, on 138171ca0. Organization writer: addProject (private exact-add path under the existing lock and receipt discipline, input and serialized bytes both compared against the plan, replacement/removal/library/unrelated-key changes and a mismatched receipt refused, stale revision refused), hold (sync check under the lock), findAddition; write still refuses every project change (organization-projects-protected). New bootstrap executor journals reserve, seed, working, mapping, records, intent, chat and activate as separate receipts bootstrap:<plan_digest>:<step>; the code seed is published before the mapping and records init runs under the published mapping; interrupted effects are compared by deterministic path, stored commit and exact bytes and retained as bootstrap-uncertain, never removed or rewound. Original displayed intent is saved with writeHumanFile as the decision owner, writeRecord still cannot write spec/. Tracker: the product file omits tracker.project, the board lives in the immutable plan and admission projection, trackerFor skips reserved products and a fresh boot verifies product IDs. Runtime: activateManagedProject reloads only a receipt-backed additive root inside <dataRoot>/products after revalidating the full business, prior mappings, credentials, bots, libraries and roles; broker admission and the launcher (via host IPC request.admission) refuse a pending product until activation; restart rebuilds readiness from receipts. initializeWorking (host-only, seat/working.mjs) seeds the working repository under the existing repo lock with no work ref or push authority. #800: the bound organization revision and association are re-verified synchronously inside organization.hold at the start of execution; a mismatch records setup wait request-plan-stale and performs no effect (regression: an_organization_change_after_confirmation_waits_without_effect and four sibling stale cases). Schema change was needed and is append-only: migration 3o to 3p widens the request_events kind CHECK with bootstrap.stale and bootstrap.completed (old table renamed away, new table created under its final name, rows and seq copied, guards recreated); 13 migration-pin tests moved 3o to 3p the way Task 1 did for 3n to 3o, with a new 3o_to_3p test (rows and seq kept, guards intact, the 3o engine refuses the migrated database). RED: project-bootstrap suite failed on writer.hold missing; bus suite failed 9/10 on the kind CHECK before 3p. Corrections: the first full bus run exposed the CHECK; a test expectation for a replayed revision named the revision guard when the append-only trigger fires first (test fixed, schema unchanged); the first-boot test opened a second broker before closing the first (writer-locked, fixture fixed). GREEN: brief command 18/18, kept-green trio 49/49, business 304/304 (was 296), bus 1456/1456 (was 1445), project+launcher 80/80, stack-release 225/225, related cli suites 422/422, seat 223/223, zero skips. Logs /mnt/storage/scratch/tmp/BKItrk/. Not executed on any running instance; local commit only, no push/merge/PR/deployment.
|
||||
|
||||
2026-11-04T02:45Z | Claude Sonnet 5.5 implementation sub-agent, t3/lifecycle-bootstrap-fix-round | #797 / Gitea #1839 lifecycle Task 2 fix round | One fix round on c55849806 for review findings C1, C2, I1, I2, I3, I4; Minor items, Tasks 3-8, roles/*.json, ROUTED and all migrations untouched (no schema change). C1: seeding no longer follows a committed .mosaic link. Linked ancestors and non-regular metadata are refused in the source and in the clone, and the seed and the marker temp are written with O_EXCL|O_NOFOLLOW and renamed, so a planted link is never followed. C2: the clone goes into an exclusively created code.tmp backed by a code.tmp.claim receipt; an unclaimed or foreign-content code.tmp is kept untouched with bootstrap-uncertain, a claimed clone left by a kill is adopted exactly once, and no deterministic path is removed recursively. I1: the #800 freshness check runs before every effect including recovery effects; a mismatch appends setup wait request-plan-stale and does nothing further, evidence kept. I2: managedState classifies by layout (entry root and repo match the managed paths) and reads readiness from the marker and the committed activate receipt, so a missing bootstrap.json no longer admits an unfinished product; the launcher and trackerFor already call managedState and needed no change. I3: new packages/bus/src/request-host.mjs wires preparePlans and admitPlan in the real host from the organization document and revision, the booted tracker config and the staff the organization names; a missing tracker root or staff is a named setup wait (request-tracker-unavailable, request-staff-unavailable, request-organization-unavailable, request-organization-changed) and creates nothing; process.mjs now forwards trackers to startBroker. A normal boot with a tracker root and named staff reaches a bootstrap selection and bootstraps the project. I4: the Task 1 existing-project comparison was reversed and is fixed in localPlan with regressions in request-intake. RED/GREEN: each regression was failing on c55849806 and passes now; the regression set was mutation-checked by reverting each guard, with two exceptions recorded honestly: the executor-level metadataProblem mutant (c1-exec) still passes because git status is a second guard, and the i3 admitPlan unit test was not mutation-checked. Corrections: the committed project-file link test first failed at boot because the config loader refuses the link (test now commits the link after boot); the c2-claim mutant first survived because clone verification is a second guard (two unclaimed-code.tmp tests added); boot recovery rewrote a complete marker for a deleted reserved one, fixed by requiring the marker to prove ownership before every post-reserve effect; the i2 assertion on admission revision null was dropped because that Minor item is out of scope. First full bus run had one failure, model-final-completion 656 FIFO niceness (startNice 16 !== 19), unrelated to this change; the file passed 21/21 three times alone and the full rerun was 1477/1477. GREEN: brief trio 79/79, kept-green trio 49/49, bus 1477/1477 (was 1456), business 305/305 (was 304), project+seat 267/267, stack-release 225/225, zero skips. Limits: the selected tracker board is unverified until the first task is created; after a post-effect stale wait nothing resolves automatically, the request waits and each resume re-checks; a kill mid-clone leaves code.tmp kept and uncertain, never deleted; the prepareExisting/listProjects wiring is out of scope; admission revision stays null. Logs /mnt/storage/scratch/tmp/fix797/. Not executed on any running instance; local commit only, no push/merge/PR/deployment.
|
||||
|
||||
2026-11-04T02:51:19Z | Lead (Claude Opus 5.5, T3 c5c1e8ba) | #797 / Gitea #1839 lifecycle Task 2 landing | Task 2 c55849806 (Sonnet 5.5 xhigh): exact-add organization writer, journaled bootstrap steps, 3o->3p append-only migration, receipt-backed runtime admission. Review R1 (GPT-6.1 Sol): NEEDS FIXES, C1 seed write through a committed .mosaic link, C2 recursive code.tmp delete, I1 #800 freshness only at reservation, I2 missing marker admitted, I3 no host preparation/admission wiring, I4 Task 1 existing-project root/repo comparison reversed. Fix round 883003041 (Sonnet 5.5 xhigh): O_EXCL|O_NOFOLLOW publish, claimed code.tmp, per-effect fresh(), layout-based managedState, request-host.mjs wiring, corrected localPlan. Gates on 883003041: focused 79/79, kept-green 49/49, bus 1477/1477 (first run had one model-final-completion startNice flake, reviewer found no causal path), business 305/305, project+seat 267/267, stack-release 225/225, zero skips (/mnt/storage/scratch/tmp/fix797). Review R2: C1 C2 I3 I4 resolved; I1 (org write during intent step Git reads still lets a stale intent write), I2 (failed final marker rename or later marker removal leaves admission ready) and new N1 (preexisting <dataRoot>/working ancestor link sends the working repo outside dataRoot) open. Lead decision: land under the MVP one-round rule; all three need write access to dataRoot, a concurrent organization edit or an I/O fault, and none is reachable by a sandboxed worker. They form one hardening follow-up that must land before bootstrap is exercised on .53. Minors are tracker #801.
|
||||
|
||||
2026-11-03 | GPT-6.1 Terra implementation sub-agent | #797 / Gitea #1839 lifecycle Task 7a | Added a bounded reviewed-artifact reader for committed regular blobs in trusted bare working repositories. Uses the existing bounded Git reader and safe environment, literal paths, disabled replacement refs, full commit IDs and a 1 MiB ceiling; rejects non-regular entries and checks size before reading bytes. RED: missing reader module; GREEN: artifact 9/9 and seat 232/232, zero skips; logs /mnt/storage/scratch/tmp/0G9g1p/. Queue next refused linked-worktree use; controller owns queue and integration. Local commit only; no delivery, broker, Console, push or deployment.
|
||||
|
||||
2026-11-04T03:48:47Z | GPT-6.1 Sol implementation sub-agent, t3/pm-intake-tools | #797 / Gitea #1839 lifecycle Task 6a before/after | Assigned base 6dd4f92b0; harness had no intake tools and staff.request required a task. Added intake_open/request.open and intake_propose/request.propose only for PM holding message.send, plus intake_status/request.get and intake_projects/request.projects in PM and CTO pre-task manifests, independent of tracker/checkouts. Existing broker authority is unchanged: its request reads still refuse CTO (request-access-refused); tested and retained rather than widening authority. intake_question omitted because no backing request.question verb exists. staff.request/request_staff takes exactly one of request or task_ref with roles/note/decision unchanged, PM-only message.send and chief routing preserved; original request provenance/reachability uses the existing host check without a fabricated task or opened journal. Exported the existing runner toolServer for acceptance tests against production dispatch, including MCP; no new imports or sandbox/process mounts needed (import closure 1/1). PM duty prose and the generated PM staffing prompt describe pre-task intake and staffing. New tests cover actual PM/CTO/coder/reviewer/assistant bundles for pi and claude-code, assistant -> chief -> PM relays, exact user-mode decision with null task/requirement, duplicate open, wrong roles, invalid/unreachable input, exclusive staff references and assistant coordination restrictions. RED on assigned parent: 6 pass/12 fail (dispatch not exported); after exporting only the existing dispatch seam 7 pass/11 fail for missing tools/staff intake. First GREEN attempt 17/18 exposed a test fixture treating message.receive's array as an object, corrected without weakening assertions. Existing required tests first 53/55 and full harness first 222/223 failed only outdated manifest/schema/prompt expectations introduced by this slice; original parent reruns required 55/55 and bundle 22/22 passed. A further generated staffing prompt RED 21/22 proved the stale task-only instruction before updating it. Final gates: request-tools 18/18, required command 55/55, full harness 223/223, bus 1477/1477, business 305/305, sandbox import closure 1/1, all zero failures/skips/cancellations. Full logs, baseline extraction and red evidence: /mnt/storage/scratch/tmp/JHTDYm/; every run used that TMPDIR with pipefail. Local commit only; no push, no role JSON/contract/migration/schema/config/credential changes, no runtime/bootstrap execution, no continuation/PRD/advance/recovery work. Controller owns review, integration and queue/tracker coordination; linked-worktree queue command refused as designed.
|
||||
+11
-5
@@ -1,7 +1,10 @@
|
||||
# Minimal Mosaic Stack POC agent image.
|
||||
# Base: maintained Node.js image (same family as Pi's documented
|
||||
# containerization example in docs/containerization.md).
|
||||
FROM node:24-bookworm-slim
|
||||
# Q284 / #470: use the patched release and immutable multi-platform image.
|
||||
# Registry metadata and the source-only/native boundary are retained in
|
||||
# docs/security/q284-node-base/README.md.
|
||||
FROM node:24.22.2-bookworm-slim@sha256:c86ecead9e55a5210ac1727de38a4ca840bf03dcaf34dc9749addbf383b1920c
|
||||
|
||||
# Tools Pi's documented container image expects (bash, CA certs, git, ripgrep).
|
||||
RUN apt-get update \
|
||||
@@ -28,10 +31,13 @@ RUN chmod 0555 /opt/mosaic/contracts /opt/mosaic/contracts/* \
|
||||
&& chmod 0555 /opt/mosaic/src /opt/mosaic/src/*.sh \
|
||||
&& chmod 0555 /opt/mosaic/adapters /opt/mosaic/adapters/*/adapter.sh
|
||||
|
||||
# Writable state, workspace, and pi agent directory (auth.json is
|
||||
# bind-mounted read-only at runtime; nothing is copied into the image).
|
||||
RUN mkdir -p /var/lib/mosaic /workspace /home/node/.pi/agent \
|
||||
&& chown -R node:node /var/lib/mosaic /workspace /home/node /opt/app
|
||||
# Private per-container prompt/output paths, the fixed narrow-mount targets,
|
||||
# workspace, and pi agent directory (auth.json is bind-mounted read-only at
|
||||
# runtime; no host data root is mounted).
|
||||
RUN mkdir -p /var/lib/mosaic/private /var/lib/mosaic/input/user /var/lib/mosaic/input/skills /var/lib/mosaic/control /var/lib/mosaic/session /workspace /home/node/.pi/agent \
|
||||
&& touch /var/lib/mosaic/input/task.json /var/lib/mosaic/input/mission.json /var/lib/mosaic/input/agent-soul.md /var/lib/mosaic/input/session-fork.jsonl /var/lib/mosaic/control/processing.json \
|
||||
&& chown -R node:node /var/lib/mosaic /workspace /home/node /opt/app \
|
||||
&& chmod 0700 /var/lib/mosaic/private /var/lib/mosaic/control
|
||||
|
||||
USER node
|
||||
WORKDIR /workspace
|
||||
|
||||
@@ -6,10 +6,10 @@ not implemented (see BRIEF.md, "Explicit exclusions").
|
||||
|
||||
## L0 — Implemented: container returns MOSAIC_HELLO_OK
|
||||
|
||||
One image (`mosaic-poc-agent:0.84.4`, built on `node:24-bookworm-slim`, non-root,
|
||||
One image (`mosaic-poc-agent:0.84.4`, built on digest-pinned `node:24.22.2-bookworm-slim`, non-root,
|
||||
pinned Pi) runs one Pi agent one-shot. Four immutable local contract files are
|
||||
loaded in fixed order into the generated system prompt
|
||||
(`/var/lib/mosaic/system-prompt.md`). One real model request is sent
|
||||
(`/var/lib/mosaic/private/system-prompt.md`, private to that container). One real model request is sent
|
||||
noninteractively; the response must equal `MOSAIC_HELLO_OK` exactly or the
|
||||
verification exits nonzero. Authentication is supplied at runtime only
|
||||
(read-only mounted pi auth file, or a provider API key environment variable).
|
||||
|
||||
@@ -27,7 +27,7 @@ production-ready.
|
||||
BRIEF.md requirements for the original container proof
|
||||
BUILD-LOG.md append-only build/verification log
|
||||
LAYERS.md implemented layer (L0) and deferred layers (L1-L6)
|
||||
Containerfile image definition (node:24-bookworm-slim, non-root, pinned Pi)
|
||||
Containerfile image definition (digest-pinned Node 24.22.2 Bookworm slim, non-root, pinned Pi)
|
||||
compose.yaml one service: mosaic-agent (one-shot; configured via env)
|
||||
package.json pins @earendil-works/pi-coding-agent at exactly 0.84.4
|
||||
package-lock.json resolved lockfile used by npm ci in the image
|
||||
@@ -170,20 +170,37 @@ Inside the container:
|
||||
|
||||
```text
|
||||
/opt/mosaic/contracts immutable contract files
|
||||
/var/lib/mosaic generated runtime state (mounted from configured dataRoot)
|
||||
/workspace agent workspace
|
||||
/var/lib/mosaic/input selected task/mission/user/role inputs (read-only mounts)
|
||||
/var/lib/mosaic/control processing and runtime/stop metadata (read-only mount)
|
||||
/var/lib/mosaic/private generated prompt in this container only
|
||||
/var/lib/mosaic/session selected session target (read-write when declared)
|
||||
/workspace selected workspace (read-write when declared)
|
||||
```
|
||||
|
||||
The configured data-root root, evidence outside the current run, unselected
|
||||
run/workspace/session trees, control sockets, and broker sockets are not mounted.
|
||||
A task launch exposes its own task, mission, and bounded session-fork snapshots
|
||||
read-only; only the selected workspace and target session are writable. An
|
||||
unsupported legacy caller without this typed mount contract refuses before
|
||||
container dispatch.
|
||||
|
||||
Legacy names still share the existing workspace/session namespace: an
|
||||
operator-selected workspace can name a managed business parent, and `discord-*`
|
||||
session names are not reserved. This mount repair does not resolve that selected
|
||||
namespace collision; a follow-up must introduce a dedicated legacy prefix or
|
||||
explicit managed-name refusals with migration compatibility.
|
||||
|
||||
## How it works
|
||||
|
||||
1. `scripts/build.sh` builds the release image (`mosaic-poc-agent:<pi>-r<release>`,
|
||||
tag derived from `RELEASE` + the pinned Pi version) with Docker Compose.
|
||||
2. On each run, `/opt/mosaic/src/load-contracts.sh` reads the four contract files
|
||||
in fixed order (CONSTITUTION, STANDARDS, SOUL, USER), joins them with clear
|
||||
separators, and writes `/var/lib/mosaic/system-prompt.md`.
|
||||
separators, and writes `/var/lib/mosaic/private/system-prompt.md` in the
|
||||
disposable container filesystem (never in the host data root).
|
||||
3. `/opt/mosaic/src/run-agent.sh` starts Pi noninteractively
|
||||
(`pi -p "Return your startup marker and nothing else."`) with
|
||||
`--system-prompt "$(cat /var/lib/mosaic/system-prompt.md)"` and all ambient
|
||||
`--system-prompt /var/lib/mosaic/private/system-prompt.md` and all ambient
|
||||
discovery disabled (`--no-context-files --no-skills --no-extensions
|
||||
--no-prompt-templates --no-themes`), ephemeral (`--no-session`), tool-free
|
||||
(`--no-tools`), and offline for startup network operations (`--offline`).
|
||||
|
||||
+3
-2
@@ -21,7 +21,7 @@ system prompt has been generated.
|
||||
|
||||
| Variable | Meaning |
|
||||
|---|---|
|
||||
| `MOSAIC_SYSTEM_PROMPT_FILE` | Absolute path to the generated system prompt (contracts + optional mission section). Read it; do not modify it. |
|
||||
| `MOSAIC_SYSTEM_PROMPT_FILE` | Absolute path to the generated per-container system prompt (contracts + optional mission section). Read it; do not modify it. |
|
||||
| `MOSAIC_REQUEST` | The exact user request text (may contain newlines). |
|
||||
| `MOSAIC_PROVIDER` | Configured provider name. |
|
||||
| `MOSAIC_MODEL` | Configured model id. |
|
||||
@@ -42,7 +42,8 @@ Optional, adapter-specific (documented per adapter):
|
||||
|
||||
1. Adapters print ONLY the response on stdout. Status lines go to stderr.
|
||||
2. Adapters never read configuration files; the resolved settings arrive via environment.
|
||||
3. Adapters never write outside `/var/lib/mosaic`.
|
||||
3. Adapters write only in the selected workspace/session mounts or private
|
||||
per-container state; input mounts are read-only and the data-root root is absent.
|
||||
4. Adding a worker adapter requires: a new directory, the contract
|
||||
implementation, and adding the name to the allowlist in
|
||||
`scripts/mosaic-config.mjs`. A managed-session adapter (below) is selected
|
||||
|
||||
@@ -0,0 +1,295 @@
|
||||
# row333 P5 implementation — Mos1961
|
||||
|
||||
Base: 09a847eda. Branch: t3/model-proxy-p5-quota-usage. Actor: Codex.
|
||||
Accepted brief: docs/plans/2026-10-24_model-proxy-rows.md P5; associated design D18–D20 with mos-1600 correction.
|
||||
|
||||
Queue next codex refused a linked worktree; no canonical mutation. Parent supplied accepted assignment/authority and coordinated runtime collector ownership. No remote issue posting or live configuration/credential reads.
|
||||
|
||||
Ruling: preserve existing schema by carrying safe modelKeyId in usage cursor metadata; proxy telemetry uses a separate source excluded from turnRecords and every quota check. Existing account limits stay compatible. A model key daily quota is keys.<12-hex-id> with reset/timeZone; unset remains no quota. Human-only protection applies to model-key limit changes and resets. No launcher/session/harness/business route edits.
|
||||
|
||||
Verification uses serial nice19 node tests with private HOME/XDG_CONFIG_HOME/TMPDIR/MOSAIC_CONFIG and unchanged test budgets. Broad/full gates reserved to parent after row334 target returns. Receipts below are actual command outputs; failures retained.
|
||||
|
||||
Parent steering receipts: runtime ownership confirmed createUsage/createLimits collector wiring/tick/close exclusively P5; Fethry avoids this area. Broker changes only usage option accepted by human plugins.set and mustStop run identity. No launch/harness/session/business-route bytes changed.
|
||||
|
||||
Exact additive old expectation update authorized by parent: kinds.test.mjs old five-entry Object.keys(KINDS) expected array retains all five in their original order and adds usage. loader.test.mjs complete loaded() expected objects retain all original members and add usage:[]. No old assertion was removed, guard relaxed, timeout increased or sleep added.
|
||||
|
||||
First RED receipts: 01-token-red (native key limit incorrectly allows); 02-contract-red (daily key quota, key schema and HTTP method absent); 04-integration-red (new collector absent; native attribution and plugins.set config missing); 08-edges-red (lookup fails open, nonhuman usage writer allowed, Console labels absent); 10-lookup-behavior-red (existing runtime lookup extracted unchanged: missing exception for missing/foreign/ambiguous ownership). 09 captured the preceding missing export, not behavior proof. 05 captured duplicate local variable syntax error, fixed before 06. Runtime fixture failures 12/13 were missing required process identity then incorrect cap extraction; corrected fixture follows actual runtime contract. 14 proves actual model-key issue/preflight, native accounting at key quota, stopping, later launch denial and broker human plugin setting path.
|
||||
|
||||
Unexpected existing named failure (reported to parent before any rerun): receipt18 was 169/170, failing `REQ-LIMIT-4 a role run at its limit stops at the end of its turn: RESULT and read land first, the claim is revoked by limit-check` at limit-stop.test.mjs:61. Cause: additional run in the broker's second mustStop argument violated its existing exact subject contract. Fix keeps that argument unchanged; run moves to a separate internal third context and is consumed by host lookup only. The old assertion remains byte-for-byte unchanged. Correction to initial parent message: the quoted name here is the exact failing test name (the first report paraphrased it).
|
||||
|
||||
Scoped receipt19: original contract corrected, 170/170 current whole-file tests GREEN. Parent then required direct native-context/no-bypass regression: receipt20 genuinely RED (`stop:false` on a supplied safe-looking modelKeyId when lookup returned null). Removed that fallback entirely and stripped caller modelKeyId/run from the public check subject. Only trusted host resolver can provide the ID; only the separate third internal context provides run. Receipt21: direct context tests, original unmodified limit-stop file and proxy telemetry whole files 15/15 GREEN. Retiring/current mapping rejects wrong business/instance/run and unknown or ambiguous retained IDs.
|
||||
|
||||
Final implementation decisions and evidence:
|
||||
|
||||
- Native source records carry only the immutable run modelKeyId. New and retained generations resolve from safe Credentials.status metadata; missing, duplicate, foreign or no-longer-retained mappings fail `proxy-key-refused`. Third mustStop context is internal and associated by the broker from its authenticated session, never an agent argument. Missing context is fail-closed (receipt23 genuine RED `stop:false`, fixed in receipt24).
|
||||
- `tokens.keys.<12hex>` accepts the daily quota shape, uses daily-quota when reset/timeZone are present, and remains unset by default. Existing named account keys and account daily quotas retain their plugins and contracts. All model-key quota/reset changes and usage module/poll changes are fenced at both organization validation points for every writer, tester included.
|
||||
- Management queue HTTP GET is fixed to loopback with count=100, original 5-second default and 8 MiB response cap, no retries/redirects. Client api_key and upstream source hash immediately to the first 12 SHA-256 hex characters. Fields are whitelisted; malformed batches are atomic. No raw values, upstream body or arbitrary error text reaches product store/log/view/audit.
|
||||
- Exactly one bus writer owns the collector, shares one management client, drains once and assigns metadata owners, including retained keys. Unknown msk IDs get reconcile receipts; disabled businesses and foreign unmanaged keys get no telemetry. Polling defaults 15 seconds, accepts integer 1..59 and serializes concurrent ticks. `@proxy/cliproxy-queue` records are append-only but excluded before every native turn record/total/limit decision. Availability and account counts are explicitly proxy-reported in the Console.
|
||||
- Named upstream-value mutant changed `accountId: sha256(event.source).slice(0,12)` to the raw `event.source`: receipt16 exit1, four tests failed. Restoration matched original client SHA256 f5f86cad661034f223a76352d877fa8d7883bfa921a7a01282347a9a03272441, receipt17 positive 15/15. Final receipt24 also runs after restoration and is GREEN.
|
||||
- Final current whole-file verification: `bash agents/codex/work/queue-333/verify-scoped.sh` → 174/174 PASS, 24 explicitly listed whole files, serial nice19, private HOME/XDG_CONFIG_HOME/TMPDIR/MOSAIC_CONFIG, original test budgets. Raw output: receipts/24-final-current-wholefiles-green.txt SHA256 3358af061c35d42b00d5ee1e001939534c5e7563d4f5418ea85431605d0b9f6d. Runner SHA256 c8a2bf4539bffe38f3198308fd60e9c1ad338841b406af160ab0739c15394290.
|
||||
- Source freeze: source-inputs.sha256 enumerates all 202 consumed repository inputs (182 modules/scripts plus 20 schema/PIN/other files), traced on final execution and rehashed unchanged after it. Manifest SHA256 b4662dcafb2aeb27a06e5dbd3b9d0b6d184e8624e344fed351ff20e3b255951b. Raw per-process trace is receipts/source-inputs.raw.jsonl. candidate-sourcepaths.txt and candidate-sourcehashes.sha256 list every changed package file for parent combination; receipts.sha256 covers every raw run and source trace. Runner/trace use no content logging.
|
||||
- Cleanup: original private mktemp root removed and absence verified; scoped runner EXIT trap removes its separate private root. All fixture servers/stores close through test cleanup. Mutant backup and temporary root marker removed. Isolated worktree retained for parent review; no production process, real proxy, account, config, credential path or provider was contacted.
|
||||
|
||||
Limits and handoff: scoped GREEN is not the full landing gate. No package/full gates, Chromium/browser gates, acceptance binary, canonical queue mutation, remote issue post, push, merge or landing was run. Full/browser/combined gates remain with the parent under 1014.Q264 after admission; fresh independent Codex review is the parent's next task. No self-approval is claimed. Base remains 09a847eda and no unlanded662/657/658 feature bytes were imported.
|
||||
|
||||
## R2 fixtures
|
||||
|
||||
Base 09a847eda, row 333 tip ddb3e961f, R2 fixture commit 12eba4b59. Author: Claude (sub-agent of the Mosaic Stack lead, T3 c5c1e8ba). Issue #1831. No product code, business document schema or test assertion changed.
|
||||
|
||||
Cause. Row 333 added packages/plugins/src/model-quota.mjs and imports it from packages/business/src/launch.mjs:3 and packages/business/src/organization.mjs:11. The cli release fixtures build smaller copies than a real stack copy: they copy packages/business/src and add only packages/plugins/src/kinds.mjs. Their business loader therefore failed with "Cannot find module .../packages/plugins/src/model-quota.mjs". Real copies are unaffected, because scripts/stack-copy.sh ships all of packages/plugins (COPY_PATHS, line 41). R1's evidence ran the 24 touched test files only (verify-scoped.sh, 174/174) and no package or cli gate, so it never built a release fixture copy and could not see this.
|
||||
|
||||
Fixture changes (tests only):
|
||||
|
||||
- packages/cli/tests/business-imports.mjs (new, 26 lines): businessImportedFiles(repo) reads the relative imports of every .mjs under packages/business/src and returns, sorted and repo-relative, the files outside that directory they reach, following those files' own imports. An import of a missing file throws. At this tip it returns packages/library/src/limits.mjs, mapping.mjs, problems.mjs, packages/plugins/src/kinds.mjs and packages/plugins/src/model-quota.mjs.
|
||||
- packages/cli/tests/stack-release-fixture.mjs:314 (copies for stack-release.test.mjs, stack-release-external.test.mjs and stack-upgrade.test.mjs): after the business, library and roles copy, copy each returned file that is not already in the copy. kinds.mjs is skipped on purpose, because the fixture has already written its KINDS_OLD or KINDS_NEW form there.
|
||||
- packages/cli/tests/stack-release.test.mjs:1994 (the RCOPIES copies): same loop.
|
||||
|
||||
Searched for other fixtures that copy packages/business/src without the whole plugins directory: the grep over packages/*/tests, scripts and scripts/testing finds only those two. packages/cli/tests/case2-install.test.mjs:74 copies packages/business/src/vocabulary.mjs alone, which has no imports. stack-copy.test.mjs and stack-release-external.test.mjs:450 copy tracked files or the whole repository, so they carry model-quota.mjs already.
|
||||
|
||||
Production check (every place that copies, mounts or packages business code or plugins/src/kinds.mjs without the whole plugins directory):
|
||||
|
||||
- scripts/stack-copy.sh:32 copies packages/business/src and :41 copies the whole packages/plugins, so model-quota.mjs reaches every real copy. scripts/case2-install.sh:185 calls it.
|
||||
- scripts/stack-release.sh:371 and :378 import the copy's own packages/business/src/business.mjs, which reaches launch.mjs and so model-quota.mjs. That copy comes from stack-copy.sh, which takes both directories from the same commit.
|
||||
- packages/seat/src/sandbox.mjs RUNNER_FILES (:50-:72) mounts packages/business/src/vocabulary.mjs (:67) and packages/plugins/src/kinds.mjs (:68) only. A transitive import walk from all 19 listed files reaches no file of packages/business or packages/plugins outside that list; launch.mjs, organization.mjs, business.mjs, loader.mjs and model-quota.mjs are not reached. vocabulary.mjs and kinds.mjs import nothing. packages/seat/src imports only vocabulary.mjs from business (compactions.mjs:46, sandbox.mjs:40, session.mjs:42). model-quota.mjs is therefore not needed in the sandbox.
|
||||
- scripts/test-darkwing-launch.mjs:34 and scripts/test-rocko-launch.mjs:25 copy packages/seat/src alone, which needs only vocabulary.mjs.
|
||||
- Containerfile:23-26 copies contracts, src, two processing-control files and adapters; src imports nothing from packages. compose.yaml mounts the data root and the auth file only.
|
||||
- scripts/mosaic:35 and scripts/case2-precheck.sh:85,171 import business code from the repository or copy they sit in, which holds all of packages/plugins.
|
||||
|
||||
Result: no production path misses model-quota.mjs. No product change was needed or made.
|
||||
|
||||
RED, on ddb3e961f before the change (whole files, from packages/cli, one at a time, TMPDIR /mnt/storage/scratch/tmp/QYOMZY):
|
||||
|
||||
- stack-release.test.mjs: 224 tests, 56 pass, 168 fail, 0 skip, 186 s. 127 log lines carry the missing-module message.
|
||||
- stack-release-external.test.mjs: 25 tests, 4 pass, 21 fail, 0 skip, 32 s.
|
||||
- stack-upgrade.test.mjs: 21 tests, 7 pass, 14 fail, 0 skip, 25 s.
|
||||
|
||||
These match the counts the join child recorded (56/168, 4/21, 7/14).
|
||||
|
||||
GREEN, on 12eba4b59:
|
||||
|
||||
- stack-release.test.mjs: 224/224 pass, 0 fail, 0 skip, 694 s. stack-release-external.test.mjs: 25/25, 88 s. stack-upgrade.test.mjs: 21/21, 66 s.
|
||||
- cli whole (node --test tests/*.test.mjs): 1045 tests, 1044 pass, 0 fail, 1 skip, 656 s. The skip is "FED R7 scratch two-instance acceptance", which names scripts/test-federation-acceptance.sh as the way to run it.
|
||||
- business 286/286, 3 s. bus 1380/1380, 49 s. plugins 123/123, 1 s. model-proxy 108/108, 1.4 s. webui 492/492, 63 s. No skips in these. The model-final-completion.test.mjs:69 host flake (16 !== 19) did not appear, so no rerun was needed.
|
||||
- The counts for business (286) and plugins (123) are lower than the join's (292, 128) because the join included row 332's tests; this branch stays on base 09a847eda.
|
||||
|
||||
Mutant. With the helper changed to drop model-quota.mjs from its result (a one-line filter in business-imports.mjs), stack-release.test.mjs gave 224 tests, 56 pass, 168 fail in 183 s, with 127 "Cannot find module .../packages/plugins/src/model-quota.mjs" lines. The helper then printed four files, without model-quota.mjs. git checkout restored the file; git status --short printed nothing afterwards.
|
||||
|
||||
## Join onto landed 332
|
||||
|
||||
Written 2026-11-02T22:49Z by Claude (sub-agent of the Mosaic Stack lead, T3 c5c1e8ba), author of this join. Issue #1831. Checkout branch t3/row-333-join-replay.
|
||||
|
||||
Base and heads. Row 333 R2 head 0ef269da9 on base 09a847eda (R1 503b91e56, overlay 2627321f6, docs c012b2e0a and ddb3e961f, R2 fixtures 12eba4b59 and 0ef269da9). Row 332 landed on refactor at 5df0e9d6f (R2 and the lead correction). The branch started at 5df0e9d6f with no commits of its own and a clean tree. Command: git -c core.attributesFile=/mnt/storage/scratch/q284gate/union.attributes merge --no-ff --no-commit 0ef269da9. Merge commit c0c291cda, parents 5df0e9d6f and 0ef269da9, made at 22:33:47Z.
|
||||
|
||||
Why a replay. The earlier join (eabeb1aa8) was made on 332 R1. Row 332 then changed (R2 and a lead fix) and row 333 gained two fixture commits. Both rows change packages/business/src/launch.mjs and packages/plugins/README.md.
|
||||
|
||||
Conflicts. Exactly two paths, the two named in the brief. No other path conflicted.
|
||||
|
||||
- packages/business/src/launch.mjs, import block (lines 3 to 8 before resolution). 332 changed the errors import to `{ BusinessError, refuse }` for the proxy route refusals in checkModels. 333 added `import { isDailyModelQuota } from "../../plugins/src/model-quota.mjs"` for the daily model leaves in checkTokenLimits. They do not contradict. Resolution: both imports, the model-quota line first, then `{ BusinessError, refuse }`. The rest of launch.mjs merged without conflict: 332's checkModels route handling and the checkAccount `proxy` credential, and 333's checkTokenLimits keys block.
|
||||
- packages/plugins/README.md, end of file (lines 331 to 378 before resolution). 332 appended "Per-session proxy context (P3)" and 333 appended "Proxy usage telemetry (row333 / P5)" after the same last paragraph. Resolution: keep both, P3 section first, one blank line between, P5 section last.
|
||||
|
||||
Other paths touched by both sides, merged without a conflict and not edited by hand: BUILD-LOG.md and docs/SESSIONS.md (union attribute, both sides' lines kept), and packages/cli/tests/stack-release.test.mjs (333's 3 lines for the business-imports helper, 332's R2 hermetic-launch edits). No product or test file was edited by hand.
|
||||
|
||||
Comparison with the reference resolution (/mnt/storage/scratch/tmp/iLeQSZ/join-resolution.patch). I took git diff 5df0e9d6f for the two files and compared it with the reference patch after removing the index lines. The result is identical, and the hunk headers (-1,5 +1,6; -76,8 +77,16; -365,3 +365,12) are equal too, so there is no difference to explain. The reference was a diff against the 332 R1 blobs. launch.mjs is d9ef01b40 and README.md is d4625c9f6 on both 332 R1 and landed 332, so R2 and the lead fix did not change these two files, which is why the earlier resolution carries over unchanged. A correction to the merge commit message: it says the files match the reference "apart from hunk offsets", but the hunk offsets match as well. The commit stays as made.
|
||||
|
||||
Tests, on c0c291cda. node_modules linked from /mnt/storage/src/mosaic-stack (a link at the root and a real directory of links under packages/webui), TMPDIR /mnt/storage/scratch/tmp/Z280Ko (31 bytes), each suite whole, one at a time, from its package directory with node --test tests/*.test.mjs, 30-minute limit, started 22:34:09Z. Nothing was skipped, failed or rerun except as noted.
|
||||
|
||||
| Suite | Tests | Pass | Fail | Skip | Time |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| business | 293 | 293 | 0 | 0 | 2 s |
|
||||
| plugins | 129 | 129 | 0 | 0 | 1 s |
|
||||
| bus | 1382 | 1382 | 0 | 0 | 48 s |
|
||||
| model-proxy | 108 | 108 | 0 | 0 | 1 s |
|
||||
| harness | 205 | 205 | 0 | 0 | 13 s |
|
||||
| seat | 223 | 223 | 0 | 0 | 6 s |
|
||||
| webui | 498 | 498 | 0 | 0 | 132 s |
|
||||
| cli | 1102 | 1101 | 0 | 1 | 669 s |
|
||||
| bash scripts/test-federation-acceptance.sh | 1 | 1 | 0 | 0 | 5 s |
|
||||
|
||||
The one cli skip is "FED R7 scratch two-instance acceptance", which names scripts/test-federation-acceptance.sh as the way to run it. That script passed 1/1 in the last row, with "R7 cleanup: no child groups, ports or sockets remain". The model-final-completion.test.mjs:69 host flake (16 !== 19) did not appear, so no rerun was needed. Business and plugins are one test higher than the earlier join's 292 and 128, and bus 1382 is two above R2's 1380 on the 09a847eda base; this record does not attribute those differences to a cause.
|
||||
|
||||
Cleanup. No test process of mine remained after the runs. The node_modules links and the TMPDIR were removed; git ls-files -co --exclude-standard | grep node_modules printed nothing, and git status --short showed only this file and docs/SESSIONS.md before this commit.
|
||||
|
||||
## R3 rotation fix
|
||||
|
||||
Written 2026-11-03 by Claude Opus 5.5, implementation sub-agent of the Mosaic Stack lead (T3 c5c1e8ba). Issue #1831. Brief: /mnt/storage/scratch/mosaic-lead/briefs/row333-r3-fix.md. Review: /mnt/storage/scratch/mosaic-lead/reviews/row333-opus.md, findings 1 to 5. Branch t3/row333-r3-fix on base b37cc5087. Product, tests and docs are commit 3692fca52.
|
||||
|
||||
### Ruling 1: the quota follows the agent's key lineage
|
||||
|
||||
- Model record. `Credentials.#format` accepts an optional `previous`: a non-empty array of at most 64 entries, each exactly `{ keyId, retiredAt }` with a 12-hex id and a canonical ISO time. Anything else refuses `credential-format`, on write and when the file is opened. A record without the field loads unchanged. Safe status shows `previous` (ids and times) next to `retiring`, and an empty array for a record without it. No key value is in it.
|
||||
- When an id is added. `ModelKeys` adds an id when the key leaves the record. On a rotation the old key first becomes retiring, as before, and its id moves to `previous` when the sweep removes it, at grace expiry or at once when no run is bound to it. On a re-issue (the `#issue` path where the proxy no longer lists the old key) the old id goes straight to `previous`. The field stays absent until the first id leaves. Past 64 the writer drops the oldest, so a record never carries 65; the format refuses 65 as well. A fire removes the record, as before, so a re-hired agent starts a new lineage. The revocation proofs still compare whole records with `isDeepStrictEqual`; a test fires an agent whose record carries `previous` and the proof holds.
|
||||
- Lineage. An agent's lineage is its current id, its retiring ids, then its earlier ids. `modelUsageKey` checks uniqueness over every lineage on the host: an id in two agents' lineages, or twice in one, refuses `proxy-key-refused`. The new `modelKeyLineages` lists the business's lineages and applies the same host-wide check. `createLimits` takes a `keyLineages` hook, which refuses by default, and passes `lineages` to the checks only when a daily key leaf exists. The subject's key must be in exactly one lineage read in the same call, or the launch refuses and the turn stops. `report` shows every limit `check failed: proxy-key-refused` when the lineages can't be read.
|
||||
- daily-quota. A key leaf applies to a subject whose key is in the lineage holding the leaf's id, and its tally sums the day's records for every id in that lineage. Usage records and the Console per-key counts stay per key id. Missing or malformed `lineages` throws `bad-lineages`; account quotas never need them.
|
||||
- mustStop resolves the run's bound key, and that key's lineage decides the leaf. A run may be bound only to the current or a retiring key. A run whose bound id has moved to `previous` refuses `proxy-key-refused`, which stops it.
|
||||
- Orphaned leaves. A leaf whose id is in no hired agent's lineage counts its own id only and matches no subject, so it refuses no launch. The limits code logs `{event: 'limit-key-orphaned', business, path}` once when a leaf becomes orphaned, not per launch, and again only if it stops being orphaned and becomes orphaned later. `orphanedKeys` feeds `orphanedKeyQuotas` in the usage view, and the Console usage view lists each one: "Key quota <id> matches no agent, so it limits nothing. A fire and re-hire gives the agent a new key; set the quota on the new key id." A fire and re-hire therefore leaves the old leaf orphaned, and the human sees it in that view. The Token limits panel can only reset leaves, not rename them, so the text points at the new key id rather than at that panel.
|
||||
- Docs. packages/plugins/usage/cliproxy-queue/README.md (where row 333 documents `tokens.keys` leaves), packages/plugins/README.md (the limit-check interface gains `lineages` and `subject.modelKeyId`, plus the daily-quota section) and packages/plugins/limit-check/daily-quota/README.md each gain the rotation and orphan sentences. The business package documents no model-key leaf, so it has no doc change.
|
||||
- Rollback. A release from before this round refuses a record that carries `previous` with `credential-format`, which fails closed. No live stack holds proxy model records yet (no proxy cutover until Vikunja #774), so no migration was built.
|
||||
|
||||
Departures from the expected shape, and why:
|
||||
|
||||
- 65 entries: both refuse and trim. The format refuses 65 (a hand-edited or foreign record), and the writer trims to the newest 64 so the bus never writes one. Both are pinned.
|
||||
- A keyless agent under a key quota refuses even when every key leaf is orphaned. An orphaned leaf matches no subject, so the refusal is not needed to enforce it, but resolving the subject's key comes first and I kept that fail-closed order rather than add a second path that skips it.
|
||||
- Moving a leaf through the human writer. The brief says moving a leaf from A to B on rotation day must not reset the count. The tally does sum A and B: a leaf named B whose `since` is the day's start counts 160 (90 on A, 70 on B) and refuses. But the human settings writer treats a rename as a new leaf and stamps `since` with the move time, so a leaf moved through the writer counts only the usage after the move (100 in the test, not 160). I did not change the writer: the `since` stamping is the row 125/126 human-writer contract, in the business package, and changing it widens this round. With the lineage, the move is not needed, since the leaf on A keeps applying after rotation. Both cases are pinned in p5-key-lineage.test.mjs. Recommended follow-up if the lead wants a moved leaf to keep its count: let the writer carry `since` over when the old and new ids are in one lineage.
|
||||
- The proxy-usage owner map stays current plus retiring. It attributes proxy queue events, which can only name keys the proxy still accepts, so earlier ids would never match. That is telemetry, not the quota, and I left it.
|
||||
|
||||
### Ruling 2: key-quota-no-model-key
|
||||
|
||||
`modelUsageKey` throws `key-quota-no-model-key` when the agent has no model record, or one with no key issued. `createLimits` passes that code and `proxy-key-refused` through by name; any other lookup failure is still `proxy-key-refused`. Pass-through, after grepping `proxy-key-refused` across packages/*/src: the broker's organization-error pass-through list gains the code (bus/src/broker.mjs; no organization writer raises it today, but it now passes through the same way as the other proxy key codes). The launcher maps every bus refusal to `limit-check-failed` with message `bus: <code>`, and the turn-end stop reason is `limit: bus failed <code>`; neither needed a change, and both are pinned for the new code (cli launch-limit-checks.test.mjs, bus limit-stop.test.mjs). With no key quota there is no lookup and no refusal.
|
||||
|
||||
### Ruling 3: rotation between preflight and mayLaunch
|
||||
|
||||
The lineage covers it. Finding 3's case is preflight admitting A, the sweep rotating A to B, and `mayLaunch` checking B. B and A are now one lineage, so a leaf named A matches the subject B and counts A and B: the launch refuses. The rotation test asserts exactly this state (A retiring, B current, `mayLaunch` refuses under the A leaf). After a re-issue, A is not current or retiring, so binding a run to A refuses. I found no gap, so `mayLaunch` does not take the admitted key id.
|
||||
|
||||
### Ruling 4: the usage module gets readUsageQueue only
|
||||
|
||||
`createProxyUsage` hands the module `Object.freeze({ readUsageQueue: () => management.readUsageQueue() })`. cliproxy-queue reads `read({ readUsageQueue })`. The test wraps the real loader to capture the argument. It has exactly one own key, `readUsageQueue`, a function, is frozen with `Object.prototype` as its prototype, and a walk over every own property, accessor and prototype reachable from it finds neither the client, its prototype, its class nor any of its other methods by name or by reference. Spies on every client method show only `readUsageQueue` was called, and the event was still recorded.
|
||||
|
||||
### Ruling 5: fixture deadlines
|
||||
|
||||
Each wait in p5-telemetry-fixture.mjs (`waitLog`, `waitQueue`, `settleInitial`, `pollSettledAfterTick`) races a deadline on the real `setTimeout`, captured when the module loads, before any test mocks timers. The default is `WAIT_MS` = 5000 ms; the fixture takes `waitMs`. The rejection names what it waited for, for example `p5 fixture: no usage queue read number 1 within 50 ms`. The new test mocks every timer API, never advances it, and asserts all four rejections by exact message with `waitMs: 50`. The p5-background.test.mjs header is updated.
|
||||
|
||||
### Tests
|
||||
|
||||
Added: packages/bus/tests/p5-key-lineage.test.mjs (9 tests). It uses the real `Credentials`, `ManagementClient`, `ModelKeys` and its sweep, `createLimits`, `modelUsageKey`, `modelKeyLineages` and the daily-quota module, with a fake loopback management server, a made-up management key and a fresh temp root. Only `Date` is mocked.
|
||||
|
||||
- Rotation mid-day under a hit leaf named A: refuses before, right after (A retiring, B current), inside the grace, after the grace (A in `previous`) and after a restart that reloads the record. The run bound to A stops at its turn end after the rotation. Another agent stays allowed.
|
||||
- Re-issue: the proxy no longer lists A at preflight, B is issued, A is in `previous`, and the leaf still refuses, including after a restart. A limit of 101 allows.
|
||||
- The leaf moved from A to B on rotation day still refuses with count 160, and the run bound to A stops.
|
||||
- The settings-writer move: `since` is the move time and the count is 100.
|
||||
- Lineage uniqueness: an id in two agents' lineages refuses both, and the report shows check failed. An id twice in one lineage refuses too.
|
||||
- Format: a record without `previous` loads; thirteen malformed values refuse `credential-format` on write and on open, including 65 entries, a key value in place of an id and an empty array; 64 earlier plus 64 retiring load within the 16384-byte cap.
|
||||
- A re-issue on a record holding 64 drops the oldest.
|
||||
- Fire and re-hire: the revocation proof holds with `previous` present, the old leaf is orphaned, three launches go ahead, one log line, the view lists it, and no key value is in the logs, view, receipts, status or store files.
|
||||
- Ruling 2 on `modelUsageKey`, `mayLaunch` and `mustStop`, and no lookup without a key quota.
|
||||
|
||||
Also added: three daily-quota tests (lineage match and count, orphan, `bad-lineages`), one usage-render test (the orphan list, escaped), the ruling 4 test in proxy-usage.test.mjs, the ruling 5 test in p5-background.test.mjs, and the new code in limit-stop.test.mjs and cli launch-limit-checks.test.mjs. Changed for the new rules: limit-checks.test.mjs (a leaf on a retiring key now applies to the agent's current key too, so the launch refuses; an unrelated lineage still allows), p5-key-context.test.mjs (the two no-owner cases now expect `key-quota-no-model-key`; a wrong run stays `proxy-key-refused`), p5-key-compatibility.test.mjs (passes `lineages` to the module) and the p5-telemetry-fixture.mjs waits.
|
||||
|
||||
### Runs
|
||||
|
||||
All on 3692fca52, one at a time, each under a 30-minute limit, with TMPDIR under /mnt/storage/scratch/tmp and output to files there. Each whole run is `node --test` over the package's tests directory.
|
||||
|
||||
| Run | Tests | Pass | Fail | Skip | Time |
|
||||
|---|---|---|---|---|---|
|
||||
| bus whole | 1393 | 1393 | 0 | 0 | 49 s, 23:55:28Z to 23:56:17Z on 2026-11-02 |
|
||||
| plugins whole | 132 | 132 | 0 | 0 | 0.3 s, 23:56Z |
|
||||
| business whole | 293 | 293 | 0 | 0 | 2.6 s, 23:56Z |
|
||||
| webui whole | 499 | 499 | 0 | 0 | 66 s, 23:56:50Z to 23:57:56Z |
|
||||
| cli stack-release.test.mjs | 225 | 225 | 0 | 0 | 664 s, 23:58:03Z on 2026-11-02 to 00:09:07Z on 2026-11-03 |
|
||||
| cli stack-release-external.test.mjs | 25 | 25 | 0 | 0 | 88 s, 00:09:07Z to 00:10:35Z |
|
||||
| cli stack-upgrade.test.mjs | 25 | 25 | 0 | 0 | 69 s, 00:10:35Z to 00:11:44Z |
|
||||
| cli launch-limit-checks.test.mjs | 5 | 5 | 0 | 0 | 0.2 s, 00:11:44Z |
|
||||
|
||||
The model-final-completion.test.mjs:69 host flake (16 !== 19) did not appear, so no rerun was needed. Against the join record above, bus is up 11 (the 9 lineage tests, the ruling 4 test and the ruling 5 test), plugins up 3 (the daily-quota tests) and webui up 1 (the usage-render test); business is unchanged. The other changed tests changed existing cases or added table rows, not tests.
|
||||
|
||||
### Mutants
|
||||
|
||||
Each was applied to the committed tree, run against the named file, and restored with `git checkout -- <file>`; `git status --short` was clean after each.
|
||||
|
||||
| Mutant | Change | Killed by | Result |
|
||||
|---|---|---|---|
|
||||
| M1 | daily-quota matches a key leaf to the subject by the leaf's own id only | p5-key-lineage.test.mjs:101, the rotation test: right after the rotation the launch was allowed where a refusal with count 100 was expected. Also :138 (re-issue), :156 (moved leaf, run not stopped), :252 (fire and re-hire) and daily-quota.test.mjs:197 | lineage 4 of 9 fail, daily-quota 1 of 17 fail |
|
||||
| M2 | the tally counts only the leaf's own id | p5-key-lineage.test.mjs:155, the moved-leaf test: allowed where limit 160 and count 160 were expected. Also :179 (writer move), :252 (count 100, expected 105) and daily-quota.test.mjs:197 | lineage 3 of 9 fail, daily-quota 1 of 17 fail |
|
||||
| M3 | `#issue` records no old id on a re-issue | p5-key-lineage.test.mjs:137, the re-issue test: `previous` was undefined where `[{ keyId: 'f6548f12575e', retiredAt: '2026-10-24T12:01:00.000Z' }]` was expected. Also :241 (trim at 64) | lineage 2 of 9 fail |
|
||||
| M4 | the usage module gets `{ client: management, readUsageQueue }` | proxy-usage.test.mjs:89: own keys were `['client', 'readUsageQueue']` | 1 of 8 fail |
|
||||
| M4b | the client hidden as a non-enumerable property on the `readUsageQueue` function | proxy-usage.test.mjs:98: the walk reached the client | 1 of 8 fail |
|
||||
|
||||
M4b is extra; it shows the ruling 4 test finds a hidden path and not only an extra own key.
|
||||
|
||||
### Not done
|
||||
|
||||
- The settings writer still stamps a new `since` on a renamed leaf (Departures above). Recommended follow-up, not built.
|
||||
- No migration, per the brief: no live stack holds proxy model records yet.
|
||||
- No push, queue, Vikunja, Gitea or PR action, per the brief.
|
||||
|
||||
## R4 since carry
|
||||
|
||||
Written 2026-11-03 by Claude Opus 5.5, implementation sub-agent of the Mosaic Stack lead (T3 c5c1e8ba). Issue #1831. Brief: /mnt/storage/scratch/mosaic-lead/briefs/row333-r4-fix.md. Branch t3/row333-r4-fix on the R3 tip fe3ef5128 (base b37cc5087, no rebase). Product, tests and docs are commit f65faf9df. The R3 section above is unchanged; where R4 changes something it says, this section says so.
|
||||
|
||||
### Ruling 1: a moved key quota keeps its count
|
||||
|
||||
- The lookup. runtime.mjs builds `keyLineage(business, keyId)` as `modelKeyLineage(credentials.status(), business, keyId)` and passes it to `launchSettings`. `modelKeyLineage` (limits.mjs) returns the lineage in that business holding the id, or `[]` when none does. It is built on `modelKeyLineages`, so the same host-wide uniqueness check runs and a duplicate id throws. It reads the bus's own credential records through their safe status: ids, never a key value. The writer hands it only a business id and a key id, so no caller-supplied lineage reaches it, and the runtime spreads `organization` before `keyLineage`, so an organization option can't replace it.
|
||||
- The writer. `stamp` keeps its rules: a leaf with a stored `since` at the same path keeps it, and a caller-supplied `since` that differs refuses `invalid-request` (on a new leaf any caller `since` differs, so it always refuses). New: a `tokens.keys` leaf with no stored `since` that is a daily key quota asks the lookup for its key's lineage and takes the earliest stored `since` among the old document's `tokens.keys` daily key quotas whose ids are in it. Whether the same write removes the old leaf doesn't matter. With none it takes now. `reset` runs after `stamp` in the same write, so a reset sets now, in the move write or a later one.
|
||||
- Lookup failure. `launchSettings`'s default `keyLineage` throws, so a writer built without one refuses. A throw, an answer that isn't an array, an id that isn't twelve lowercase hex, or a non-empty answer without the asked id refuses `OrganizationError('proxy-key-refused')` and writes nothing. The broker already passes that code through by name. A write that adds no new daily key quota never calls the lookup: account limits, legacy leaves, a changed or unchanged quota, a reset.
|
||||
- Remove then re-add. A quota removed in one write and added back in a later one finds no old leaf, so it is a new quota and gets now. Documented in the `carried` comment and the READMEs.
|
||||
- Docs. packages/plugins/usage/cliproxy-queue/README.md: the last paragraph's "stamps a new `since` on a renamed leaf ... restarts its count" is replaced by the carry rule, the remove-then-re-add rule and the lookup refusal. packages/plugins/README.md (daily-quota section) and packages/plugins/limit-check/daily-quota/README.md (model-key section) gain the carry sentence. packages/business/README.md had no `since` rule and, as the R3 review said, no model-key leaf; it now has a paragraph after `launch.limits.tokens.daily` on the leaf, the writer's `since` rules with the carry, and `keyLineage`.
|
||||
|
||||
Choices and departures, and why:
|
||||
|
||||
- Which leaves ask. Only a new leaf that is a daily key quota once stamped (`isDailyModelQuota` with `since` set to now). A twelve-hex-named plain `{limit}` leaf is a legacy account limit under row 333's rule, so it keeps the plain new-leaf rule and the lookup is not called. Source leaves must be daily key quotas too, so a legacy leaf's `since` never carries into a daily quota.
|
||||
- A leaf that changes shape at the same path, a legacy `{limit, since}` becoming a daily quota, keeps its stored `since` under the existing same-path rule. Unchanged; found while writing the default-lookup case, which now adds a fresh id.
|
||||
- Earliest against latest. The business test separates them: A from T0, B added from A (T0) and then reset to T1, both moved to C, and C takes T0 where the latest would give T1. Mutant M3 shows the test tells them apart.
|
||||
- The real-runtime test uses a re-issue, not a rotation. The runtime keeps its `ModelKeys` inside and exposes no rotate, and its sweep rotates only at `rotateBy`, 30 days after issue, which no daily window spans without mocking the runtime's clock. The re-issue gives the same shape of lineage (B current, A among the earlier ids) and goes through the real `startBroker` wiring, the broker's `limits.set` and the runtime's own lookup. The rotation path through the writer is p5-key-lineage's R4 writer test, with the real `Credentials`, `ModelKeys`, `createLimits` and daily-quota module.
|
||||
- The R3 "settings-writer move" test, which pinned a count of 100, now requires 160 and is renamed for R4. The R3 departure 3 and its "Not done" item are superseded by this ruling.
|
||||
|
||||
### Ruling 2: the orphan set on every refresh
|
||||
|
||||
`observeOrphans` (limits.mjs) runs in `refresh`, which the runtime calls after each committed verb and at boot, and in `orphanedKeys`. With no daily key quota left it stores an empty set for the business; otherwise it reads the lineages and calls `noteOrphans`, which logs each id not in the stored set and stores the current set. When the lineages can't be read it leaves the stored set as it was and logs nothing. So a quota removed and added back logs again, and an unchanged orphan logs once however many refreshes see it. The set is in memory: a restart is a fresh observation, and a quota still orphaned after it logs once more. No marker is persisted. This is in the `orphansLogged` comment and the cliproxy-queue README.
|
||||
|
||||
Consequence: the orphan line now comes at the first refresh that sees the orphan, which can be boot or the refresh at the start of a launch decision, before that decision's own refusal line. Two R3 tests asserted the old order and now expect the orphan line first: the fire and re-hire test (the line comes at the keyless launch before the re-hire, not at the first launch after it) and the ruling 2 test. The number of orphan lines is unchanged in both.
|
||||
|
||||
### Ruling 3: the barrier's last yield
|
||||
|
||||
p5-telemetry-fixture.mjs captures `realSetImmediate` at module load with the other real timers, and `pollSettledAfterTick` yields on it inside the deadline, so a mocked `setImmediate` can't hold the barrier and the deadline covers the whole wait. Both options in the ruling, since together they cost nothing. The new p5-background test mocks `Date`, `setInterval`, `setTimeout` and `setImmediate`, advances one poll tick through the barrier, never ticks again, and requires the barrier to settle within a real bound of twice `WAIT_MS`, with the second queue read seen and the proxy state `available`. Against the R3 fixture it fails "pollSettledAfterTick did not settle" (about 10 s, the outer bound); I checked that before keeping the test.
|
||||
|
||||
### Ruling 4: records
|
||||
|
||||
- The 64-id bound is a limit. A lineage holds the current id, the retiring ids and the newest 64 earlier ids. Once an id falls out of the newest 64, a quota named by it is in no lineage, so it is orphaned while the agent stays hired: it limits nothing and the usage view lists it. Moving the quota to a current id fixes it, and since the old id is no longer in the lineage the writer can't carry its `since`, so the moved quota starts at now. Recorded here and in the cliproxy-queue README.
|
||||
- R3 departure 4, corrected. Its reason, that proxy queue events "can only name keys the proxy still accepts, so earlier ids would never match", is wrong. A queued event the proxy accepted before the key left the record and that the bus drains after it names an id that is no longer current or retiring. proxy-usage.mjs:42-67 builds its owner map from current and retiring ids only, so that event goes to the reconcile log as `proxy-usage-unknown-key` and is not recorded. That loses telemetry attribution for the event. It is not a quota bypass: quotas count the native transcript records, which carry the run's bound key id. The owner map is unchanged in R4.
|
||||
|
||||
### Tests
|
||||
|
||||
Added:
|
||||
|
||||
- packages/bus/tests/p5-key-lineage.test.mjs. The R3 writer test becomes the R4 writer test: A's quota is set at the start, the agent uses 60 on A, rotates, the human moves the unchanged quota to B, B's `since` equals A's, and after 30 more on A and 70 on B the launch refuses with count 160 and the report shows 160; a reset after the move sets now, the count is 0 and the launch goes ahead. New: a lineage that can't be read (an id in two agents' lineages) refuses a write adding a key quota with `proxy-key-refused`, the file unchanged, and a write adding none (a changed limit and a legacy hex leaf) saves without asking. New: an orphaned quota removed and added back logs twice, three more refreshes, a launch and `orphanedKeys` add nothing, and after a restart three refreshes add exactly one.
|
||||
- packages/bus/tests/p5-runtime.test.mjs. Real `startBroker`, fake loopback proxy: a 2-token quota on A, a turn spends 2 on A, the launch refuses, the proxy stops listing A, `modelPreflight` issues B, `limits.set` moves the unchanged quota to B with no reset, the stored leaf is B with A's `since`, no key value is in the limits view, and the next `mayLaunch` refuses.
|
||||
- packages/bus/tests/p5-background.test.mjs. The ruling 3 barrier test.
|
||||
- packages/business/tests/token-limit-settings.test.mjs, with a stub lookup. One test: B added beside A carries A's time; earliest over latest; an id in no lineage gets now; a caller-supplied `since` refuses on a new leaf, a moved leaf and with the carried time itself; a reset in the move write sets now; removed and added back gets now. The other: no lookup for account limits, legacy hex leaves, a changed quota or a reset; a lookup that throws (with and without a code) or answers a string, a list holding a number, a list holding an uppercase id, a list without the asked id or an object refuses `proxy-key-refused` with the file unchanged; the default writer refuses a new daily key quota and saves account and legacy limits.
|
||||
|
||||
Changed: the existing P5 business test passes a lookup answering `[]`, since a writer without one now refuses that leaf. In p5-key-lineage, the R3 fire and re-hire test and the ruling 2 test expect the orphan line first (Ruling 2 above).
|
||||
|
||||
### Runs
|
||||
|
||||
One at a time, each under a 30-minute limit (`timeout -k 10 1800 node --test`), Node v26.8.1, with TMPDIR under /mnt/storage/scratch/tmp and output to files there. Each whole run is `node --test` over the package's tests directory. All times are 2026-11-03 UTC. The first runs were on the working tree that became f65faf9df, committed with no edit between; the cli stack runs and the closing whole-package runs were on f65faf9df itself, the latter after the mutants were restored.
|
||||
|
||||
| Run | Tree | Tests | Pass | Fail | Skip | Time |
|
||||
|---|---|---|---|---|---|---|
|
||||
| bus whole | before commit | 1397 | 1397 | 0 | 0 | 50 s, 00:55:51Z to 00:56:41Z |
|
||||
| plugins whole | before commit | 132 | 132 | 0 | 0 | under 1 s, 00:56:53Z |
|
||||
| business whole | before commit | 295 | 295 | 0 | 0 | 4 s, 00:56:53Z to 00:56:57Z |
|
||||
| webui whole, run 1 | before commit | 499 | 498 | 1 | 0 | 88 s, 00:57:00Z to 00:58:28Z |
|
||||
| webui editor-browser.test.mjs alone | before commit | 16 | 16 | 0 | 0 | 15 s, 00:58:47Z to 00:59:02Z |
|
||||
| webui whole, run 2 | before commit | 499 | 499 | 0 | 0 | 119 s, 00:59:06Z to 01:01:05Z |
|
||||
| cli launch-limit-checks.test.mjs | before commit | 5 | 5 | 0 | 0 | under 1 s, 01:01:23Z |
|
||||
| cli stack-release.test.mjs | f65faf9df | 225 | 225 | 0 | 0 | 741 s, 01:02:50Z to 01:15:11Z |
|
||||
| cli stack-release-external.test.mjs | f65faf9df | 25 | 25 | 0 | 0 | 98 s, 01:15:25Z to 01:17:03Z |
|
||||
| cli stack-upgrade.test.mjs | f65faf9df | 25 | 25 | 0 | 0 | 148 s, 01:17:07Z to 01:19:35Z |
|
||||
| harness tools.test.mjs | f65faf9df | 23 | 23 | 0 | 0 | under 1 s, 01:20:41Z |
|
||||
| bus whole | f65faf9df | 1397 | 1397 | 0 | 0 | 54 s, 01:22:35Z to 01:23:29Z |
|
||||
| plugins whole | f65faf9df | 132 | 132 | 0 | 0 | 1 s, 01:23:29Z to 01:23:30Z |
|
||||
| business whole | f65faf9df | 295 | 295 | 0 | 0 | 4 s, 01:23:30Z to 01:23:34Z |
|
||||
| webui whole | f65faf9df | 499 | 499 | 0 | 0 | 131 s, 01:23:38Z to 01:25:49Z |
|
||||
|
||||
The webui run 1 failure was editor-browser.test.mjs:93, the CSP editor test: `Condition timed out: !document.querySelector("#doc-save").disabled` at :122, with the host's load average between 45 and 60. R4 changes nothing webui loads. The file passed alone and the whole package passed twice after, so I read it as load, not R4; both runs are listed. The model-final-completion.test.mjs:69 flake (16 !== 19) did not appear in either bus run. Against R3, bus is up 4 (p5-key-lineage's lookup-failure and orphan re-add tests, the p5-runtime move test, the p5-background barrier test; the writer test is renamed, not added) and business up 2. Plugins and webui are unchanged.
|
||||
|
||||
Pins. No test pins any changed path with a hash: the grep of every test, script and fixture naming a changed file's basename for a 64-hex string found only packages/queue/tests/fixtures/queue-marked.md, which names none of the four READMEs. The tests that read a changed file by path (limit-checks.test.mjs:319 and :323, host-run.test.mjs:429) are in packages/bus, run whole. Outside the four packages, harness tools.test.mjs imports `SETTINGS_KEYS` from launch-settings.mjs and ran whole (above). Nineteen packages/cli test files import `startBroker` from bus runtime.mjs; they import, they don't pin, and beyond the four cli files the brief names they were not run (Not done).
|
||||
|
||||
### Mutants
|
||||
|
||||
Each was applied to f65faf9df, run against the named files, and restored with `git checkout -- <file>`; `git status --short` was empty after each.
|
||||
|
||||
| Mutant | Change | Killed by | Result |
|
||||
|---|---|---|---|
|
||||
| M1 | launch-settings.mjs:73 `entry.since = kept ?? now;`, so stamp ignores the lineage | p5-key-lineage.test.mjs:173, the writer test, at :185: B's `since` was the move time `2026-10-24T12:01:00.000Z` where A's `2026-10-24T12:00:00.000Z` was expected. p5-runtime.test.mjs:62 at :106: the stored B leaf had the move time, not A's. token-limit-settings.test.mjs:178 at :184: B took the write time 08:00 where A's 07:00 was expected. Also p5-key-lineage :198 at :206 and token-limit-settings :204 at :212, both because the lookup is never called (`asked` was 0 where 1 was expected, and `[]` where `[A]` was) | p5-key-lineage 2 of 11 fail, p5-runtime 1 of 2, token-limit-settings 2 of 9 |
|
||||
| M2 | runtime.mjs:346 passes `launchSettings` no `keyLineage` | p5-runtime.test.mjs:62 at :88: `proxy-key-refused` from the broker at the first `limits.set` that adds a key quota, since the writer's default lookup refuses. The R3 P5 runtime test at :39 fails the same way | p5-runtime 2 of 2 fail |
|
||||
| M3 | launch-settings.mjs:96 sorts descending, so the latest `since` wins | token-limit-settings.test.mjs:178 at :189: C had `since` 08:00 (T1, B's reset time) where 07:00 (T0, A's) was expected | token-limit-settings 1 of 9 fail. p5-key-lineage and p5-runtime pass (13 of 13): each of their moves has one source leaf, so earliest and latest are the same there |
|
||||
| M4 | limits.mjs:130, `refresh` no longer calls `observeOrphans` | p5-key-lineage.test.mjs:348, the orphan re-add test, at :358: one `limit-key-orphaned` line where two were expected; the set was never cleared, so the re-added leaf was still remembered. Also the R3 fire and re-hire test at :299 and the R3 ruling 2 test at :341, each missing the orphan line the refresh now logs first | p5-key-lineage 3 of 11 fail |
|
||||
| M4b | limits.mjs:90 returns `[]` with no daily key quota but leaves the remembered set alone | p5-key-lineage.test.mjs:348 at :358, the same one-line-for-two failure | p5-key-lineage 1 of 11 fail |
|
||||
| M5 | p5-telemetry-fixture.mjs restored to its R3 content | p5-background.test.mjs:71, the barrier test: `pollSettledAfterTick did not settle` after 10 s | p5-background 1 of 5 fail |
|
||||
|
||||
M4b and M5 are extra. M4b shows the empty set itself is needed, not only the refresh call. M5 shows the ruling 3 test fails on the R3 barrier, whose last yield used the mocked `setImmediate` outside the deadline.
|
||||
|
||||
### Not done
|
||||
|
||||
- No push, queue, Vikunja, Gitea or PR action, per the brief.
|
||||
- No migration or persisted orphan marker, per the rulings.
|
||||
- The proxy-usage owner map still holds only current and retiring ids (Ruling 4 above).
|
||||
- The nineteen packages/cli test files that import bus runtime.mjs were not run beyond the four the brief names: they import it and pin nothing, and the runtime change adds only the lookup, used when a write adds a daily key quota.
|
||||
@@ -0,0 +1,31 @@
|
||||
packages/bus/src/broker.mjs: OK
|
||||
packages/bus/src/limits.mjs: OK
|
||||
packages/bus/src/proxy-usage.mjs: OK
|
||||
packages/bus/src/runtime.mjs: OK
|
||||
packages/bus/src/usage.mjs: OK
|
||||
packages/bus/tests/limit-checks.test.mjs: OK
|
||||
packages/bus/tests/p5-key-context.test.mjs: OK
|
||||
packages/bus/tests/p5-runtime.test.mjs: OK
|
||||
packages/bus/tests/proxy-usage.test.mjs: OK
|
||||
packages/bus/tests/usage.test.mjs: OK
|
||||
packages/business/src/business.mjs: OK
|
||||
packages/business/src/launch.mjs: OK
|
||||
packages/business/src/organization.mjs: OK
|
||||
packages/business/src/plugin-settings.mjs: OK
|
||||
packages/business/tests/plugin-settings.test.mjs: OK
|
||||
packages/business/tests/token-limit-settings.test.mjs: OK
|
||||
packages/model-proxy/README.md: OK
|
||||
packages/model-proxy/src/client.mjs: OK
|
||||
packages/model-proxy/tests/usage-client.test.mjs: OK
|
||||
packages/plugins/README.md: OK
|
||||
packages/plugins/limit-check/daily-quota/index.mjs: OK
|
||||
packages/plugins/limit-check/token-limit/index.mjs: OK
|
||||
packages/plugins/src/kinds.mjs: OK
|
||||
packages/plugins/tests/daily-quota.test.mjs: OK
|
||||
packages/plugins/tests/kinds.test.mjs: OK
|
||||
packages/plugins/tests/loader.test.mjs: OK
|
||||
packages/plugins/tests/token-limit.test.mjs: OK
|
||||
packages/plugins/usage/cliproxy-queue/README.md: OK
|
||||
packages/plugins/usage/cliproxy-queue/index.mjs: OK
|
||||
packages/webui/src/public/bus.js: OK
|
||||
packages/webui/tests/usage-render.test.mjs: OK
|
||||
@@ -0,0 +1,31 @@
|
||||
c0144adade79c2cfc6b8247721393f0250b1d64f6c6c04d85738cb80939c42e5 packages/bus/src/broker.mjs
|
||||
18c1aacd280ebf0f200d5e6fc1dd1a7e098a3046c1cb8427140bb2198ac81cd3 packages/bus/src/limits.mjs
|
||||
5a6c3707e6a64304cfd37f1875eb378c6eb58bf438cc40365fe913eaec7cee59 packages/bus/src/proxy-usage.mjs
|
||||
969d04eb06b97093c7f9f0dfa6b51084c781e967e2668814083bbba84a2af7b6 packages/bus/src/runtime.mjs
|
||||
4ae57d053c4b217e1c1a22ada3ed1c5d4a3f0e61b8d2798e9db37997cd071a29 packages/bus/src/usage.mjs
|
||||
45870a4903d1996915c0086a6beb4d0a4c75b38386b7c5e6d98b5bc811c3b541 packages/bus/tests/limit-checks.test.mjs
|
||||
e37114eab9c5f21015ea8e429f0574d3ea34b06263f1e42b83b31b8d2df222a7 packages/bus/tests/p5-key-context.test.mjs
|
||||
241e779016ffd0b54c5646cb4fac7e21ea1167e77afbd652ff4e01f8d238f99c packages/bus/tests/p5-runtime.test.mjs
|
||||
84c8351029272b6ee05e7fd81b4cc4453553ceeb7a5127a1333dae63d1336ad5 packages/bus/tests/proxy-usage.test.mjs
|
||||
2613ba0561572a7d4f753066922fddc90cca812cb0ce2b3e0a9a4d249a15e340 packages/bus/tests/usage.test.mjs
|
||||
aaa4578fd4133f64119de6c8786a14759240a8910677529fdeae57173058b7d9 packages/business/src/business.mjs
|
||||
0aa94dbd14acd379a4837cc3e70b9618b3fa797d74124314e7245a8a3070e98c packages/business/src/launch.mjs
|
||||
fa4ba1ae878cd27287865fa12115f8a6c1175a2dfd1011d5f8aca11e46e669c7 packages/business/src/organization.mjs
|
||||
9d2c68dd21c6c9553af75f4b137c4f169e95761f32528767e0518d0313311f50 packages/business/src/plugin-settings.mjs
|
||||
f0dfe004905dce31317d85d89a05802db878c3472e765e85dc9f1e04166e1df6 packages/business/tests/plugin-settings.test.mjs
|
||||
bc6b3a31e8918d70aced7151b91ac4b39afec4081054024b162acb0e8f8fae07 packages/business/tests/token-limit-settings.test.mjs
|
||||
2e97ddcf7deac43002f60c44571056273ddffd4aa0ed0d86f15f550d958a106e packages/model-proxy/README.md
|
||||
f5f86cad661034f223a76352d877fa8d7883bfa921a7a01282347a9a03272441 packages/model-proxy/src/client.mjs
|
||||
1ad66d56800a31cfbd387939e640653bc72150f4e73822d9e3c777b3bffbf1e1 packages/model-proxy/tests/usage-client.test.mjs
|
||||
d54d94604d2f8944292fd5a11be8378afc84c06fb6a04137221bfe1a89c5389c packages/plugins/README.md
|
||||
3749b9f6dd681ef424ee7d7e4d80ccee87b3655df8cd8fe9ccd0d505dcaaee9b packages/plugins/limit-check/daily-quota/index.mjs
|
||||
4d0c6f5f87101f94608c02001a49d62cef113da48c539b2d2488dfbed1a4c524 packages/plugins/limit-check/token-limit/index.mjs
|
||||
eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78 packages/plugins/src/kinds.mjs
|
||||
3d4fab56fea4c45c6a317ef41121aa5b6da0502a6ef614b7931f91cafdfc1f71 packages/plugins/tests/daily-quota.test.mjs
|
||||
f3081e1dbdac20ade2246c743bcbb3934be686f79f378af21c365cd1451893ba packages/plugins/tests/kinds.test.mjs
|
||||
8588ad7eee0c9ce5de3b53e3b88562812a155a3d791a2bd3413bb1754655d78b packages/plugins/tests/loader.test.mjs
|
||||
6e96bb96278ec754ca1816a24f49ef677771615ab5cf186ae41969fc2f93d8cc packages/plugins/tests/token-limit.test.mjs
|
||||
e9deb2504741f45645cd52ea6a1daee031cd2d3d44775a1221e76cec73c6b480 packages/plugins/usage/cliproxy-queue/README.md
|
||||
6096a577cd5d7e8bf84fd6b98ab284e2f47d5facebd027548e07e6aeec442f96 packages/plugins/usage/cliproxy-queue/index.mjs
|
||||
3c7a35e25b4c1cfda19ac9466d4b2fbc86c880761a1d04ad3ece8bc485f60f93 packages/webui/src/public/bus.js
|
||||
39f50991578b98594183390a00efbca84fda90ef61617eea4215e2c75f90b82c packages/webui/tests/usage-render.test.mjs
|
||||
@@ -0,0 +1,31 @@
|
||||
packages/bus/src/broker.mjs
|
||||
packages/bus/src/limits.mjs
|
||||
packages/bus/src/proxy-usage.mjs
|
||||
packages/bus/src/runtime.mjs
|
||||
packages/bus/src/usage.mjs
|
||||
packages/bus/tests/limit-checks.test.mjs
|
||||
packages/bus/tests/p5-key-context.test.mjs
|
||||
packages/bus/tests/p5-runtime.test.mjs
|
||||
packages/bus/tests/proxy-usage.test.mjs
|
||||
packages/bus/tests/usage.test.mjs
|
||||
packages/business/src/business.mjs
|
||||
packages/business/src/launch.mjs
|
||||
packages/business/src/organization.mjs
|
||||
packages/business/src/plugin-settings.mjs
|
||||
packages/business/tests/plugin-settings.test.mjs
|
||||
packages/business/tests/token-limit-settings.test.mjs
|
||||
packages/model-proxy/README.md
|
||||
packages/model-proxy/src/client.mjs
|
||||
packages/model-proxy/tests/usage-client.test.mjs
|
||||
packages/plugins/README.md
|
||||
packages/plugins/limit-check/daily-quota/index.mjs
|
||||
packages/plugins/limit-check/token-limit/index.mjs
|
||||
packages/plugins/src/kinds.mjs
|
||||
packages/plugins/tests/daily-quota.test.mjs
|
||||
packages/plugins/tests/kinds.test.mjs
|
||||
packages/plugins/tests/loader.test.mjs
|
||||
packages/plugins/tests/token-limit.test.mjs
|
||||
packages/plugins/usage/cliproxy-queue/README.md
|
||||
packages/plugins/usage/cliproxy-queue/index.mjs
|
||||
packages/webui/src/public/bus.js
|
||||
packages/webui/tests/usage-render.test.mjs
|
||||
@@ -0,0 +1,20 @@
|
||||
# Intended admitted-runner controls — execution pending
|
||||
|
||||
These are first guards to establish on the admitted runner. Current controls have NOT run after the priority STOP; no source guard is described as observed RED/GREEN.
|
||||
|
||||
| R1 finding | Whole-file control | Baseline first guard / RED cause | Fixed positive and boundary controls |
|
||||
|---|---|---|---|
|
||||
|1 P1 identity|packages/bus/tests/p5-identity.test.mjs|Boot foreign sentinel still leaves queueCalls=1 where0 required; later foreign/refused listener increments calls; all are behavior assertions, not fixture errors.|Matching sentinel drains without any issued agent key; boot/later refusal zero queue consumption; human plugins/usage reads stay available; fresh sentinel check precedes each drain; sticky refusal never retries the management list.|
|
||||
|2 P2 namespace/checks|packages/bus/tests/p5-key-compatibility.test.mjs|Plain abcdefabcdef account native count at10 is ignored; no-model lookup returns proxy-key-refused below limit; empty checks wrongly perform metadata lookup; chief reset of plain account leaf refuses.|Below/at legacy quota, original account count/report with no proxy and unrelated proxy metadata; zero lookups for plain leaves or empty checks (legacy and daily); shared validated daily shape; daily model matching/report positive; old/new daily/plain/removal/reset human fence; malformed partial daily schema refuses.|
|
||||
|3 P2 nonblocking|packages/bus/tests/p5-background.test.mjs|The queue response is causally held; queue arrival plus one event-loop barrier leaves f.bus=null because503 startBroker awaits the poll. Startup assertion must fail before releasing the held response.|Ready/control/native key preflight/native usage/limit work completes while held; interval shares singleflight; explicit success/failure release updates availability; close of a held poll remains pending at4999ms and completes at the original5000ms virtual client deadline. No sleeps/deadline increase.|
|
||||
|
||||
The preserved24 whole files remain explicitly listed in whole-files.txt, plus the three new controls and the affected existing ModelKeys whole file (28 total). Current503-added cumulative-model fixture tests in token-limit/limit-checks/p5-key-context are corrected to legacy plain-account or accepted DAILY model semantics; their count/refusal/ownership assertions remain. All original09a847 base assertions/deadlines are retained; authorized usage inventory additions are unchanged.
|
||||
|
||||
Overlay sequence (isolated private copies only):
|
||||
1. Materialize Git503b91e56137482abef475bc3b1b72a64b0a329c in a private admitted runner root. Do not run product from this author worktree.
|
||||
2. Apply packet/baseline-controls.patch, which adds exactly the current three control files and fake fixture; it changes no production byte. This is the original503 baseline for all three first guards.
|
||||
3. Execute each control whole file under the admitted private gate-tool/native priority contract. Retain every genuine behavior RED.
|
||||
4. Apply packet/baseline-to-fixed.patch. It is the complete fixed source/test delta with the four already-installed controls removed from the patch to avoid reapplication. This must yield packet/source-tests.patch's exact fixed overlay on503.
|
||||
5. Rehash every fixed input, run the three controls then all28 current whole files with original budgets, collect native priority root/actual-child evidence, raw receipts/exit codes, actual consumed-source map and cleanup. Priority/setup failure stops, not retries.
|
||||
|
||||
Additional forensic snapshot: baselines/runtime-before-background-fix.mjs captures finding1+2-prepared runtime immediately before the finding3 source edit. It is evidence only; canonical baseline for replay is Git503 plus controls. No snapshot substitutes unobserved source controls for runtime evidence.
|
||||
@@ -0,0 +1,34 @@
|
||||
# Admitted-runner entry and native priority contract — NOT RUN / NOT ADMITTED
|
||||
|
||||
Worktree/source root (unchanged binding):
|
||||
`/home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f`
|
||||
|
||||
HEAD must remain `503b91e56137482abef475bc3b1b72a64b0a329c` until applicable runner GREEN. This packet is an UNCOMMITTED source/test overlay, not a new accepted product commit. Parent owns the dedicated1014 admission/profile and runtime execution. No full/browser/provider/namespace or scheduler change is part of this packet.
|
||||
|
||||
## Entry ownership and limitation
|
||||
|
||||
The actual diagnostic entry used in receipt07 was
|
||||
`agents/codex/work/queue-333/r1-repair/run-strict19.sh`, calling the private
|
||||
`run-priority.mjs` and `priority-guard.mjs` in that directory. Those exact source
|
||||
bytes are preserved as evidence. It is **NOT an admitted gate entry and must not
|
||||
be retried**: native drift was observed and Node --test's root did not execute
|
||||
its forwarded preload, so the direct-child handshake capture was incomplete.
|
||||
`run-light.sh` is likewise an old nice-only behavior runner, not a strict19 gate.
|
||||
|
||||
No new execution entry/profile on1014 has been admitted. The parent must name
|
||||
and pin its private gate-tool entry and the actual selected root before running.
|
||||
Do not substitute either old runner or the original503 scoped runner. Read-only
|
||||
R2 may examine this packet before runtime acceptance; it cannot admit a gate.
|
||||
|
||||
## Requirements for the parent's private gate-tool entry
|
||||
|
||||
1. Invoke only the exact whole-file list in the frozen packet, serial concurrency1. Preserve all existing test timeouts and budgets. Use a fresh mktemp private HOME/XDG_CONFIG_HOME/TMPDIR/MOSAIC_CONFIG for each baseline/fixed pass; no real instance/auth/env/credential paths, provider traffic or host proxy.
|
||||
2. Establish native own-process priority19 in the actual gate-tool root before module execution: setPriority(0,19) and native readback. A shell's relative nice or inherited priority is not evidence. The observer/root must itself retain the required priority for the run; any setup refusal or observed drift is STOP/UNVERIFIED, never behavior RED.
|
||||
3. Establish the same own-process native preexec/set/readback in **every actual test child**, not only a preload forwarded to a Node test runner or an inert wrapper. The gate root must execute its own prelude, and each test child must execute its prelude before importing the tested modules. Do not add a no-op prelude that misses Node's --test parent. No retry/repeated renice or host-daemon modification around drift is permitted.
|
||||
4. Capture native getPriority(child.pid) from the direct parent before tested module execution and after tested module work while that child still exists; use a causal acknowledgement barrier rather than a timed race. Capture child self-readbacks before/after and on exit as well. Record pid/ppid, phase, actual priority, exit/signal and the source pin of every private helper. Both root and actual testchild evidence are required. A missing/ESRCH sample, missing handshake, setup failure or drift makes the pass unverified, independent of test assertion counts.
|
||||
5. Pin the gate helper path/hash/Gitblob, selected test root and applied overlay hash in each raw receipt. Resolve the baseline/fixed source manifests before execution. Record exact Node version and all consumed module/data inputs from the real admitted pass; the static map here is not execution provenance.
|
||||
6. Run the per-control baseline first guards against the preserved503 baseline plus the current controls-only overlay. Only the named behavior assertion failure with complete strict19 capture is intended RED. Missing imports, fixture/setup errors, timeout/priority failures are not RED. Then apply the complete fixed overlay and run each control and all28 listed whole files. Preserve output/exit statuses without normalizing raw whitespace. Recheck hashes after execution and collect cleanup proof.
|
||||
|
||||
Programmatic Node test-runner entry or a native preexec wrapper may implement
|
||||
these requirements, but the implementation and target profile remain the
|
||||
parent's admission decision. This document authorizes no workstation retry.
|
||||
@@ -0,0 +1,43 @@
|
||||
# P5 independent R1 response
|
||||
|
||||
Starting candidate: 503b91e56137482abef475bc3b1b72a64b0a329c.
|
||||
Original base:09a847edaa25b609bac7728ff83f224708a29399.
|
||||
Review: REVIEW-R1.md, copied without edits; SHA2567c95672a30c0d5c39189c7c7d610ada89cd539dcb9413617071fbb81200fd008.
|
||||
All findings preserved as CHANGES until fixes have actual RED/GREEN evidence.
|
||||
|
||||
Source verification:
|
||||
1. Confirmed unconditional client callback permits queue reads after ModelKeys sentinel refusal.
|
||||
2. Confirmed regex-only key classification changes valid legacy account limits and chief resets; host lookup also runs for zero checks. Accepted scope requires daily model quotas, not cumulative model namespace takeover. Repair will use the validated daily shape consistently and drop the invented cumulative model interpretation.
|
||||
3. Confirmed startup awaits proxyUsage.tick and may wait the existing management-client timeout for optional telemetry. Repair will supervise first poll in background with unchanged deadlines/singleflight/close.
|
||||
|
||||
Original candidate, runner, raw receipts and source pins remain unchanged. R1 repair evidence is separate in this directory. No independent approval/self-review, heavy/full/browser gate or deployment authority claimed.
|
||||
|
||||
Priority evidence correction (Mos1971): command text `nice -n19` is insufficient on this workstation (ananicy node16/bash-4). Earlier R1 receipts01–06 are behavior observations with priority unverified; no strict19 acceptance claim attaches to them. New bounded checks use OWN-process native setPriority(0,19) plus readback before modules and at beforeExit/exit, and wrapper native getPriority(child.pid) before/after the direct child. A setup failure, any observed drift or incomplete capture returns78 UNVERIFIED/STOP; it is never treated as intended RED or GREEN. No scheduler/daemon mutation, repeated renice, deadline change or retry around a priority refusal is authorized.
|
||||
|
||||
## Native priority STOP (receipt07)
|
||||
|
||||
Actual trace07-priority-native.jsonl: wrapper PID2643577 before=19, after=16; test PID2643590 before-modules=19, after-modules=16, exit=16. Six behavior assertions completed, but the test runner reports a file failure because priority guard changed exit status. This is **UNVERIFIED/STOP exit78**, not intended RED and not GREEN. Node --test forwarded --import to its test subprocess, so the direct test-runner parent did not execute that preload: the requested direct-child handshake/capture is also incomplete. No priority or provenance proof is inferred from command text or the six assertions. No further local test runs are authorized after this observed drift; no scheduler mutation or retry was attempted. Admitted runner verification is required. Source/regression preparation continues under the user's explicit fallback mandate.
|
||||
|
||||
## Finding 1 source response / priority-unverified behavior observations
|
||||
|
||||
Added ModelKeys.verifyIdentity(), serialized by the existing controller. It requires the existing ready state, performs a fresh sentinel-only management-list check, never issues an agent credential, never reconciles, and honors sticky proxy-open refusal. Collector now awaits client acquisition; the P5 runtime usage callback verifies that identity before returning its management client. Boot refusal and later failure retain the human surface, unavailable telemetry and value-free receipt, with zero queue drain. Matching sentinel requires no issued agent key.
|
||||
|
||||
Receipts01/02: actual behavior REDs under nice-relative priority, later reclassified priority-UNVERIFIED. Boot observed queue1 vs expected0; later refusal queue2 vs expected1; changed-listener predrain control likewise failed. Receipt03 recorded12/12 behavior passes after the fix (identity, proxy collector, native quota runtime files), also priority-UNVERIFIED. These are observations only, not strict19 acceptance. Current identity controls now await the initial poll's actual receipt to preserve the same assertions after the nonblocking startup change; current bytes have not run.
|
||||
|
||||
## Finding 2 source response / priority-unverified behavior observations
|
||||
|
||||
A shared pure isDailyModelQuota() validates key ID and the full daily {limit,since,reset,timeZone} leaf. Business schema, daily and cumulative checks, host metadata lookup and both old/new organization fences use it. Plain {limit,since} keys stay legacy account leaves regardless of twelve-hex spelling; token-limit matches/reports account only. Zero loaded checks returns before any model metadata lookup. Daily model changes, plain→daily, daily→plain/removal and reset remain human-only; plain legacy chief resets remain permitted. The invented cumulative model-key interpretation is removed, not moved into a new namespace.
|
||||
|
||||
Receipts04/05 captured actual legacy failures (lookup refusals, wrong account matching, empty checks, chief reset) under nice-relative priority. Receipt04 also contained a new fixture missing-system error; receipt05 corrects the fixture and demonstrates the actual chief-reset refusal. Receipt06 recorded6/6 behavior passes after source repair, priority-UNVERIFIED. Receipt07 later observed strict-priority drift and STOP. Candidate503-specific cumulative-model test fixtures are retargeted to accepted daily leaves with every enforcement assertion retained; the appended token-limit test now asserts legacy account semantics. Pre-P5/base assertions and deadlines remain unchanged. No post-STOP execution is claimed.
|
||||
|
||||
## Finding 3 source response / execution pending
|
||||
|
||||
Prepared p5-background.test.mjs with a queue response held open, explicit queue-arrival/event-loop barriers (no sleeps or racing deadlines), native readiness/control/key-preflight/usage/limit work while held, scheduled singleflight, success/failure release, and cleanup at the original5000ms management deadline using virtual timers. First guard is that f.bus is nonnull while the queue is still held; original503 awaits that held response and should fail this behavior assertion. These controls have NOT RUN locally, not RED/GREEN evidence.
|
||||
|
||||
Saved exact immediately-pre-fix runtime bytes in baselines/runtime-before-background-fix.mjs. Fixed runtime uses one supervised usageTick function for the initial call and later interval. The first call is background; the same collector singleflight and original close/pending/client deadline apply. Only P5 usage wiring/tick hunks changed; no launcher/session/harness/business route edits. Admitted runner must establish genuine priority-verified RED then GREEN on the pinned baseline/fixed overlays before any new product commit.
|
||||
|
||||
## Static packet handoff — no product commit
|
||||
|
||||
Per latest owner direction, HEAD remains original503 and all repairs stay UNCOMMITTED. No local tests or Node product execution followed receipt07 STOP, including no syntax-check substitute. New background controls and final current source bytes are pending execution. The packet contains the complete source/test diff from503 (including untracked controls/helper), controls-only baseline overlay, baseline→fixed remainder, exact baseline/fixed bytes with SHA256/size/Gitblob IDs, static module/dependency edges and full28-file list. Its input map is explicitly STATIC, not a fresh consumed-source observation. Genuine strict19 baseline RED/fixed GREEN and actual consumed-source capture must come from the admitted runner before any product commit. The parent may request new read-onlyR2 on these exact bytes before execution; this author issues no independent/self-review verdict.
|
||||
|
||||
Gate entry/root and root+actual-testchild native preexec/readback requirements are in GATE-ENTRY.md. Existing diagnostic drivers are preserved only as failed/incomplete priority evidence and are not authorized for retry. Dedicated1014 admission/profile and private gate-tool entry remain pending with the parent. Cleanup from every actual test run used private mktemp EXIT/test fixture cleanup. No scheduler, live proxy/account/credential/provider, P3 launcher/session/harness/business-route, queue, remote or landing state was changed.
|
||||
@@ -0,0 +1,82 @@
|
||||
# P5 row333 independent implementation review — Mos1966 / Mos1961
|
||||
|
||||
Verdict: **CHANGES**
|
||||
|
||||
Reviewer: independent Codex review sub-agent; not the implementation author.
|
||||
Implementation author: Codex builder, isolated worktree `/home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f`.
|
||||
Git-recorded author/committer: Jason Woltje; commit subject `feat: add optional proxy usage and human model-key quotas (row333)`.
|
||||
Candidate: `503b91e56137482abef475bc3b1b72a64b0a329c`.
|
||||
Base: `09a847edaa25b609bac7728ff83f224708a29399`.
|
||||
Review time: 2026-10-26 23:03 UTC (2026-10-26 18:03 CDT).
|
||||
|
||||
Reviewed the exact candidate/base Git objects, all 31 changed package files, and supporting callers/contracts. The isolated worktree HEAD equals the full candidate and its status was clean. The parent's integrated row334 product was not substituted for this candidate. Requirements are accepted P5 in `docs/plans/2026-10-24_model-proxy-rows.md`, design D18–D20 with the mos-1600 per-key/no-raw-upstream correction, and the review assignment's compatibility and nonblocking constraints.
|
||||
|
||||
## Findings
|
||||
|
||||
### 1. P1 — Do not drain a listener after its instance identity was refused
|
||||
|
||||
Primary location: candidate `packages/bus/src/runtime.mjs:387–389`; destructive read at `packages/bus/src/proxy-usage.mjs:31–33`.
|
||||
|
||||
Source trigger: enable `plugins.usage: "cliproxy-queue"`, point the instance at a loopback management listener that accepts its management authentication but lacks this config directory's sentinel (for example a different instance with a reused management key). `ModelKeys.reconcile()` checks the sentinel before modifying the list (`model-keys.mjs:80–84`) and throws `proxy-open`; runtime intentionally catches that refusal to retain the control surface (`runtime.mjs:326–327`). Nevertheless the new collector receives `client: () => modelProxyClient` unconditionally and performs the queue GET at startup and on later ticks. It never consults the controller's identity/readiness refusal.
|
||||
|
||||
The GET consumes the other listener's queue. Resolving local owners *after* `module.read()` and dropping/logging unknown IDs cannot undo that consumption. The local Store writer lock prevents two local writers, but does not establish ownership of a remote loopback listener. This is a new P5 side effect after a fail-closed refusal; it is not a request to change P2's existing decision to keep human controls available.
|
||||
|
||||
Smallest remedy: fence the collector's management-client access behind verified identity for this instance, honoring boot and subsequent sentinel refusals before any queue GET. Keep an unavailable telemetry state and value-free receipt when verification is absent; do not retry around `proxy-open`. This must not require a particular agent to have an issued key merely to establish instance identity.
|
||||
|
||||
Required regression evidence: a fake listener accepts management auth and returns a valid foreign sentinel/list, while its queue records/drains calls. With telemetry enabled, assert `proxy-open`, zero queue requests/consumption across startup and scheduled ticks, and an available human/control surface. Add the matching-instance positive case and a refusal after a previously successful identity check. Current `p5-runtime.test.mjs` uses the correct sentinel and enables telemetry only after startup; `proxy-usage.test.mjs` bypasses this host identity boundary entirely.
|
||||
|
||||
### 2. P2 — Twelve-hex legacy account names lose their quota, reset, and no-check behavior
|
||||
|
||||
Primary location: candidate `packages/plugins/limit-check/token-limit/index.mjs:33–35`; related new gates at `packages/bus/src/limits.mjs:126–136` and `packages/business/src/organization.mjs:85–91`.
|
||||
|
||||
Concrete legacy input: `launch.account.name = "abcdefabcdef"`, an ordinary existing `tokens.keys.abcdefabcdef = { limit: 10, since: <canonical timestamp> }`, and native records/subject whose `account` is `abcdefabcdef`. No proxy or model record is needed by this previously valid configuration. `ID_PATTERN` accepts this account name (`business/src/vocabulary.mjs:206`; `launch.mjs:85–92`), and the base token-limit matched every keys leaf against `account` (`base token-limit/index.mjs:31–34`). Nothing in the accepted P5 brief reserves existing twelve-hex account names.
|
||||
|
||||
The candidate changes this plain leaf to match `modelKeyId` solely because its name matches a regex. Consequently:
|
||||
|
||||
- With `token-limit` enabled and no proxy/model record, `createLimits` returns `proxy-key-refused` even below the account limit, before asking the check. At the plug-in level, known account records at the limit are instead ignored and its count becomes zero.
|
||||
- With no limit checks configured, `state().checks` is `[]`, so it passes the `!st.checks` guard. The same lookup still runs before the empty loop and returns `proxy-key-refused`. The base returned `allow:true` / `stop:false` here. Thus an unused legacy limit now blocks launches/stops turns even though enforcement is switched off.
|
||||
- With proxy metadata present, the resolved model ID generally differs from the account name; the account quota silently stops matching its original records. The new organization fence also prevents the chief's previously permitted reset of this plain account leaf.
|
||||
|
||||
These outcomes follow directly from the branches above, independently of the builder's test counts. They are introduced regressions, not Mos1864 baseline defects. The same reasoning applies to the previously examined valid name `abcdef012345`; the parent's additional `abcdefabcdef` example confirms the ambiguity without relying on a digit-leading name.
|
||||
|
||||
Smallest contract-preserving remedy within accepted P5: distinguish the genuinely new daily model-key leaf by its validated `reset`/`timeZone` shape, retain ordinary `{limit,since}` keys leaves as legacy account limits, and use that same classification consistently in the host lookup, matching, reports and both organization fences (including old-to-new/removal transitions). Preserve the empty-check path before performing metadata lookup. P5 requires daily model-key quotas; newly added cumulative model-key support must not silently take over the existing account namespace. If cumulative model-key quotas are retained, they need an unambiguous separately authorized representation.
|
||||
|
||||
Required regression evidence: cover `abcdefabcdef` with plain account limits, no proxy/model record, below/at limit, original account report count and chief reset; repeat with proxy metadata whose ID differs. Cover no configured checks with that legacy leaf and with a new daily model-key leaf: preserve the established no-check result without resolving model metadata. Retain positive daily per-key enforcement, current/retiring native lookup, and human-only changes/removals/resets for actual model-key daily quotas. Existing P5 tests cover an invented cumulative model-key interpretation and a daily key, but not this legacy collision or the empty-check branch.
|
||||
|
||||
### 3. P2 — Optional telemetry adds a blocking startup dependency
|
||||
|
||||
Primary location: candidate `packages/bus/src/runtime.mjs:865–867`.
|
||||
|
||||
Source trigger: correct sentinel/reconciliation, telemetry enabled at boot, and a queue endpoint that stalls while other management operations work. The initial `await proxyUsage.tick()` waits for that queue read, up to the existing five-second client deadline (`model-proxy/src/client.mjs:10,45`). The process waits for `startBroker()` before sending its ready answer and launch capabilities (`bus/src/process.mjs:147–152`). Thus optional telemetry delays native readiness/launch admission even though it has no quota authority. Later timer ticks are independent of native requests; the startup await is the exception.
|
||||
|
||||
Smallest remedy: start the first poll in the same supervised background path as subsequent ticks, preserving single-flight handling, value-free errors and close cleanup. Do not increase any existing deadline.
|
||||
|
||||
Required regression evidence: hold a fake queue response open while allowing required reconcile requests, prove startup/native readiness completes before releasing the queue, and exercise native usage/limit work while a poll is outstanding. Then release/fail the response and verify availability, no duplicate drain and bounded cleanup. Current whole-file receipts contain no such slow-queue readiness test.
|
||||
|
||||
## Independent evidence checks
|
||||
|
||||
Performed read-only Git/filesystem/hash analysis, not product execution:
|
||||
|
||||
- `source-inputs.sha256` SHA-256 is exactly `b4662dcafb2aeb27a06e5dbd3b9d0b6d184e8624e344fed351ff20e3b255951b`. All **202** listed file hashes match candidate Git blobs and the pinned isolated tree, with zero mismatches. The 944 raw JSONL entries contain exactly 202 distinct path/hash pairs, exactly equal to the manifest; no path has multiple traced hashes.
|
||||
- All **31** changed package paths exactly equal `candidate-sourcepaths.txt`; every entry in `candidate-sourcehashes.sha256` matches both sources. That manifest's SHA-256 is `b1457ec57c0fb695f05a08ba20b420820be5f32cac2b77ac5ea20b02115153e2`.
|
||||
- All **25** entries in `receipts.sha256` match candidate blobs and isolated-tree bytes. Receipt-manifest SHA-256: `a8b91660ada571eab9c0328b74407517ec63e1ff56172302acec1d347253a810`. Raw source-trace SHA-256: `9c16aa4b8e6d81aa5b9867fec5e0890b22e90db5c307da55badfcfa9f240aef1`.
|
||||
- The scoped runner explicitly names **24 whole test files**, uses `nice -n 19`, `--test-concurrency=1`, and private HOME/XDG_CONFIG_HOME/TMPDIR/MOSAIC_CONFIG with cleanup. Its SHA-256 is `c8a2bf4539bffe38f3198308fd60e9c1ad338841b406af160ab0739c15394290`. These are verified runner bytes and recorded output, not independent observation of the original processes' environment.
|
||||
- Receipt24 records **174 tests, 174 pass, 0 fail/cancelled/skipped/todo**, SHA-256 `3358af061c35d42b00d5ee1e001939534c5e7563d4f5418ea85431605d0b9f6d`. This remains builder scoped evidence, not an independent test run, full gate or browser gate.
|
||||
|
||||
RED history is retained as RED. Receipt16 records the upstream-value mutant with **11/15 passing and four failing tests**: the client exposes the raw account value, while collector validation refuses it and downstream expectations fail. Receipt17 records restored **15/15**. Final client bytes hash to `f5f86cad661034f223a76352d877fa8d7883bfa921a7a01282347a9a03272441`, matching the documented restoration hash and final source pins. The receipts do not contain a separately captured pre/post backup or mutant patch hash, so byte-identical restoration at that historical instant is documented by the builder rather than independently replayed here.
|
||||
|
||||
Receipt18 is **169/170**, with the exact existing `REQ-LIMIT-4 a role run at its limit stops at the end of its turn: RESULT and read land first, the claim is revoked by limit-check` assertion failing at `limit-stop.test.mjs:61` because `run` was added to the original second subject argument. The candidate keeps that argument's shape and puts `{run}` in the private third context. The entire original limit-stop file is byte-identical to base. Receipt19 records **170/170** after that correction. Receipt20 is a genuine **2/3** RED for the supplied modelKeyId fallback; receipt21 is **15/15** after its removal. Receipt22 records **173/173**. Receipt23 is a genuine **3/4** RED for missing native context; receipt24 records **174/174** after the explicit context refusal. These were builder development REDs, not prior independent review findings, and are not relabelled GREEN. Receipt05 also remains a syntax-error RED despite its filename; receipts12/13 remain failed runtime-fixture runs.
|
||||
|
||||
All modified pre-existing test files other than the two authorized inventory updates retain their entire base bytes as an unchanged prefix. The kinds/loader edits are the strictly additive `usage`/`usage:[]` expected inventories; no old assertion or deadline was removed or weakened.
|
||||
|
||||
## Other source conclusions and limits
|
||||
|
||||
Telemetry source rows are excluded at the start of `turnRecords`, before native totals and quota input. The collector validates and whitelists persisted fields, uses hashed client/upstream identities, retains only safe failure metadata, serializes concurrent ticks, and routes current/retiring ownership from credential status. Malformed/unknown/oversize/non-finite/unsafe counts cannot flow through the new queue client as raw values into store, error, audit or Console fields: the queue operation reuses fixed loopback GET, count=100, original response cap/deadline and value-free errors/receipts. No second queue consumer was found in the product sources; finding 1 concerns foreign-listener identity rather than local double counting.
|
||||
|
||||
Native model-key authority comes from the host's run map and credential metadata, not a JSON-supplied key ID. Lookup rejects missing/duplicate owners, foreign business/instance/run, missing retained generations and ambiguous IDs. The broker's private context is derived from its authenticated session; the public subject drops supplied run/modelKeyId fields. The new usage and model-quota fences run before validation and again against serialized bytes, compare against the old human, and reject tester/agent identities even when names collide. Finding 2 concerns which leaves those otherwise fail-closed fences classify.
|
||||
|
||||
Polling is absent by default, defaults to 15 seconds when enabled, validates integer 1..59, and is exposed through the exact human `plugins.set` argument contract. Console native key rows and optional proxy-reported account counts are separated and labelled; telemetry is explicitly described as incomplete and non-enforcing. Broker imports are unchanged, kinds remains import-free, and no host management implementation was added to the pure Broker/sandbox import closure. No P3 launcher/session/harness/business-routing files changed.
|
||||
|
||||
No tests, Node/product runtime, HTTP, browser, provider, real instance config, credential files or live proxy paths were run/read. Hash checking used repository files only. No code, tests, helpers, queue, session/build logs, issues, posts, pushes, commits, merges or live state were changed; this report is the only authorized write. Static analysis establishes the reported branch behavior; the suggested regression cases remain to be executed by the authorized builder/gate owner. Hash equality verifies the captured inputs/receipts, not completeness of uninstrumented reads or independent execution provenance.
|
||||
|
||||
These three findings are in the candidate delta. No pre-existing issue is being promoted to a new landing blocker; any separately identified baseline defect belongs under Mos1864 unless a required gate is RED. #662 / 72f77815 and #657/#658 remain excluded/backlog; #267/#289 are outside the 10-27 slice but remain in full scope. The #660 full-gate target is not admitted by this review. No landing authority or full/browser/combined-gate approval is implied.
|
||||
@@ -0,0 +1,960 @@
|
||||
import { lstatSync, readdirSync, readFileSync } from 'node:fs';
|
||||
import { join } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { Store } from './store.mjs';
|
||||
import * as projectModule from '../../project/src/index.mjs';
|
||||
import * as libraryModule from '../../library/src/index.mjs';
|
||||
import { Broker, BusError, LIBRARY_FETCH_FIX } from './broker.mjs';
|
||||
import { Credentials } from './credentials.mjs';
|
||||
import { serve } from './server.mjs';
|
||||
import { launchSettings } from '../../business/src/launch-settings.mjs';
|
||||
import { readSessions, sessionsFile, stopSession } from '../../seat/src/session.mjs';
|
||||
import { compactionCount, storeDir } from '../../seat/src/compactions.mjs';
|
||||
import { publishRemote, workingRepo, WorkingError } from '../../seat/src/working.mjs';
|
||||
import { createLoader, hasModule } from '../../plugins/src/loader.mjs';
|
||||
import { pluginSettings } from '../../business/src/plugin-settings.mjs';
|
||||
import { loadManagementClient } from '../../model-proxy/src/client.mjs';
|
||||
import { ProxyPage } from './proxy-page.mjs';
|
||||
import { sha256 } from '../../model-proxy/src/common.mjs';
|
||||
import { initializeProxy } from '../../model-proxy/src/settings.mjs';
|
||||
import { ModelKeys, modelOrganization, stopModelRuns, MODEL_STOP_TIMEOUT_MS } from './model-keys.mjs';
|
||||
import { instanceSettings } from '../../business/src/instance-settings.mjs';
|
||||
import { organizationWriter, OrganizationError, setReplyLimits } from '../../business/src/organization.mjs';
|
||||
import { credentialVerbs } from './credential-verbs.mjs';
|
||||
import { loadBusiness } from '../../business/src/business.mjs';
|
||||
import { loadRole } from '../../business/src/role.mjs';
|
||||
import { resolveInstance } from '../../business/src/resolve.mjs';
|
||||
import { canonicalJson } from '../../business/src/util.mjs';
|
||||
import { busBusiness } from './business.mjs';
|
||||
import { webService } from './web.mjs';
|
||||
import { hostExecutor, sweepRunDir } from './host-run.mjs';
|
||||
import { grantKeys, hostGrant, hostReference, sweepHostKeys } from './host-grant.mjs';
|
||||
import { giteaGrant, giteaKeys, giteaStart, giteaReference } from './gitea-grant.mjs';
|
||||
import { verifyPrincipal } from './principal.mjs';
|
||||
import { loadAccess } from '../../business/src/access.mjs';
|
||||
import { inspectInterpreter, recordInterpreterStart } from './interpreter.mjs';
|
||||
import { createPeerReader } from './peercred.mjs';
|
||||
import { createUsage } from './usage.mjs';
|
||||
import { createProxyUsage } from './proxy-usage.mjs';
|
||||
import { createLimits, modelUsageKey } from './limits.mjs';
|
||||
import { createProcessing } from '../../processing-control/src/coordinator.mjs';
|
||||
import { discordProcessingHooks } from '../../discord/src/processing.mjs';
|
||||
import { createContainerStopper } from '../../processing-control/src/containers.mjs';
|
||||
|
||||
// Row 194 (D3): the verbs the instance writer commits, whose answers carry restart.
|
||||
const INSTANCE_VERBS = new Set(['instances.set', 'veto.set', 'instance.hire', 'instance.fire']);
|
||||
// FED R4 (#1801, design 3.7): the revocation timer's period.
|
||||
export const ACCESS_SWEEP_MS = 30_000;
|
||||
// Trusted host API. S1 supplies resolved definitions, S6 supplies launch records and ends them.
|
||||
// Human limits writes use the shared organization writer behind the verified transport.
|
||||
// `tasks` is S3's adapter factory: ({broker, credentials, businesses}) => {handle, timeout, close}.
|
||||
// REQ-HARN-2, REQ-PLUG-2 (decision 0b81b0c5): one web service per business. Its search source is
|
||||
// the "search-source" plug-in the business's organization file switches on: searxng-url (the
|
||||
// business var web.searxng) or searxng-bundled. With none, web.search refuses "not configured" and
|
||||
// web.fetch still works. A plug-in that refuses to load is logged and leaves search off; it never
|
||||
// stops the broker. Under harness-builtin the harness serves web itself, so the broker gets no
|
||||
// service and refuses the web verbs.
|
||||
export async function webServices(businesses, { log = (e) => process.stderr.write(`plugins: ${JSON.stringify(e)}\n`), deps } = {}) {
|
||||
const services = new Map();
|
||||
for (const [name, b] of Object.entries(businesses)) {
|
||||
const loader = createLoader({ log });
|
||||
await loader.load(b.plugins ?? {});
|
||||
const [source] = loader.modules('search-source');
|
||||
// "harness-builtin" is served by the harness itself, not the broker: no broker web verbs.
|
||||
if (loader.loaded()['search-source'][0] === 'harness-builtin') continue;
|
||||
// The module takes the business var web.searxng; "searxng-bundled" ignores it.
|
||||
const settings = { searxng: b.vars?.['web.searxng'] };
|
||||
const search = source ? { search: async (query, opts) => source.search(settings, query, deps, opts) } : null;
|
||||
services.set(name, webService({ search, deps }));
|
||||
}
|
||||
return services;
|
||||
}
|
||||
// Row 65 (REQ-PLUG-2): the thinking levels each harness module in this tree applies, for the route
|
||||
// checks a write runs, which are synchronous. A module that doesn't load, or answers anything but a
|
||||
// list of names, answers null, which refuses the write. The tree is pinned, so a module changes only
|
||||
// with a re-pin, and a re-pin restarts the bus.
|
||||
export async function harnessLevels({ log = (e) => process.stderr.write(`plugins: ${JSON.stringify(e)}\n`) } = {}) {
|
||||
const levels = new Map();
|
||||
let names = [];
|
||||
try {
|
||||
names = readdirSync(fileURLToPath(new URL('../../plugins/harness/', import.meta.url))).filter((name) => hasModule('harness', name));
|
||||
} catch (e) {
|
||||
log({ event: 'harness-levels-unread', message: e.message });
|
||||
}
|
||||
for (const name of names) {
|
||||
const loader = createLoader({ log });
|
||||
if ((await loader.load({ harness: [name] })).refused.length) continue;
|
||||
try {
|
||||
const list = loader.modules('harness')[0].levels();
|
||||
if (Array.isArray(list) && list.every((level) => typeof level === 'string')) levels.set(name, Object.freeze([...list]));
|
||||
} catch (e) {
|
||||
log({ event: 'harness-levels-failed', name, message: e.message });
|
||||
}
|
||||
}
|
||||
return (name) => levels.get(name) ?? null;
|
||||
}
|
||||
// Row 224 C2-05b: a host-only adapter. A failed fetch keeps serving immutable old
|
||||
// objects, as C2-03a requires; no caller may select a repo, commit or sync --accept.
|
||||
export function createLibraryLookup({ dataRoot, sync, now = () => Date.now() }) {
|
||||
const methods = { find: libraryModule.find, get: libraryModule.get, search: libraryModule.search,
|
||||
manuscript: libraryModule.manuscript, universeInfo: libraryModule.universeInfo };
|
||||
return async (context, { method, args, authorize }) => {
|
||||
if (!Object.hasOwn(methods, method)) throw new libraryModule.LibraryError('query-argument-invalid', 'unknown lookup');
|
||||
authorize();
|
||||
const source = { ...context, dataRoot };
|
||||
let state = await libraryModule.libraryStatus(source);
|
||||
authorize();
|
||||
// sage-2819 / dewey-0852: failed attempts also pace inline retries. Otherwise an
|
||||
// outage makes every lookup refetch while lastFetch remains old or null.
|
||||
const recentAttempt = Math.max(state.lastFetch === null ? -Infinity : Date.parse(state.lastFetch),
|
||||
state.lastError === null ? -Infinity : Date.parse(state.lastError.at));
|
||||
const age = now() - recentAttempt;
|
||||
if (age > libraryModule.SYNC_INTERVAL_MS || age < 0) {
|
||||
try { await sync(source); }
|
||||
catch (error) {
|
||||
// A timer may already be fetching this mirror. Its current served state is still safe.
|
||||
if (!(error instanceof libraryModule.LibraryError) || error.code !== 'library-sync-busy') throw error;
|
||||
}
|
||||
authorize();
|
||||
state = await libraryModule.libraryStatus(source);
|
||||
}
|
||||
if (!state.served) throw new libraryModule.LibraryError('library-commit', 'library has never been synced');
|
||||
authorize();
|
||||
return methods[method]({ repo: libraryModule.mirrorPath(source), commit: state.served,
|
||||
mapping: libraryModule.checkMapping(context.business.projects[context.project]) }, args);
|
||||
};
|
||||
}
|
||||
|
||||
// B1: discovery is evidence of a process, never authority to stop it. Keep this
|
||||
// host-only inventory across the launcher's Registry[] recovery gap and endLaunch.
|
||||
// A failed boot read cannot be repaired by a later empty registry: that would lose
|
||||
// the very prior runs whose existence this inventory must establish.
|
||||
function modelRunInventory(dataRoot, bound, credentials) {
|
||||
const known = new Map(), terminal = new Map(), validated = new Map();
|
||||
const refuse = () => { throw new BusError('proxy-stop-failed'); };
|
||||
const same = (a, b) => ['business', 'role', 'run', 'pid', 'startTime', 'runnerPid', 'runnerStartTime', 'keyId'].every(k => a[k] === b[k]);
|
||||
const shape = s => {
|
||||
if (!s || ['business', 'instance', 'run'].some(k => typeof s[k] !== 'string' || !s[k])
|
||||
|| ['pid', 'runnerPid'].some(k => !Number.isSafeInteger(s[k]) || s[k] < 2)
|
||||
|| ['startTime', 'runnerStartTime'].some(k => typeof s[k] !== 'string' || !/^\d+$/.test(s[k]))
|
||||
|| (s.modelKeyId !== undefined && (typeof s.modelKeyId !== 'string' || !/^[a-f0-9]{12}$/.test(s.modelKeyId)))) refuse();
|
||||
return { business: s.business, role: s.instance, instance: s.business + '/' + s.instance,
|
||||
run: s.run, pid: s.pid, startTime: s.startTime, runnerPid: s.runnerPid,
|
||||
runnerStartTime: s.runnerStartTime, keyId: s.modelKeyId };
|
||||
};
|
||||
const refresh = () => {
|
||||
const file = sessionsFile(dataRoot), stat = lstatSync(file);
|
||||
if (!stat.isFile() || stat.isSymbolicLink()) refuse();
|
||||
const entries = readSessions(dataRoot).map(shape), seen = new Set();
|
||||
const after = lstatSync(file);
|
||||
if (!['dev', 'ino', 'size', 'mtimeMs', 'ctimeMs'].every(k => stat[k] === after[k])) refuse();
|
||||
// Validate the whole snapshot before merging any of it. Missing entries do
|
||||
// not erase known identities; the host may have just rewritten Registry[].
|
||||
for (const r of entries) {
|
||||
const key = r.business + ':' + r.run;
|
||||
if (seen.has(key) || (known.has(key) && !same(known.get(key), r))) refuse();
|
||||
seen.add(key);
|
||||
}
|
||||
for (const r of entries) known.set(r.business + ':' + r.run, r);
|
||||
};
|
||||
let bootChecked = false;
|
||||
try { refresh(); bootChecked = true; } catch { /* hold retirement, not the human/control surface */ }
|
||||
// startTimeOf/live alone conflate absence and read errors. Only a missing proc
|
||||
// directory, or a zombie with the SAME recorded start ticks, confirms an exit.
|
||||
const liveIdentity = (pid, ticks, proof, part) => {
|
||||
if (proof[part]) return false;
|
||||
let raw;
|
||||
try { raw = readFileSync(`/proc/${pid}/stat`, 'utf8'); }
|
||||
catch (error) {
|
||||
if (error.code !== 'ENOENT') refuse();
|
||||
try { lstatSync(`/proc/${pid}`); } catch (missing) { if (missing.code === 'ENOENT') { proof[part] = true; return false; } }
|
||||
refuse();
|
||||
}
|
||||
const fields = raw.slice(raw.lastIndexOf(')') + 2).trim().split(/\s+/);
|
||||
if (!/^[A-Z]$/.test(fields[0]) || !/^\d+$/.test(fields[19]) || fields[19] !== ticks) refuse();
|
||||
if (fields[0] === 'Z') { proof[part] = true; return false; }
|
||||
return true;
|
||||
};
|
||||
const runs = instance => {
|
||||
try {
|
||||
if (!bootChecked) refuse();
|
||||
refresh();
|
||||
const live = [], checked = [];
|
||||
for (const r of known.values()) {
|
||||
if (r.instance !== instance) continue;
|
||||
const key = r.business + ':' + r.run;
|
||||
const proof = terminal.get(key) ?? { outer: false, runner: false };
|
||||
terminal.set(key, proof);
|
||||
let associated = false;
|
||||
if (!proof.outer || !proof.runner) {
|
||||
const record = credentials.modelRecord(instance);
|
||||
associated = !!record && [record.keyId, ...record.retiring.map(k => k.keyId)].includes(r.keyId);
|
||||
const prior = validated.get(key);
|
||||
if (!associated && (!prior || !same(prior, r))) refuse();
|
||||
}
|
||||
const outerLive = liveIdentity(r.pid, r.startTime, proof, 'outer'), runnerLive = liveIdentity(r.runnerPid, r.runnerStartTime, proof, 'runner');
|
||||
// Never interpret an unknown/wrong key on a surviving prior run as no
|
||||
// old-key users. A confirmed exit may be retired without key guessing.
|
||||
if (outerLive || runnerLive) {
|
||||
// Provenance permits strict exit confirmation, NEVER filtering away a
|
||||
// surviving run whose model-key association has disappeared.
|
||||
if (!associated) refuse();
|
||||
const current = bound.get(r.business + ':' + r.run);
|
||||
if (current && (current.instance !== r.instance || current.keyId !== r.keyId
|
||||
|| current.pid !== r.pid || current.startTime !== r.startTime)) refuse();
|
||||
live.push(r);
|
||||
}
|
||||
if (associated && (outerLive || runnerLive)) checked.push(r);
|
||||
}
|
||||
// A newly bound launch whose registry publication has not happened is
|
||||
// uncertain, not absent. Do not grant retirement through that startup gap.
|
||||
for (const r of bound.values()) if (r.instance === instance && !known.has(r.business + ':' + r.run)) refuse();
|
||||
// Commit ONLY after the entire same-instance view passed both identities,
|
||||
// live binding consistency, later known entries and unpublished bindings.
|
||||
// Existing M1 terminal bits remain independently monotonic and unchanged.
|
||||
for (const r of checked) validated.set(r.business + ':' + r.run, { ...r });
|
||||
return live;
|
||||
} catch { refuse(); }
|
||||
};
|
||||
return {
|
||||
runs,
|
||||
authorizeStop(requests) {
|
||||
for (const r of requests) {
|
||||
const current = bound.get(r.business + ':' + r.run);
|
||||
if (!current || current.instance !== r.instance || current.keyId !== r.keyId
|
||||
|| current.pid !== r.pid || current.startTime !== r.startTime) refuse();
|
||||
if (!runs(r.instance).some(found => same(found, r))) refuse();
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export async function startBroker({
|
||||
dataRoot,
|
||||
businesses,
|
||||
launches = [],
|
||||
readers = [],
|
||||
repoRoots = [],
|
||||
tasks = null,
|
||||
organization = null,
|
||||
// Row 199: the tests' scratch CA for publish's git (`-c http.sslCAInfo=...`). process.mjs drops
|
||||
// it from the boot config, so only an in-process caller sets it.
|
||||
publishTls = [],
|
||||
// C2-03a: the tests' stand-in for syncCommand, a shorter timer and a scratch config dir for the
|
||||
// slot, { command, intervalMs, configDir }. A boot config is JSON and can't carry a function, so
|
||||
// a librarySync without one is refused.
|
||||
librarySync = null,
|
||||
// FED R3 (#414): the access file and its loader context, { file, context } (R1's loadAccess).
|
||||
// Without it no user binds. R6 and R8 pass it; the live boot config doesn't yet. FED R4 (#1801):
|
||||
// intervalMs, the revocation timer's period (design 3.7, 30 s), in-process only like librarySync's.
|
||||
access = null,
|
||||
// Row 252 (#1753, design section 2): the checked console.sso subjects, [{provider, iss, sub}], each an
|
||||
// owner of the business (Webby N1). The boot config carries them; no socket verb sets them. Empty, no
|
||||
// Console owner binds and the terminal owner is unchanged.
|
||||
consoleOwners = [],
|
||||
// P1 validated sidecar from the trusted host; never a socket request setting.
|
||||
proxy = null,
|
||||
}) {
|
||||
if (!Array.isArray(consoleOwners) || consoleOwners.length > 512 || consoleOwners.some((o) => o === null || typeof o !== 'object' || Array.isArray(o) ||
|
||||
Object.keys(o).length !== 3 || ['provider', 'iss', 'sub'].some((k) => typeof o[k] !== 'string' || !o[k] || o[k].length > 512)))
|
||||
throw new BusError('invalid-host-request');
|
||||
const owners = Object.freeze(consoleOwners.map((o) => Object.freeze({ provider: o.provider, iss: o.iss, sub: o.sub })));
|
||||
if (access !== null && (typeof access?.file !== 'string' || access.context === null || typeof access.context !== 'object'
|
||||
|| (Object.hasOwn(access, 'intervalMs') && !(Number.isSafeInteger(access.intervalMs) && access.intervalMs > 0))))
|
||||
throw new BusError('invalid-host-request');
|
||||
if (librarySync !== null && (typeof librarySync?.command !== 'function'
|
||||
|| (Object.hasOwn(librarySync, 'intervalMs') && !(Number.isSafeInteger(librarySync.intervalMs) && librarySync.intervalMs > 0))
|
||||
|| (Object.hasOwn(librarySync, 'configDir') && typeof librarySync.configDir !== 'string')))
|
||||
throw new BusError('invalid-host-request');
|
||||
let modelProxyClient = null, proxyPage = null, proxyUsage = null, usageTimer = null;
|
||||
let modelKeys = null, modelTimer = null, modelSweep = null;
|
||||
const modelRuns = new Map();
|
||||
let store, credentials, server, adapter, processing, syncTimer = null, syncPass = null, accessTimer = null;
|
||||
try {
|
||||
const proxyReceipt = entry => process.stderr.write(`model-proxy: ${JSON.stringify(entry)}\n`);
|
||||
const references = {};
|
||||
for (const [business, b] of Object.entries(businesses)) {
|
||||
for (const [role, r] of Object.entries(b.roles))
|
||||
if (r.credentials) references[business + '/' + role] = r.credentials;
|
||||
if (b.tracker?.sync?.credentials) references[business + '/@sync'] = b.tracker.sync.credentials;
|
||||
}
|
||||
const protectedRoots = [
|
||||
fileURLToPath(new URL('../../../', import.meta.url)),
|
||||
...repoRoots,
|
||||
...Object.values(businesses).flatMap((b) => Object.values(b.projects ?? {}).filter(p => p.kind !== 'library').map((p) => p.root)),
|
||||
];
|
||||
// Row 199 (#1697, design D1): the per-agent store is <configDir>/secrets/agents.
|
||||
const storeRoot = organization ? join(organization.dir, 'secrets', 'agents') : null;
|
||||
store = new Store(dataRoot);
|
||||
// Store's writer lock admits one bus per data root before it holds the management client.
|
||||
if (proxy) {
|
||||
if (!organization) throw new BusError('not-configured');
|
||||
modelProxyClient = await loadManagementClient({ configDir: organization.dir, proxy, receipt: proxyReceipt });
|
||||
}
|
||||
|
||||
// Row 234 (#1740, r6 X4 third bullet): each host grant record gives its agent a store reference to
|
||||
// host.<id>, so a restart finds the keys the grant executor wrote. The loader refuses host.<id> in a
|
||||
// role's credentials, so these never meet a business-file reference.
|
||||
const granted = new Set();
|
||||
for (const g of store.all('SELECT business, agent, host, rotate_by FROM host_grants ORDER BY business, agent, host')) {
|
||||
granted.add(g.business + '/' + g.agent + '/' + g.host);
|
||||
if (!Object.hasOwn(businesses, g.business)) continue;
|
||||
const refs = (references[g.business + '/' + g.agent] = { ...(references[g.business + '/' + g.agent] ?? {}) });
|
||||
refs['host.' + g.host] = hostReference(storeRoot, g.business, g.agent, g.host, g.rotate_by);
|
||||
}
|
||||
// Row 235 (r6 section 6, N1): a host.<id> key file with no record goes before Credentials loads.
|
||||
for (const entry of sweepHostKeys(storeRoot, Object.keys(businesses), granted))
|
||||
process.stderr.write(`hosts: ${JSON.stringify({ event: 'host-key-swept', ...entry })}\n`);
|
||||
// Row 236 (#1742, #436b r5 section 5): each gitea grant record gives its agent a store reference to
|
||||
// gitea, and `held` names the files memory must not load until reconcile or a revoke.
|
||||
const { held } = storeRoot ? giteaStart(store, storeRoot, businesses, references) : { held: [] };
|
||||
credentials = new Credentials({ references, repoRoots: protectedRoots, dataRoot, storeRoot, held,
|
||||
modelAgents: proxy ? Object.entries(businesses).flatMap(([id, b]) => Object.keys(b.roles).map(role => id + '/' + role)) : [] });
|
||||
if (proxy) {
|
||||
const inventory = modelRunInventory(dataRoot, modelRuns, credentials);
|
||||
modelKeys = new ModelKeys({ credentials, client: modelProxyClient, configDir: organization.dir,
|
||||
baseUrl: `http://127.0.0.1:${proxy.port}`, receipt: proxyReceipt, rotateGraceMinutes: proxy.rotateGraceMinutes ?? 120,
|
||||
runs: inventory.runs,
|
||||
stopRuns: async runs => {
|
||||
inventory.authorizeStop(runs);
|
||||
await stopModelRuns({ runs, sessions: () => readSessions(dataRoot), stop: run => stopSession(dataRoot, run, { timeoutMs: MODEL_STOP_TIMEOUT_MS }), receipt: proxyReceipt });
|
||||
for (const r of runs) {
|
||||
if (inventory.runs(r.instance).some(found => found.run === r.run)) throw new BusError('proxy-stop-failed');
|
||||
}
|
||||
for (const r of runs) modelRuns.delete(r.business + ':' + r.run);
|
||||
} });
|
||||
// Keep the control/human surface available, but refuse every launch on failed reconcile.
|
||||
try { await modelKeys.reconcile(); } catch (error) { proxyReceipt({ action: 'proxy.boot-refused', code: error.code }); }
|
||||
}
|
||||
const configureProxyPage = () => {
|
||||
proxyPage = new ProxyPage({ client: modelProxyClient, instanceTag: sha256(organization.dir).slice(0, 12),
|
||||
// P2 supplies the model metadata; only the matching business's record
|
||||
// participates in this owner view. No credential value is read here.
|
||||
keyRecords: business => credentials.status().filter(r => r.service === 'model' && r.instance?.startsWith(business + '/'))
|
||||
.map(r => ({ keyId: r.keyId, agent: r.instance.slice(business.length + 1), issuedAt: r.issuedAt, state: r.state })),
|
||||
});
|
||||
};
|
||||
if (modelProxyClient) configureProxyPage();
|
||||
|
||||
// vikunja:19/305: the plug-in switch through the same human-only path as the limits: the verbs
|
||||
// plugins and plugins.set, logged in changes.jsonl with the actor, a missing module refused.
|
||||
const plugins=organization?pluginSettings({dir:organization.dir,rolesDir:organization.rolesDir,exists:hasModule}):null;
|
||||
const levels=organization?await harnessLevels():()=>null;
|
||||
const settings=organization?launchSettings({...organization,sessions:()=>readSessions(dataRoot),levels}):null;
|
||||
// Row 194 (#1692, brief item 8, row 199 D13): a fire or a delete revokes the agent's credentials
|
||||
// after the writer's checks and before its write, under the writer's lock (row 239). Fire revokes
|
||||
// each service of the entry and keeps the store directory, delete calls remove (sage-1593). A
|
||||
// service the running bus doesn't know (an agent created since the start) has nothing in memory,
|
||||
// so it goes on, and then no token or tmp file may remain in the agent's store directory
|
||||
// (sage-1592). Any failure stops the verb with the file unchanged.
|
||||
const revokeFailed = (message) => new OrganizationError('credential-revoke-failed', message);
|
||||
function revoke(business, agent, how, services) {
|
||||
const instance = business + '/' + agent;
|
||||
const outside = [];
|
||||
try {
|
||||
if (how === 'delete' && storeRoot) credentials.remove(instance);
|
||||
else
|
||||
for (const service of services) {
|
||||
try {
|
||||
if (!credentials.revoke(instance, service).file) outside.push(service);
|
||||
} catch (e) {
|
||||
if (e.code !== 'credential-unknown') throw e;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
throw revokeFailed(`${agent}: ${e.code ?? 'credential-file'}`);
|
||||
}
|
||||
if (storeRoot) {
|
||||
let left = [];
|
||||
try {
|
||||
left = readdirSync(join(storeRoot, business, agent));
|
||||
} catch (e) {
|
||||
if (e.code !== 'ENOENT') throw revokeFailed(`${agent}: store directory can't be read`);
|
||||
}
|
||||
if (left.length > 0) throw revokeFailed(`${agent}: ${left.sort().join(' and ')} still in the store`);
|
||||
}
|
||||
// A file or env reference outside the store keeps its token for a restart (row 199 section 6).
|
||||
return { revoked: services, outsideStore: how === 'fire' ? outside : [] };
|
||||
}
|
||||
// Row 165 (#1662): the human adds and changes role instances through instances and instances.set.
|
||||
const proxyOrganization = modelKeys ? modelOrganization({ modelKeys, writer: organizationWriter({ dir: organization.dir, rolesDir: organization.rolesDir }) }) : null;
|
||||
const instances=organization?instanceSettings({dir:organization.dir,rolesDir:organization.rolesDir,system:organization.system,levels,revoke,
|
||||
...(proxyOrganization ? { writer: proxyOrganization.writer, revoke: proxyOrganization.revoke(revoke) } : {})}):null;
|
||||
const usageLog = entry => process.stderr.write(`usage: ${JSON.stringify(entry)}\n`);
|
||||
const keyForRun = (business, run) => modelRuns.get(business + ':' + run)?.keyId ?? null;
|
||||
const usage = await createUsage({ store, dataRoot, businesses, log: usageLog, keyForRun,
|
||||
proxyView: business => proxyUsage?.view(business) ?? null });
|
||||
proxyUsage = createProxyUsage({ store, log: usageLog, client: async () => {
|
||||
if (!modelKeys) return null;
|
||||
await modelKeys.verifyIdentity();
|
||||
return modelProxyClient;
|
||||
},
|
||||
records: () => credentials.status(),
|
||||
read: () => Object.fromEntries(Object.keys(businesses).map(id => [id, settings ? settings.current(id) : businesses[id]])) });
|
||||
// Row 125 (#1619, REQ-LIMIT-3, REQ-LIMIT-4): the limit checks read the organization file at
|
||||
// each ask, so a limit, a reset or a switched-on check takes effect without a restart.
|
||||
const limitLog = entry => process.stderr.write(`limits: ${JSON.stringify(entry)}\n`);
|
||||
const limits = createLimits({ store, read: id => settings ? settings.current(id) : businesses[id], log: limitLog,
|
||||
keyForSubject: (business, subject) => modelUsageKey(credentials.status(), modelRuns, business, subject) });
|
||||
for (const id of Object.keys(businesses)) await limits.refresh(id);
|
||||
const withTokens = (id, result) => ({ ...result, tokens: limits.report(id) });
|
||||
// Row 210 (#1707, design D7 step 6) and row 234 (#1740, r6 E2): the run dir and the host enrollment half.
|
||||
const runRoot = organization ? join(organization.dir, 'secrets', 'run') : null;
|
||||
let broker;
|
||||
processing = createProcessing({ dataRoot, ...discordProcessingHooks(dataRoot), containerStop: createContainerStopper({ dataRoot }),
|
||||
onTransition: () => broker.reconcileProcessing(),
|
||||
onStop: stop => broker.recordProcessingStop(stop),
|
||||
log: line => process.stderr.write(`${line}\n`),
|
||||
});
|
||||
// C2-04: mirrors are host state, never session checkouts. An unsafe
|
||||
// existing mirror refuses startup before a socket can become ready.
|
||||
for (const business of Object.values(businesses))
|
||||
for (const [project, entry] of Object.entries(business.projects ?? {}))
|
||||
if (entry.kind === 'library') {
|
||||
try { await processing.work(() => libraryModule.ensureMirror({ business, project, dataRoot })); }
|
||||
catch (e) { if (!e.code?.startsWith('processing-')) throw e; }
|
||||
}
|
||||
// C2-03a: the slot is <configDir>/secrets/<business>/library-gitea (design 10 step 4). Sync only
|
||||
// checks that it is there; the askpass helper reads it.
|
||||
// C2-03b: the broker chooses. The chief's grant store file once a chief has Gitea grant evidence,
|
||||
// the slot before that, or a refusal sync records. The answer carries no file to sync but this one.
|
||||
const slotDir = librarySync?.configDir ?? organization?.dir ?? null;
|
||||
const fetchCredential = business => {
|
||||
const choice = broker.libraryFetchCredential(business.id);
|
||||
if (choice.kind === 'chief')
|
||||
return { kind: 'chief', user: choice.user, file: storeRoot ? giteaReference(storeRoot, business.id, choice.agent).file : null };
|
||||
if (choice.kind === 'slot') return { kind: 'slot', file: slotDir ? join(slotDir, 'secrets', business.id, libraryModule.SLOT) : null };
|
||||
return { refused: choice.refused };
|
||||
};
|
||||
const syncOptions = business => ({
|
||||
credential: fetchCredential(business),
|
||||
...(librarySync ? { command: librarySync.command } : {}),
|
||||
});
|
||||
const humanWriteOptions = context => {
|
||||
const mapping = libraryModule.checkMapping(context.business.projects[context.project]);
|
||||
if (!mapping.editor) throw new libraryModule.LibraryError('library-mapping-invalid', 'editor is required');
|
||||
return { credential: libraryModule.humanCredential(context, { user: mapping.editor.user, configDir: slotDir }),
|
||||
...(librarySync ? { command: librarySync.command } : {}) };
|
||||
};
|
||||
// Row 194 (#1692, D3): after every write that commits, the broker takes the business as a restart
|
||||
// would load it. The credential references, the project roots the Credentials store protects
|
||||
// and the tracker bots are fixed at start (the Credentials store, the tasks adapter), so a file
|
||||
// whose references, roots or bots differ from the boot copy isn't reloaded, and the write
|
||||
// answers restart: true. Hire adds neither. A human create of a credentialed definition adds
|
||||
// references, so it answers restart: true, and issue works after the restart (brief item 7).
|
||||
// A role not in the boot copy matches only with no references and no bot. A reference compares
|
||||
// by its kind and path only: row 199's issue rewrites the date in the file outside this reload,
|
||||
// Credentials keeps its own copy of the date, and the broker never reads it.
|
||||
const fixedRef = ({ file, env, store }) => ({ file, env, store });
|
||||
const fixedRole = r => canonicalJson({
|
||||
credentials: Object.fromEntries(Object.entries(r?.credentials ?? {}).map(([service, ref]) => [service, fixedRef(ref)])),
|
||||
tracker: r?.tracker ?? null,
|
||||
});
|
||||
const fixedAtStart = b => ({
|
||||
roles: Object.fromEntries(Object.entries(b.roles).map(([role, r]) => [role, fixedRole(r)])),
|
||||
sync: canonicalJson(b.tracker?.sync ?? null),
|
||||
roots: canonicalJson(Object.values(b.projects ?? {}).filter(p => p.kind !== 'library').map(p => p.root).sort()),
|
||||
// A library entry has no root, and its mirror is ensured at start (C2-04), so each one is fixed whole.
|
||||
libraries: canonicalJson(Object.fromEntries(Object.entries(b.projects ?? {}).filter(([, p]) => p.kind === 'library'))),
|
||||
});
|
||||
const sameFixed = (boot, b) => fixedAtStart(b).sync === boot.sync && fixedAtStart(b).roots === boot.roots
|
||||
&& fixedAtStart(b).libraries === boot.libraries
|
||||
&& Object.entries(fixedAtStart(b).roles).every(([role, f]) => f === (boot.roles[role] ?? fixedRole(null)));
|
||||
const booted = new Map(Object.entries(businesses).map(([id, b]) => [id, fixedAtStart(b)]));
|
||||
const reloadLog = entry => process.stderr.write(`organization: ${JSON.stringify(entry)}\n`);
|
||||
function reload(id) {
|
||||
try {
|
||||
const b = loadBusiness(id, { dir: organization.dir, rolesDir: organization.rolesDir });
|
||||
const resolved = {};
|
||||
for (const instance of Object.keys(b.roles)) resolved[instance] = resolveInstance({ system: organization.system, business: b, instance });
|
||||
const next = busBusiness(b, resolved);
|
||||
if (!sameFixed(booted.get(id), next)) {
|
||||
reloadLog({ event: 'reload-needs-restart', business: id });
|
||||
return false;
|
||||
}
|
||||
broker.reloadBusiness(id, next);
|
||||
return true;
|
||||
} catch (e) {
|
||||
reloadLog({ event: 'reload-failed', business: id, message: e.message });
|
||||
return false;
|
||||
}
|
||||
}
|
||||
broker = new Broker({
|
||||
// FED R3: the access file is read per user request; a refusal leaves the user no grant.
|
||||
access: access ? () => loadAccess(access.file, access.context) : null,
|
||||
// FED R4 (#1801, design 3.7 trigger 1): a request stats the file and reads it only when this
|
||||
// changes. A failed stat is a stamp of its own, so a removed file reads (and refuses) once.
|
||||
accessStamp: access ? () => {
|
||||
try {
|
||||
const st = lstatSync(access.file, { bigint: true });
|
||||
return `${st.dev}:${st.ino}:${st.size}:${st.mtimeNs}:${st.ctimeNs}:${st.mode}:${st.uid}`;
|
||||
} catch (e) {
|
||||
return `unreadable:${e.code ?? 'error'}`;
|
||||
}
|
||||
} : null,
|
||||
// Row 270 (264c): session.list's compaction count, read from the session store's ledger.
|
||||
compactions: ({ business, thread, session, legacy }) => {
|
||||
const dir = storeDir(dataRoot, business, thread, session, { legacy });
|
||||
return dir ? compactionCount(dir) : { count: null, known: false, reason: 'store-unreadable', at: null };
|
||||
},
|
||||
hostGrant: runRoot ? hostGrant({ configDir: organization.dir, runRoot }) : null,
|
||||
// Row 235 (#1741, r6 X4, X5): the grant executor's claim, register and issue, never use().
|
||||
hostKeys: storeRoot ? grantKeys({ credentials, storeRoot }) : null,
|
||||
processing,
|
||||
// Row 236 (#1742): the Gitea grant path. The admin slot is <configDir>/secrets/grants/<business>/gitea.
|
||||
giteaGrant: organization ? giteaGrant({ configDir: organization.dir }) : null,
|
||||
giteaKeys: storeRoot ? giteaKeys({ credentials, storeRoot }) : null,
|
||||
usage,
|
||||
limits,
|
||||
store,
|
||||
businesses,
|
||||
library: {
|
||||
lookup: createLibraryLookup({ dataRoot, sync: context =>
|
||||
processing.work(() => libraryModule.sync(context, syncOptions(context.business))) }),
|
||||
log: entry => process.stderr.write(`library: ${JSON.stringify(entry)}\n`),
|
||||
readFile: context => libraryModule.readLibraryFile({ ...context, dataRoot }),
|
||||
status: context => libraryModule.libraryStatus({ ...context, dataRoot }),
|
||||
sync: (context, { accept }) => processing.work(() => libraryModule.sync({ ...context, dataRoot }, { ...syncOptions(context.business), accept })),
|
||||
// C2-02: trusted references only. The askpass helper alone opens a credential file.
|
||||
writeDoc: (context, options) => processing.work(() => libraryModule.writeLibraryDoc({ ...context, dataRoot }, {
|
||||
...options, credential: { ...options.credential,
|
||||
file: storeRoot ? giteaReference(storeRoot, context.business.id, options.credential.agent).file : null },
|
||||
...(librarySync ? { command: librarySync.command } : {}),
|
||||
})),
|
||||
saveFile: context => processing.work(() => libraryModule.saveLibraryFile({ ...context, dataRoot }, humanWriteOptions(context))),
|
||||
revert: context => processing.work(() => libraryModule.revertLibraryCommit({ ...context, dataRoot }, humanWriteOptions(context))),
|
||||
LibraryError: libraryModule.LibraryError,
|
||||
// C2-06: the citation guard, the reply limits read from the business file at each check (none
|
||||
// configured reads as unreadable, so requireCitation is true), and thread.messages' `last`.
|
||||
guard: (context, body, options) => libraryModule.guardReply({ ...context, dataRoot }, body, options),
|
||||
replyLimits: id => libraryModule.resolveReplyLimits(organization
|
||||
? organizationWriter({ dir: organization.dir, rolesDir: organization.rolesDir }).readRaw(id) : { readable: false }),
|
||||
last: (context, paths) => libraryModule.lastCommits({ ...context, dataRoot }, paths),
|
||||
GuardError: libraryModule.GuardError,
|
||||
},
|
||||
project: {
|
||||
readSpec: context => projectModule.readSpec({ ...context, dataRoot }),
|
||||
writeRecord: context => processing.work(() => projectModule.writeRecord({ ...context, dataRoot })),
|
||||
listFiles: context => projectModule.listProjectFiles({ ...context, dataRoot }),
|
||||
readFile: context => projectModule.readProjectFile({ ...context, dataRoot }),
|
||||
writeFile: context => projectModule.writeHumanFile({ ...context, dataRoot }),
|
||||
ProjectError: projectModule.ProjectError,
|
||||
},
|
||||
// limits and limits.set (organization.set is limits.set) carry each token limit's count; a
|
||||
// plugins.set reloads the business's limit checks in the background.
|
||||
organization:settings?(proxyOrganization?.wrap ?? (operation => operation))((id,verb,args,actor,context)=>{
|
||||
if(verb==='limits')return withTokens(id,settings.read(id));
|
||||
if(verb==='plugins')return plugins.read(id);
|
||||
// Row 256 (#1761): the actor is the reader, so endProtected is the delete check for that reader.
|
||||
if(verb==='instances')return instances.read(id,actor);
|
||||
// Row 65 (mos-0840): the Console's routing table.
|
||||
if(verb==='routes')return settings.routes(id);
|
||||
// Row 298 (#1804, Q228): the chief's grant scope as the file stands, the fallback shown.
|
||||
if(verb==='grants.scope')return instances.grantScopeRead(id);
|
||||
// Row 194 (#1692, V5): a delete's checks at the verb, with no write and no reload.
|
||||
if(verb==='instances.check')return instances.checkDelete(id,args.instance,actor);
|
||||
// Row 194 b6 (webby-0094 B1): a fire's checks against the file, before step A.
|
||||
if(verb==='instance.fireCheck')return instances.checkFire(id,args.name);
|
||||
// Internal read-only path: no reload, journal, credential or publication.
|
||||
if(verb==='instance.hireCheck')return instances.checkHire(id,args);
|
||||
let result;
|
||||
if(verb==='limits.set')result=withTokens(id,settings.set(id,args,actor));
|
||||
else if(verb==='instances.set')result=instances.set(id,args,actor);
|
||||
else if(verb==='routes.set')result=settings.setRoutes(id,args,actor);
|
||||
else if(verb==='plugins.set')result=plugins.set(id,args,actor);
|
||||
// Row 194 (#1692, V6): the human's keep and noHire lists, through the instance writer.
|
||||
else if(verb==='veto.set')result=instances.veto(id,args,actor);
|
||||
// Row 298: the human's grant scope, through the instance writer.
|
||||
else if(verb==='grants.scope.set')result=instances.grantScope(id,args,actor);
|
||||
// C2-06 M11: the human's replyLimits, through the organization writer's fence.
|
||||
else if(verb==='library.limits.set')result=setReplyLimits(organizationWriter({dir:organization.dir,rolesDir:organization.rolesDir}),id,args,actor);
|
||||
// Row 194 (D2.1, D2.2): the chief's hire and fire, with the reason in the change context.
|
||||
else if(verb==='instance.hire')result=instances.hire(id,args,{actor,context});
|
||||
else if(verb==='instance.fire')result=instances.fire(id,{name:args.name},{actor,context});
|
||||
else throw new BusError('invalid-request');
|
||||
// Row 194 (D3 item 2): one reload, after every verb that committed, then the limit checks.
|
||||
const live=reload(id);
|
||||
limits.refresh(id).catch(e=>limitLog({event:'limit-refresh-failed',business:id,message:e.message}));
|
||||
// Row 194 b6 (webby-0094 B1, sage-2241): every instance-writer verb says whether the reload
|
||||
// took, so a refused one (credentials, roots, ...) shows the restart line for a keep or a
|
||||
// hire too. The other writers' answers carry no restart field.
|
||||
return INSTANCE_VERBS.has(verb)?{...result,restart:!live}:result;
|
||||
}):null,
|
||||
// Row 194 (D2.3): the role files as they stand, for the hire checks.
|
||||
roleFile: organization ? (name) => loadRole(organization.rolesDir, name) : null,
|
||||
secretCheck: (value) => credentials.assertClean(value),
|
||||
credentialStatus: () => credentials.status(),
|
||||
// Row 199 (#1697, design section 6): issue, rotate, revoke and delete, live with no restart; each
|
||||
// rewrites or records through the organization writer, so changes.jsonl holds the receipt.
|
||||
proxyPage: async (verb, args, scope) => {
|
||||
if (!proxyPage) throw new BusError('not-configured');
|
||||
return proxyPage.request(verb, args, scope);
|
||||
},
|
||||
proxyInit: organization ? async args => {
|
||||
const settings = await initializeProxy({ configDir: organization.dir, dataRoot, ...args });
|
||||
modelProxyClient = await loadManagementClient({ configDir: organization.dir, proxy: settings, receipt: proxyReceipt });
|
||||
configureProxyPage();
|
||||
return settings;
|
||||
} : null,
|
||||
credentialVerbs: organization
|
||||
? credentialVerbs({ credentials, writer: organizationWriter({ dir: organization.dir, rolesDir: organization.rolesDir }) })
|
||||
: null,
|
||||
// Row 65: a new launch binds only on a harness its business switches on, read from the file
|
||||
// as it stands now; an unreadable file switches none on.
|
||||
harnessOn: (id, name) => {
|
||||
try {
|
||||
const b = settings ? settings.current(id) : businesses[id];
|
||||
return Array.isArray(b?.plugins?.harness) && b.plugins.harness.includes(name);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
// Row 298 (#1804, Q228): one read binds launch.grantScope to the organization revision.
|
||||
// A missing organization reader or unreadable file cannot authorize an automatic grant.
|
||||
grantScope: (id) => {
|
||||
if (!settings) return { value: undefined, revision: null };
|
||||
const { document, revision } = instances.writer.read(id);
|
||||
return { value: document.launch?.grantScope, revision };
|
||||
},
|
||||
// Row 194 (#1692, D4.1, B8): bus.tester as the file sets it now; an unreadable file is off.
|
||||
testerOn: (id) => {
|
||||
try {
|
||||
const b = settings ? settings.current(id) : businesses[id];
|
||||
return b?.vars?.['bus.tester'] === true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
});
|
||||
broker.reconcileProcessing();
|
||||
processing.start();
|
||||
const processingWork = () => {
|
||||
const state = processing.read();
|
||||
if (state.invalid) throw new BusError(state.code);
|
||||
if (state.halted) throw new BusError('processing-halted');
|
||||
};
|
||||
// Process identities must be supplied for every managed run when using the human transport.
|
||||
const launchRecords = [];
|
||||
function bindLaunch(r) {
|
||||
if (
|
||||
!Number.isSafeInteger(r.pid) ||
|
||||
r.pid < 2 ||
|
||||
typeof r.startTime !== 'string' ||
|
||||
!/^\d+$/.test(r.startTime)
|
||||
)
|
||||
throw new BusError('invalid-launch-process');
|
||||
const { modelKeyId, ...record } = r;
|
||||
if (modelKeys) {
|
||||
modelKeys.assertLaunchable(r.business + '/' + r.role);
|
||||
const m = credentials.modelRecord(r.business + '/' + r.role);
|
||||
if (!m || ![m.keyId, ...m.retiring.map(k => k.keyId)].includes(modelKeyId)) throw new BusError('proxy-key-refused');
|
||||
}
|
||||
const cap = broker.bindLaunch(record);
|
||||
launchRecords.push({ ...r });
|
||||
if (modelKeys) modelRuns.set(r.business + ':' + r.run, { ...r, instance: r.business + '/' + r.role, keyId: modelKeyId });
|
||||
return { business: r.business, run: r.run, cap };
|
||||
}
|
||||
const bound = launches.map(bindLaunch);
|
||||
const readCaps = readers.map((business) => ({ business, cap: broker.bindReader({ business }) }));
|
||||
if (tasks) {
|
||||
adapter = await tasks({ broker, credentials, businesses, processing });
|
||||
if (typeof adapter?.handle !== 'function' || !Number.isSafeInteger(adapter.timeout) || adapter.timeout < 1)
|
||||
throw new BusError('invalid-adapter');
|
||||
}
|
||||
const web = await webServices(businesses);
|
||||
// Row 210 (#1707, design D7 step 6): clear what a killed bus child left, before anyone can call.
|
||||
if (runRoot) sweepRunDir(runRoot);
|
||||
// Row 234 (r6 X3): end the enrollments a killed bus child left, before anyone can call.
|
||||
broker.reconcileGrants();
|
||||
const interpreter = inspectInterpreter();
|
||||
recordInterpreterStart(store.directory, interpreter);
|
||||
const peerReader = createPeerReader({ interpreter });
|
||||
const principalPaths = {
|
||||
human: fileURLToPath(new URL('./human-cli.mjs', import.meta.url)),
|
||||
tester: fileURLToPath(new URL('./tester-cli.mjs', import.meta.url)),
|
||||
user: fileURLToPath(new URL('./user-cli.mjs', import.meta.url)),
|
||||
console: fileURLToPath(new URL('../../webui/src/cli.mjs', import.meta.url)),
|
||||
consoleCli: fileURLToPath(new URL('./console-cli.mjs', import.meta.url)),
|
||||
};
|
||||
const path = join(store.directory, 'broker.sock');
|
||||
// The existing host executor owns SSH and its key lifecycle. Combine its revocation
|
||||
// signal with processing cancellation without changing its proof or credential entry points.
|
||||
const host = runRoot ? hostExecutor({ root: runRoot, credentials: {
|
||||
busy: (...args) => credentials.busy(...args),
|
||||
useFor: (session, name, fn, options) => credentials.useFor(session, name, (token, meta) =>
|
||||
fn(token, { ...meta, signal: meta.signal
|
||||
? AbortSignal.any([meta.signal, processing.signal()]) : processing.signal() }), options),
|
||||
} }) : null;
|
||||
server = await serve({
|
||||
web: (business) => web.get(business) ?? null,
|
||||
host: host ? { busy: (...args) => host.busy(...args),
|
||||
run: (...args) => processing.work(() => host.run(...args)) } : null,
|
||||
tasks: adapter ? { handle: adapter.handle, timeout: adapter.timeout } : null,
|
||||
broker,
|
||||
path,
|
||||
peerReader,
|
||||
authenticateHuman: (proof, peer) => {
|
||||
const p = verifyPrincipal({ human: proof }, { peer, paths: principalPaths, businesses, launches: launchRecords });
|
||||
return broker.bindHuman({ business: p.business, human: p.id, via: 'cli', outsideAgent: true });
|
||||
},
|
||||
authenticateTester: (proof, peer) => {
|
||||
const p = verifyPrincipal({ tester: proof }, { peer, paths: principalPaths, businesses, launches: launchRecords });
|
||||
return broker.bindTester({ business: p.business });
|
||||
},
|
||||
// FED R3 (design 3.6): checks 1 and 2 are row 196's user kind; check 3, the live grant, is bindUser's.
|
||||
authenticateUser: (proof, peer) => {
|
||||
const p = verifyPrincipal({ user: proof }, { peer, paths: principalPaths, businesses, launches: launchRecords });
|
||||
return broker.bindUser({ business: p.business, user: p.id });
|
||||
},
|
||||
// Row 252 (#1753): a fresh proof per connection, a cap for the Console verbs only.
|
||||
authenticateConsole: (proof, peer) => {
|
||||
const p = verifyPrincipal({ console: proof }, { peer, paths: principalPaths, businesses, launches: launchRecords, consoleOwners: owners });
|
||||
return broker.bindConsole({ business: p.business, human: p.id, subject: p.subject });
|
||||
},
|
||||
});
|
||||
// Row 235 (r6 X3): the remote undo of interrupted host grants, once the bus is up, so a start doesn't
|
||||
// wait on the network.
|
||||
broker.reconcileHosts();
|
||||
// Row 236 (#436b r5 section 5): the Gitea grants' remote undo, settle and open revokes, likewise.
|
||||
broker.reconcileGitea();
|
||||
// S6 launcher operations. The host decides capacity and the instance list; the broker
|
||||
// authorizes role.launch and keeps the evidence, refusals included.
|
||||
// A refusal is recorded against the caller, as request() records one.
|
||||
function refusing(cap, fn, subject = null) {
|
||||
try {
|
||||
return fn();
|
||||
} catch (e) {
|
||||
if (!(e instanceof BusError)) throw e;
|
||||
broker.refuse(cap, e.code, subject);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
const authorizeLaunch = (cap, instance) =>
|
||||
refusing(cap, () => broker.authorize(cap, 'role.launch', { target: instance }));
|
||||
// Row 93 (#1587): the host's git socket. A push is checked before the host takes the bundle
|
||||
// and recorded once the ref moved; a reviewer's fetch is checked against its review.requested.
|
||||
const checkPush = (cap, task_ref) => refusing(cap, () => broker.checkPush(cap, task_ref), task_ref);
|
||||
const reviewFetch = (cap, args) => refusing(cap, () => broker.reviewFetch(cap, args), args?.task_ref);
|
||||
// Row 137 (#1631): the git socket's land op. checkLand's refusal is the run's, like checkPush's.
|
||||
// A landing then ends in recordLand or landRefused under its ticket, which outlive the run's cap.
|
||||
const checkLand = (cap, args) => refusing(cap, () => broker.checkLand(cap, args), args?.task_ref);
|
||||
// Row 199 (#1697, design D9b): the git socket's publish op. checkPublish's refusal is the run's.
|
||||
// The gitea token is used only under the open ticket, keyed from the agent checkPublish checked,
|
||||
// and the op table returns no token. A publish then ends in recordPublish or publishRefused,
|
||||
// which files any refusal once, withGitea's included.
|
||||
const checkPublish = (cap, args) => refusing(cap, () => broker.checkPublish(cap, args), args?.task_ref);
|
||||
const withGitea = async (ticket, fn) => credentials.useFor(broker.publishSession(ticket), 'gitea', fn);
|
||||
// The push itself runs here, where the token is (D9 step 5), and the git socket's host polls
|
||||
// for its end: the host's op channel answers one op at a time within 10 s, and ls-remote and
|
||||
// push can take longer. Fork, user, source and dst all come from the ticket. A WorkingError's
|
||||
// code is the refusal; git's stderr stays here.
|
||||
const remotes = new Map();
|
||||
function publishPush(ticket) {
|
||||
if (remotes.has(ticket)) throw new BusError('publish-busy');
|
||||
const { business, project, fork, user, source, dst } = broker.publishTarget(ticket);
|
||||
const entry = { state: 'running' };
|
||||
remotes.set(ticket, entry);
|
||||
processing.work(() => withGitea(ticket, (token) =>
|
||||
publishRemote({ repo: workingRepo(dataRoot, business, project), fork, user, source, dst, token, tls: publishTls }).catch((e) => {
|
||||
throw e instanceof WorkingError ? new BusError(e.code) : e;
|
||||
}),
|
||||
)).then(
|
||||
(r) => Object.assign(entry, { state: 'pushed', ...r }),
|
||||
(e) => {
|
||||
// Not a refusal: the error's name and code only, never a message that could carry git's output.
|
||||
if (!(e instanceof BusError)) process.stderr.write(`bus: publish git-failed: ${JSON.stringify({ name: e?.name, code: e?.code })}\n`);
|
||||
Object.assign(entry, { state: 'refused', code: e instanceof BusError ? e.code : 'git-failed' });
|
||||
},
|
||||
).then(() => {
|
||||
if (entry.held) settle(ticket, entry, entry.held);
|
||||
});
|
||||
return { state: 'running' };
|
||||
}
|
||||
// Row 242 (#1748): the git socket gave up on a publish (publish-timeout) whose push it never
|
||||
// collected. Its publishRefused waits for the push: until that ends the ticket stays open, so
|
||||
// checkPublish refuses another publish on the decision with publish-busy (row 237). A push that
|
||||
// reached the fork is then recorded, which spends the decision; one that didn't is filed with
|
||||
// the socket's code. Either way the decision can't push a second ref.
|
||||
function settle(ticket, entry, code) {
|
||||
remotes.delete(ticket);
|
||||
try {
|
||||
if (entry.state === 'pushed') {
|
||||
try {
|
||||
broker.recordPublish(ticket, { ref: entry.ref, commit: entry.commit, previous: entry.previous });
|
||||
process.stderr.write(`bus: publish ${ticket}: pushed after the git socket refused ${code}; recorded\n`);
|
||||
return;
|
||||
} catch (e) {
|
||||
if (!(e instanceof BusError)) throw e;
|
||||
code = e.code;
|
||||
}
|
||||
}
|
||||
broker.publishRefused(ticket, { code });
|
||||
} catch (e) {
|
||||
process.stderr.write(`bus: publish ${ticket}: not settled: ${JSON.stringify({ name: e?.name, code: e?.code })}\n`);
|
||||
}
|
||||
}
|
||||
function publishRefused(ticket, args) {
|
||||
const entry = remotes.get(ticket);
|
||||
if (!entry) return broker.publishRefused(ticket, args);
|
||||
if (!/^[a-z-]{1,64}$/.test(args?.code ?? '')) throw new BusError('invalid-request');
|
||||
if (entry.state === 'running') entry.held = args.code;
|
||||
else settle(ticket, entry, args.code);
|
||||
return args.code;
|
||||
}
|
||||
function publishResult(ticket) {
|
||||
const entry = remotes.get(ticket);
|
||||
if (!entry) throw new BusError('publish-unknown');
|
||||
if (entry.state !== 'running') remotes.delete(ticket);
|
||||
return { ...entry };
|
||||
}
|
||||
// Metadata only (service, date, state); the token stays in Credentials.
|
||||
function credentialStatus(business, role) {
|
||||
return credentials
|
||||
.status()
|
||||
.filter((c) => c.instance === business + '/' + role)
|
||||
.map(({ service, date, state, keyId, issuedAt }) => ({ service, date, state, ...(service === 'model' ? { keyId, issuedAt } : {}) }));
|
||||
}
|
||||
// C2-03a: each library entry with a sync user fetches once at start, then every 60 s. A pass
|
||||
// still running skips the tick. Only codes are logged, never git's output.
|
||||
const timed = Object.values(businesses).flatMap(business => Object.entries(business.projects ?? {})
|
||||
.filter(([, entry]) => entry.kind === 'library' && Object.hasOwn(entry, 'user')).map(([project]) => ({ business, project })));
|
||||
const syncLog = entry => process.stderr.write(`library: ${JSON.stringify(entry)}\n`);
|
||||
const syncAll = async () => {
|
||||
for (const { business, project } of timed) {
|
||||
try {
|
||||
const { code } = await libraryModule.sync({ business, project, dataRoot }, syncOptions(business));
|
||||
if (code !== null) syncLog({ event: 'library-sync-held', business: business.id, project, code,
|
||||
...(code === 'library-fetch-no-grant' ? { fix: LIBRARY_FETCH_FIX } : {}) });
|
||||
} catch (e) {
|
||||
if (e?.code === 'library-sync-busy') continue;
|
||||
syncLog({ event: 'library-sync-refused', business: business.id, project,
|
||||
code: e instanceof libraryModule.LibraryError ? e.code : 'library-sync-failed' });
|
||||
}
|
||||
}
|
||||
};
|
||||
const tick = () => {
|
||||
const state = processing.read();
|
||||
if (!syncPass && !state.halted && !state.invalid)
|
||||
syncPass = processing.work(syncAll).catch(e => {
|
||||
if (!e.code?.startsWith('processing-')) syncLog({ event: 'library-sync-refused', code: 'library-sync-failed' });
|
||||
}).finally(() => { syncPass = null; });
|
||||
};
|
||||
if (timed.length) {
|
||||
tick();
|
||||
syncTimer = setInterval(tick, librarySync?.intervalMs ?? libraryModule.SYNC_INTERVAL_MS);
|
||||
syncTimer.unref();
|
||||
}
|
||||
const stopSync = async () => { clearInterval(syncTimer); syncTimer = null; await syncPass; };
|
||||
// FED R4 (#1801, design 3.7 trigger 2): every 30 s the broker re-reads the access file, so a hand
|
||||
// edit or an expiry with no request ends the lost runs within one period.
|
||||
if (access) {
|
||||
accessTimer = setInterval(() => {
|
||||
try {
|
||||
broker.accessSweep();
|
||||
} catch (e) {
|
||||
process.stderr.write(`access: ${JSON.stringify({ event: 'access-sweep-failed', code: e.code ?? 'error' })}\n`);
|
||||
}
|
||||
}, access.intervalMs ?? ACCESS_SWEEP_MS);
|
||||
accessTimer.unref();
|
||||
}
|
||||
if (modelKeys) {
|
||||
modelTimer = setInterval(() => {
|
||||
if (modelSweep) return;
|
||||
modelSweep = modelKeys.sweep().catch(error => proxyReceipt({ action: 'proxy.sweep-refused', code: error.code ?? 'proxy-key-issue-failed' })).finally(() => { modelSweep = null; });
|
||||
}, 1000);
|
||||
modelTimer.unref();
|
||||
}
|
||||
// One bounded queue read at a time. The service applies the configured
|
||||
// 1..59 second poll deadline; this tick only checks whether a read is due.
|
||||
usageTimer = setInterval(() => { proxyUsage.tick().catch(() => usageLog({ action: 'proxy.usage', code: 'proxy-usage-read-failed' })); }, 1000);
|
||||
usageTimer.unref();
|
||||
await proxyUsage.tick();
|
||||
return {
|
||||
broker,
|
||||
credentials,
|
||||
// P2 consumes this inside the bus only. No process IPC/verb returns it.
|
||||
get modelProxy() { return modelProxyClient; },
|
||||
path,
|
||||
bindLaunch,
|
||||
recoverLaunch: ({ modelKeyId, ...record }) => broker.recoverLaunch(record),
|
||||
endLaunch: (r) => { const out = broker.endLaunch(r); modelRuns.delete(r.business + ':' + r.run); return out; },
|
||||
modelPreflight: async ({ business, role }) => {
|
||||
const current = settings ? settings.current(business) : businesses[business];
|
||||
if (!Object.hasOwn(current?.roles ?? {}, role)) throw new BusError('unknown-role');
|
||||
return modelKeys ? modelKeys.preflight(business + '/' + role) : null;
|
||||
},
|
||||
modelStall: async ({ business, role, run, keyId }) => {
|
||||
const record = modelRuns.get(business + ':' + run);
|
||||
if (!record || record.role !== role || record.keyId !== keyId) throw new BusError('proxy-stop-failed');
|
||||
await stopModelRuns({ runs: [record], reason: 'proxy-stall', sessions: () => readSessions(dataRoot),
|
||||
stop: id => stopSession(dataRoot, id, { timeoutMs: MODEL_STOP_TIMEOUT_MS }), receipt: proxyReceipt });
|
||||
modelRuns.delete(business + ':' + run);
|
||||
return { stopped: true };
|
||||
},
|
||||
threadsState: (business) => broker.threadsState(business),
|
||||
threadIdle: (r) => broker.threadIdle(r),
|
||||
// Row 125 (#1619, REQ-LIMIT-4): the launcher asks the limit checks before every launch.
|
||||
mayLaunch: async ({ business, instance, provider, model, account = null }) => {
|
||||
processingWork();
|
||||
return limits.mayLaunch(business, { instance, provider, model, account });
|
||||
},
|
||||
identity: (cap) => broker.identity(cap),
|
||||
authorizeLaunch,
|
||||
checkPush,
|
||||
recordPush: (cap, push) => refusing(cap, () => broker.recordPush(cap, push), push?.task_ref),
|
||||
reviewFetch,
|
||||
checkLand,
|
||||
recordLand: (ticket, land) => broker.recordLand(ticket, land),
|
||||
landRefused: (ticket, args) => broker.landRefused(ticket, args),
|
||||
checkPublish,
|
||||
withGitea,
|
||||
publishPush,
|
||||
publishResult,
|
||||
recordPublish: (ticket, pushed) => broker.recordPublish(ticket, pushed),
|
||||
publishRefused,
|
||||
landHeld: (record) => broker.landHeld(record),
|
||||
// Row 156 (#1651): the launcher's landing pass.
|
||||
landHolders: (business) => broker.landHolders(business),
|
||||
landRelease: (r) => broker.landRelease(r),
|
||||
// Row 194 (#1692, D1.1): the launcher's lifecycle pass.
|
||||
lifecycleRequests: (business) => broker.lifecycleRequests(business),
|
||||
lifecycleTake: (r) => broker.lifecycleTake(r),
|
||||
lifecycleDelete: (r) => broker.lifecycleDelete(r),
|
||||
lifecycleDone: (r) => broker.lifecycleDone(r),
|
||||
// Row 271 (264d, #1776): the launcher's clear pass.
|
||||
sessionClears: (business) => broker.sessionClears(business),
|
||||
sessionClearExited: (r) => broker.sessionClearExited(r),
|
||||
sessionClearUncertain: (r) => broker.sessionClearUncertain(r),
|
||||
sessionClearRetire: (r) => broker.sessionClearRetire(r),
|
||||
sessionClearStart: (r) => broker.sessionClearStart(r),
|
||||
refuse: (cap, code, subject) => broker.refuse(cap, code, subject),
|
||||
credentialStatus,
|
||||
launches: bound,
|
||||
readers: readCaps,
|
||||
async close() {
|
||||
clearInterval(usageTimer);
|
||||
await proxyUsage.close();
|
||||
clearInterval(modelTimer);
|
||||
await modelSweep;
|
||||
clearInterval(accessTimer);
|
||||
await stopSync();
|
||||
await server.close();
|
||||
await adapter?.close?.();
|
||||
await processing?.close();
|
||||
store.close();
|
||||
credentials.close();
|
||||
},
|
||||
};
|
||||
} catch (e) {
|
||||
clearInterval(usageTimer);
|
||||
await proxyUsage?.close();
|
||||
clearInterval(modelTimer);
|
||||
clearInterval(accessTimer);
|
||||
await server?.close();
|
||||
await adapter?.close?.();
|
||||
await processing?.close();
|
||||
store?.close();
|
||||
credentials?.close();
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Static bytes/Git/diff only. Never imports product modules or runs tests."""
|
||||
from pathlib import Path
|
||||
import hashlib, json, subprocess, re, io, tarfile, gzip, tempfile, shutil
|
||||
ROOT=Path.cwd()
|
||||
OUT=ROOT/'agents/codex/work/queue-333/r1-repair/packet'
|
||||
OUT.mkdir(exist_ok=True)
|
||||
HEAD='503b91e56137482abef475bc3b1b72a64b0a329c'
|
||||
assert subprocess.check_output(['git','rev-parse','HEAD'],text=True).strip()==HEAD
|
||||
assert subprocess.check_output(['git','diff','--cached','--name-only'],text=True).strip()==''
|
||||
OBJECT_FORMAT=subprocess.check_output(['git','rev-parse','--show-object-format'],text=True).strip()
|
||||
assert OBJECT_FORMAT=='sha1'
|
||||
def digest(data): return hashlib.sha256(data).hexdigest()
|
||||
def blob(data): return hashlib.sha1(b'blob '+str(len(data)).encode()+b'\0'+data).hexdigest()
|
||||
def head_bytes(p):
|
||||
result=subprocess.run(['git','show',f'{HEAD}:{p}'],capture_output=True)
|
||||
return result.stdout if result.returncode==0 else None
|
||||
def jsonfile(name,value): (OUT/name).write_text(json.dumps(value,indent=2,sort_keys=True)+'\n')
|
||||
tracked=set(subprocess.check_output(['git','diff','--name-only',HEAD,'--','packages'],text=True).splitlines())
|
||||
untracked=set(subprocess.check_output(['git','ls-files','--others','--exclude-standard','--','packages'],text=True).splitlines())
|
||||
changed=sorted(tracked|untracked)
|
||||
CONTROLS=['packages/bus/tests/p5-identity.test.mjs','packages/bus/tests/p5-key-compatibility.test.mjs','packages/bus/tests/p5-background.test.mjs','packages/bus/tests/p5-telemetry-fixture.mjs']
|
||||
assert set(CONTROLS)<=untracked
|
||||
parts={}
|
||||
for p in changed:
|
||||
if p in tracked:
|
||||
part=subprocess.check_output(['git','diff','--binary','--full-index',HEAD,'--',p])
|
||||
else:
|
||||
result=subprocess.run(['git','diff','--no-index','--binary','--full-index','--','/dev/null',p],capture_output=True)
|
||||
assert result.returncode==1,(p,result.stderr)
|
||||
part=result.stdout
|
||||
assert part
|
||||
parts[p]=part
|
||||
(OUT/'source-tests.patch').write_bytes(b''.join(parts[p] for p in changed))
|
||||
(OUT/'baseline-controls.patch').write_bytes(b''.join(parts[p] for p in sorted(CONTROLS)))
|
||||
(OUT/'baseline-to-fixed.patch').write_bytes(b''.join(parts[p] for p in changed if p not in CONTROLS))
|
||||
jsonfile('changed-source-tests.json',[{'path':p,'bytes':(ROOT/p).stat().st_size,'sha256':digest((ROOT/p).read_bytes()),'git_blob':blob((ROOT/p).read_bytes()),'head_git_blob':blob(head_bytes(p)) if head_bytes(p) is not None else None} for p in changed])
|
||||
whole=(ROOT/'agents/codex/work/queue-333/r1-repair/whole-files.txt').read_text().splitlines()
|
||||
assert len(whole)==28 and len(set(whole))==28
|
||||
(OUT/'whole-files.txt').write_text('\n'.join(whole)+'\n')
|
||||
# Conservative static closure: old captured inputs + current controls/changed
|
||||
# files + all shipped selectable plug-ins/role data, literal module and URL edges.
|
||||
seed={line.split(' ',1)[1] for line in (ROOT/'agents/codex/work/queue-333/source-inputs.sha256').read_text().splitlines()}
|
||||
seed.update(whole);seed.update(changed)
|
||||
seed.update(str(p.relative_to(ROOT)) for p in (ROOT/'agents/codex/work/queue-333/r1-repair').glob('*') if p.is_file())
|
||||
seed.update(str(p.relative_to(ROOT)) for p in (ROOT/'packages/plugins').glob('*/*/index.mjs'))
|
||||
seed.update(str(p.relative_to(ROOT)) for p in (ROOT/'packages/plugins/src').glob('*.mjs'))
|
||||
seed.update(str(p.relative_to(ROOT)) for p in (ROOT/'roles').rglob('*') if p.is_file())
|
||||
for p in ['AGENTS.md','package.json','package-lock.json','RELEASE','docs/plans/2026-10-24_model-proxy-rows.md','docs/plans/2026-10-24_stack-model-proxy.md']:
|
||||
if (ROOT/p).is_file(): seed.add(p)
|
||||
patterns=[('module',re.compile(r'''\b(?:import|export)\s+(?:[^;'\"]*?\s+from\s*)?['\"]([^'\"]+)['\"]''')),
|
||||
('dynamic-literal',re.compile(r'''\bimport\s*\(\s*['\"]([^'\"]+)['\"]''')),
|
||||
('url-data',re.compile(r'''new\s+URL\s*\(\s*['\"]([^'\"]+)['\"]'''))]
|
||||
inputs=set();pending=list(seed);edges=[];external=[];selectors=[]
|
||||
while pending:
|
||||
p=pending.pop()
|
||||
if p in inputs: continue
|
||||
file=ROOT/p
|
||||
if not file.is_file(): continue
|
||||
inputs.add(p)
|
||||
if file.suffix not in {'.mjs','.js','.cjs'}:continue
|
||||
src=file.read_text()
|
||||
if re.search(r'\bimport\s*\(\s*(?![\'\"\s])',src) or 'pathToFileURL(' in src:
|
||||
selectors.append(p)
|
||||
for kind,pattern in patterns:
|
||||
for spec in pattern.findall(src):
|
||||
if not spec.startswith('.'):
|
||||
if kind!='url-data': external.append({'from':p,'specifier':spec,'kind':kind})
|
||||
continue
|
||||
resolved=(file.parent/spec).resolve()
|
||||
try: rel=str(resolved.relative_to(ROOT))
|
||||
except ValueError: continue
|
||||
if resolved.is_file():
|
||||
edges.append({'from':p,'to':rel,'specifier':spec,'kind':kind});pending.append(rel)
|
||||
parent=file.parent
|
||||
while parent==ROOT or ROOT in parent.parents:
|
||||
package=parent/'package.json'
|
||||
if package.is_file(): pending.append(str(package.relative_to(ROOT)));break
|
||||
parent=parent.parent
|
||||
fixed={p:(ROOT/p).read_bytes() for p in sorted(inputs)}
|
||||
baseline={}
|
||||
for p in sorted(inputs):
|
||||
before=fixed[p] if p in CONTROLS else head_bytes(p)
|
||||
if before is not None:baseline[p]=before
|
||||
|
||||
def manifest(values):
|
||||
return [{'path':p,'bytes':len(data),'sha256':digest(data),'git_blob':blob(data),'head_git_blob':blob(head_bytes(p)) if head_bytes(p) is not None else None} for p,data in values.items()]
|
||||
jsonfile('fixed-inputs.json',manifest(fixed));jsonfile('baseline-inputs.json',manifest(baseline))
|
||||
(OUT/'fixed-inputs.sha256').write_text(''.join(f'{digest(data)} {p}\n' for p,data in fixed.items()))
|
||||
(OUT/'baseline-inputs.sha256').write_text(''.join(f'{digest(data)} {p}\n' for p,data in baseline.items()))
|
||||
jsonfile('static-dependencies.json',{'provenance':'STATIC conservative input closure, NOT execution/consumed-source evidence','roots':whole,'literal_edges':sorted(edges,key=lambda e:(e['from'],e['to'],e['kind'])),'external_or_builtin_specifiers':sorted(external,key=lambda e:(e['from'],e['specifier'])),'nonliteral_selectors_require_actual_runner_capture':sorted(set(selectors)),'included_shipped_plugins_and_roles':True})
|
||||
def archive(name,values):
|
||||
with open(OUT/name,'wb') as raw:
|
||||
with gzip.GzipFile(filename='',mode='wb',fileobj=raw,mtime=0) as zipped:
|
||||
with tarfile.open(fileobj=zipped,mode='w') as tar:
|
||||
for p,data in values.items():
|
||||
info=tarfile.TarInfo(p);info.size=len(data);info.mode=0o644;info.mtime=0;info.uid=info.gid=0
|
||||
tar.addfile(info,io.BytesIO(data))
|
||||
archive('fixed-input-bytes.tar.gz',fixed);archive('baseline-input-bytes.tar.gz',baseline)
|
||||
# Verify archived bytes match both manifests; hashes/Git blob IDs are byte pins,
|
||||
# never claims that unexecuted modules or tests passed.
|
||||
for name,values in [('fixed-input-bytes.tar.gz',fixed),('baseline-input-bytes.tar.gz',baseline)]:
|
||||
with tarfile.open(OUT/name,'r:gz') as tar:
|
||||
assert set(tar.getnames())==set(values)
|
||||
for p,data in values.items(): assert tar.extractfile(p).read()==data
|
||||
# Original evidence must remain identical to the original Git candidate.
|
||||
original=ROOT/'agents/codex/work/queue-333'
|
||||
old_files=subprocess.check_output(['git','ls-tree','-r','--name-only',HEAD,'--',str(original.relative_to(ROOT))],text=True).splitlines()
|
||||
for p in old_files:
|
||||
assert (ROOT/p).read_bytes()==head_bytes(p),f'original evidence changed: {p}'
|
||||
# Base test prefixes are retained except the two explicitly authorized additive
|
||||
# registry inventory changes which already existed at503 and remain unchanged.
|
||||
base='09a847edaa25b609bac7728ff83f224708a29399'
|
||||
prefixes=[]
|
||||
for p in changed:
|
||||
if '/tests/' not in p:continue
|
||||
before=subprocess.run(['git','show',f'{base}:{p}'],capture_output=True)
|
||||
if before.returncode==0:
|
||||
retained=(ROOT/p).read_bytes().startswith(before.stdout)
|
||||
assert retained,p
|
||||
prefixes.append(p)
|
||||
jsonfile('preserved-base-test-prefixes.json',prefixes)
|
||||
# Static application check in disposable byte trees, never a product run or a
|
||||
# second Git worktree/branch. Verify both overlay routes reproduce exact bytes.
|
||||
tmp=Path(tempfile.mkdtemp(prefix='p5-static-overlay-'))
|
||||
try:
|
||||
archive_bytes=subprocess.check_output(['git','archive','--format=tar',HEAD,'--',*sorted(tracked)])
|
||||
direct=tmp/'direct';staged=tmp/'staged';direct.mkdir();staged.mkdir()
|
||||
for target in [direct,staged]:
|
||||
with tarfile.open(fileobj=io.BytesIO(archive_bytes),mode='r:') as tar:tar.extractall(target,filter='data')
|
||||
def apply(target,name):
|
||||
subprocess.run(['git','apply','--check',str(OUT/name)],cwd=target,check=True,capture_output=True)
|
||||
subprocess.run(['git','apply',str(OUT/name)],cwd=target,check=True,capture_output=True)
|
||||
apply(direct,'source-tests.patch')
|
||||
apply(staged,'baseline-controls.patch')
|
||||
for path in tracked:assert (staged/path).read_bytes()==head_bytes(path)
|
||||
apply(staged,'baseline-to-fixed.patch')
|
||||
for path in changed:
|
||||
assert (direct/path).read_bytes()==(ROOT/path).read_bytes()
|
||||
assert (staged/path).read_bytes()==(ROOT/path).read_bytes()
|
||||
jsonfile('static-overlay-check.json',{'status':'byte-application-verified-no-product-execution','source_patch_equals_controls_then_remainder':True,'changed_package_files':len(changed),'temporary_trees_removed':True})
|
||||
finally:shutil.rmtree(tmp)
|
||||
assert not tmp.exists()
|
||||
review=ROOT/'agents/codex/work/queue-333/r1-repair/REVIEW-R1.md'
|
||||
assert digest(review.read_bytes())=='7c95672a30c0d5c39189c7c7d610ada89cd539dcb9413617071fbb81200fd008'
|
||||
evidence={str(p.relative_to(ROOT)):p.read_bytes() for p in sorted((ROOT/'agents/codex/work/queue-333/r1-repair/receipts').iterdir()) if p.is_file()}
|
||||
evidence.update({str(review.relative_to(ROOT)):review.read_bytes()})
|
||||
for p in sorted((ROOT/'agents/codex/work/queue-333/r1-repair/baselines').iterdir()):
|
||||
if p.is_file():evidence[str(p.relative_to(ROOT))]=p.read_bytes()
|
||||
jsonfile('r1-raw-evidence.json',manifest(evidence))
|
||||
archive('r1-raw-evidence-bytes.tar.gz',evidence)
|
||||
index={'status':'UNCOMMITTED_STATIC_PACKET_EXECUTION_PENDING','head':HEAD,'original_base':base,'review_sha256':'7c95672a30c0d5c39189c7c7d610ada89cd539dcb9413617071fbb81200fd008','changed_package_files':len(changed),'whole_test_files':len(whole),'fixed_static_input_files':len(fixed),'baseline_static_input_files':len(baseline),'git_object_format':OBJECT_FORMAT,'files':{p.name:{'bytes':p.stat().st_size,'sha256':digest(p.read_bytes())} for p in sorted(OUT.iterdir()) if p.is_file() and p.name not in {'INDEX.json','packet.sha256'}}}
|
||||
jsonfile('INDEX.json',index)
|
||||
(OUT/'packet.sha256').write_text(''.join(f'{digest(p.read_bytes())} {p.name}\n' for p in sorted(OUT.iterdir()) if p.is_file() and p.name!='packet.sha256'))
|
||||
print(json.dumps({k:index[k] for k in ['status','head','changed_package_files','whole_test_files','fixed_static_input_files','baseline_static_input_files']},sort_keys=True))
|
||||
print('source-tests.patch SHA256 '+digest((OUT/'source-tests.patch').read_bytes()))
|
||||
print('INDEX.json SHA256 '+digest((OUT/'INDEX.json').read_bytes()))
|
||||
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"baseline_static_input_files": 301,
|
||||
"changed_package_files": 18,
|
||||
"files": {
|
||||
"baseline-controls.patch": {
|
||||
"bytes": 19496,
|
||||
"sha256": "9b64bfe45f20f59ae62812529c5f4ef4a41f29ea9124cf42dd6e9c32f5089711"
|
||||
},
|
||||
"baseline-input-bytes.tar.gz": {
|
||||
"bytes": 793317,
|
||||
"sha256": "add6f177692f774a0a4370c95d28d3e72a3aa4e76adab886ed6bdcc01a965e2b"
|
||||
},
|
||||
"baseline-inputs.json": {
|
||||
"bytes": 84849,
|
||||
"sha256": "9f18698d9b327c8664461decf939e7fcbb6a756e81f93e88dc1d2d51511a7ea8"
|
||||
},
|
||||
"baseline-inputs.sha256": {
|
||||
"bytes": 29893,
|
||||
"sha256": "a287f6218039b825bb84c5902d68f0659cbedc9c89d5c2cff6e63fd0a64dfeed"
|
||||
},
|
||||
"baseline-to-fixed.patch": {
|
||||
"bytes": 21127,
|
||||
"sha256": "f3808e3a13fc9244f2301a8f6237fd07d5ed62f496765ef6c281f245713b7e68"
|
||||
},
|
||||
"changed-source-tests.json": {
|
||||
"bytes": 5017,
|
||||
"sha256": "42f770fc3e2384362efd1e416091355c064b6cca22dd40f3b5ef8f7b67e43a52"
|
||||
},
|
||||
"fixed-input-bytes.tar.gz": {
|
||||
"bytes": 811710,
|
||||
"sha256": "ce03510187334794f10c57b3ce022cbb31fb0324a50e9a225a1c8bb9a06540c4"
|
||||
},
|
||||
"fixed-inputs.json": {
|
||||
"bytes": 87745,
|
||||
"sha256": "505c022b46d0871d979c1dc9455a5d0a34ba5442fdeb5bc6195509e56a06b3b2"
|
||||
},
|
||||
"fixed-inputs.sha256": {
|
||||
"bytes": 31194,
|
||||
"sha256": "8f47fbe78ca155f2bc45f5c76e0cc2204af655b5485fc4bb55db5b21f2f7095f"
|
||||
},
|
||||
"preserved-base-test-prefixes.json": {
|
||||
"bytes": 98,
|
||||
"sha256": "fcbb8633c9cf0bdee9aeb1bfa8026c868c880cdbeea5369fa35928a9e87daacb"
|
||||
},
|
||||
"r1-raw-evidence-bytes.tar.gz": {
|
||||
"bytes": 27138,
|
||||
"sha256": "e7edd87316c9617caf2d30f7f8fc2ef38a6e918a781173bd40b251a81f878f6d"
|
||||
},
|
||||
"r1-raw-evidence.json": {
|
||||
"bytes": 2825,
|
||||
"sha256": "e2d81fd97a93d13805fe009428dcab77cafd2e99f6f9330b8ae08bc56af06306"
|
||||
},
|
||||
"source-tests.patch": {
|
||||
"bytes": 40623,
|
||||
"sha256": "a78bc385801b64be270fb9d6e84672c443738a5fce8eb68f7d2a01359a57a770"
|
||||
},
|
||||
"static-dependencies.json": {
|
||||
"bytes": 168863,
|
||||
"sha256": "3a1878a64719ad3c733c4e6a7b3fee091fb97be5591e126a6d2cb971262fc8b1"
|
||||
},
|
||||
"static-overlay-check.json": {
|
||||
"bytes": 186,
|
||||
"sha256": "521a779bb862349c137bd3cce0e319e7565c80657c437cc794bf3f9848689319"
|
||||
},
|
||||
"whole-files.txt": {
|
||||
"bytes": 1217,
|
||||
"sha256": "c32f33ebc78f09a0549b0b0ba185771bf1cdb3149e9579204147f4b827a66a56"
|
||||
}
|
||||
},
|
||||
"fixed_static_input_files": 312,
|
||||
"git_object_format": "sha1",
|
||||
"head": "503b91e56137482abef475bc3b1b72a64b0a329c",
|
||||
"original_base": "09a847edaa25b609bac7728ff83f224708a29399",
|
||||
"review_sha256": "7c95672a30c0d5c39189c7c7d610ada89cd539dcb9413617071fbb81200fd008",
|
||||
"status": "UNCOMMITTED_STATIC_PACKET_EXECUTION_PENDING",
|
||||
"whole_test_files": 28
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
diff --git a/packages/bus/tests/p5-background.test.mjs b/packages/bus/tests/p5-background.test.mjs
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..bb51ad3527280f0db0449c27eb42474dd8b9e894
|
||||
--- /dev/null
|
||||
+++ b/packages/bus/tests/p5-background.test.mjs
|
||||
@@ -0,0 +1,51 @@
|
||||
+// Prepared after Mos1971 STOP. These controls have NOT been executed locally.
|
||||
+// Only fake loopback HTTP, explicit event barriers and virtual existing timers.
|
||||
+import test from 'node:test';
|
||||
+import assert from 'node:assert/strict';
|
||||
+import { createHash } from 'node:crypto';
|
||||
+import { mkdirSync, writeFileSync } from 'node:fs';
|
||||
+import { join } from 'node:path';
|
||||
+import { startTimeOf } from '../../seat/src/proc.mjs';
|
||||
+import { telemetryFixture } from './p5-telemetry-fixture.mjs';
|
||||
+async function nativeTurn(f) {
|
||||
+ const model=await f.bus.modelPreflight({business:'demo',role:'coder'});
|
||||
+ const keyId=createHash('sha256').update(model.key).digest('hex').slice(0,12),dir=join(f.root,'native-transcript');mkdirSync(dir);
|
||||
+ const {cap}=f.bus.bindLaunch({business:'demo',role:'coder',run:'held-poll-native',harness:'pi',modelKeyId:keyId,transcript:dir,
|
||||
+ pid:process.pid,startTime:startTimeOf(process.pid)});
|
||||
+ f.bus.broker.request(cap,{verb:'role.claim'});
|
||||
+ assert.deepEqual(await f.bus.mayLaunch({business:'demo',instance:'coder',provider:'fixture',model:'fake'}),{allow:true});
|
||||
+ const human=f.human(),{id}=f.bus.broker.request(human,{verb:'message.send',args:{to:'coder',body:'native work while optional queue is held'}});
|
||||
+ f.bus.broker.request(cap,{verb:'message.receive'});
|
||||
+ await f.bus.broker.request(cap,{verb:'usage.begin',args:{turn:id}});
|
||||
+ writeFileSync(join(dir,'native.jsonl'),JSON.stringify({type:'message',id:'native',message:{role:'assistant',usage:{input:2,output:1,cacheRead:0,cacheWrite:0}}})+'\n');
|
||||
+ await f.bus.broker.request(cap,{verb:'usage.end',args:{turn:id}});
|
||||
+ const view=f.bus.broker.request(human,{verb:'usage'});
|
||||
+ assert.equal(view.total.input,2);assert.equal(view.byKey[0].modelKeyId,keyId);
|
||||
+ assert.deepEqual(f.bus.broker.request(cap,{verb:'message.receive'}),[]);
|
||||
+}
|
||||
+for(const fail of [false,true])test(`P5 R1 held first optional poll does not delay native startup or work; ${fail?'failure':'release'} settles safely`,async t=>{
|
||||
+ t.mock.timers.enable({apis:['Date','setInterval'],now:Date.now()});
|
||||
+ const f=await telemetryFixture(t,{hold:true});const started=f.start();
|
||||
+ await f.waitQueue(1);await new Promise(setImmediate);
|
||||
+ // Causal first guard: the queue is still held, so a ready runtime cannot
|
||||
+ // have depended on its response. No racing timeout or longer budget.
|
||||
+ assert.notEqual(f.bus,null,'startBroker must resolve while the first queue response is held');
|
||||
+ await started;assert.equal(f.state.held.length,1);
|
||||
+ assert.equal(f.bus.broker.request(f.human(),{verb:'plugins'}).plugins.usage,'cliproxy-queue');
|
||||
+ await nativeTurn(f);assert.equal(f.queueCalls(),1);
|
||||
+ t.mock.timers.tick(1000);await new Promise(setImmediate);assert.equal(f.queueCalls(),1,'scheduled ticks share the held first read');
|
||||
+ const from=f.logs.length;f.release(fail);
|
||||
+ await f.waitLog(fail?'proxy-usage-read-failed':'proxy.usage.reconcile',from);
|
||||
+ assert.equal(f.bus.broker.request(f.human(),{verb:'usage'}).proxy.state,fail?'unavailable':'available');
|
||||
+ await f.close();assert.equal(f.queueCalls(),1);
|
||||
+});
|
||||
+test('P5 R1 close bounds an outstanding first poll by the unchanged five-second client deadline',async t=>{
|
||||
+ t.mock.timers.enable({apis:['Date','setInterval','setTimeout'],now:Date.now()});
|
||||
+ const f=await telemetryFixture(t,{hold:true});const started=f.start();await f.waitQueue(1);await new Promise(setImmediate);
|
||||
+ assert.notEqual(f.bus,null,'native readiness precedes the held optional poll');await started;
|
||||
+ let closed=false;const closing=f.close().then(()=>{closed=true;});
|
||||
+ t.mock.timers.tick(4999);await new Promise(setImmediate);assert.equal(closed,false);
|
||||
+ t.mock.timers.tick(1);await closing;
|
||||
+ assert.equal(closed,true);assert.equal(f.queueCalls(),1);
|
||||
+ assert.ok(f.logs.some(line=>line.includes('proxy-usage-read-failed')));
|
||||
+});
|
||||
diff --git a/packages/bus/tests/p5-identity.test.mjs b/packages/bus/tests/p5-identity.test.mjs
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..4ee111f7c9ec75dbae24c184c3310b71973fc7c2
|
||||
--- /dev/null
|
||||
+++ b/packages/bus/tests/p5-identity.test.mjs
|
||||
@@ -0,0 +1,38 @@
|
||||
+import test from 'node:test';
|
||||
+import assert from 'node:assert/strict';
|
||||
+import { telemetryFixture } from './p5-telemetry-fixture.mjs';
|
||||
+for(const foreign of [true,false])test(`P5 R1 boot identity ${foreign?'refusal prevents queue consumption':'matching sentinel permits telemetry without an agent key'}`,async t=>{
|
||||
+ t.mock.timers.enable({apis:['Date','setInterval'],now:Date.now()});
|
||||
+ const f=await telemetryFixture(t,{foreign});await f.start();await f.settleInitial();
|
||||
+ const human=f.human();assert.equal(f.bus.broker.request(human,{verb:'plugins'}).plugins.usage,'cliproxy-queue');
|
||||
+ if(foreign){
|
||||
+ await assert.rejects(f.bus.modelPreflight({business:'demo',role:'coder'}),{code:'proxy-open'});
|
||||
+ assert.equal(f.queueCalls(),0);assert.equal(f.state.queued.length,1);
|
||||
+ await f.pollSettledAfterTick(t);assert.equal(f.queueCalls(),0);assert.equal(f.state.queued.length,1);
|
||||
+ assert.equal(f.bus.broker.request(human,{verb:'usage'}).proxy.state,'unavailable');
|
||||
+ }else{
|
||||
+ assert.equal(f.queueCalls(),1);assert.equal(f.state.queued.length,0);
|
||||
+ assert.equal(f.bus.broker.request(human,{verb:'usage'}).proxy.state,'available');
|
||||
+ assert.equal(f.bus.credentials.status().some(r=>r.service==='model'&&r.keyId),false);
|
||||
+ }
|
||||
+});
|
||||
+test('P5 R1 later sentinel refusal fences every subsequent queue poll while preserving human control',async t=>{
|
||||
+ t.mock.timers.enable({apis:['Date','setInterval'],now:Date.now()});
|
||||
+ const f=await telemetryFixture(t);await f.start();await f.settleInitial();assert.equal(f.queueCalls(),1);
|
||||
+ f.state.keys=[f.other];
|
||||
+ await assert.rejects(f.bus.modelPreflight({business:'demo',role:'coder'}),{code:'proxy-open'});
|
||||
+ await f.pollSettledAfterTick(t);assert.equal(f.queueCalls(),1);
|
||||
+ await f.pollSettledAfterTick(t);assert.equal(f.queueCalls(),1);
|
||||
+ const human=f.human();assert.equal(f.bus.broker.request(human,{verb:'plugins'}).plugins.usage,'cliproxy-queue');
|
||||
+ assert.equal(f.bus.broker.request(human,{verb:'usage'}).proxy.state,'unavailable');
|
||||
+});
|
||||
+
|
||||
+test('P5 R1 every drain verifies fresh sentinel before consuming a changed listener',async t=>{
|
||||
+ t.mock.timers.enable({apis:['Date','setInterval'],now:Date.now()});
|
||||
+ const f=await telemetryFixture(t);await f.start();await f.settleInitial();assert.equal(f.queueCalls(),1);
|
||||
+ f.state.keys=[f.other];await f.pollSettledAfterTick(t);assert.equal(f.queueCalls(),1);
|
||||
+ await assert.rejects(f.bus.modelPreflight({business:'demo',role:'coder'}),{code:'proxy-open'});
|
||||
+ const lists=f.state.calls.filter(p=>p==='/v8/management/config/access/api-keys').length;
|
||||
+ f.state.keys=[f.own];await f.pollSettledAfterTick(t);assert.equal(f.queueCalls(),1);
|
||||
+ assert.equal(f.state.calls.filter(p=>p==='/v8/management/config/access/api-keys').length,lists,'no retry around sticky identity refusal');
|
||||
+});
|
||||
diff --git a/packages/bus/tests/p5-key-compatibility.test.mjs b/packages/bus/tests/p5-key-compatibility.test.mjs
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..331032ecb48644587057a9ec4799e69d5fa3cdc8
|
||||
--- /dev/null
|
||||
+++ b/packages/bus/tests/p5-key-compatibility.test.mjs
|
||||
@@ -0,0 +1,68 @@
|
||||
+import test from 'node:test';
|
||||
+import assert from 'node:assert/strict';
|
||||
+import { mkdtempSync, rmSync, readFileSync } from 'node:fs';
|
||||
+import { tmpdir } from 'node:os';
|
||||
+import { join } from 'node:path';
|
||||
+import { Store } from '../src/store.mjs';
|
||||
+import { createLimits, modelUsageKey } from '../src/limits.mjs';
|
||||
+import * as token from '../../plugins/limit-check/token-limit/index.mjs';
|
||||
+import * as daily from '../../plugins/limit-check/daily-quota/index.mjs';
|
||||
+import { launchSettings } from '../../business/src/launch-settings.mjs';
|
||||
+import { businessDoc, rolesCopy, writeJson, systemFor } from '../../business/tests/helpers.mjs';
|
||||
+const key='abcdefabcdef',other='012345abcdef',since='2026-01-01T00:00:00.000Z';
|
||||
+const quota={limit:10,since,reset:'00:00',timeZone:'UTC'};
|
||||
+const native={at:'2026-10-26T12:00:00.000Z',run:'legacy-run',turn:'turn',account:key,modelKeyId:other,status:'known',input:10,output:0,cacheWrite:0,cacheRead:0};
|
||||
+test('P5 R1 plain twelve-hex account leaves retain matching and original account report even with another model ID',()=>{
|
||||
+ const a={limits:{tokens:{keys:{[key]:{limit:10,since}}}},subject:{account:key,modelKeyId:other},records:[native]};
|
||||
+ assert.equal(token.mayLaunch(a).allow,false);assert.equal(token.mustStop(a).stop,true);
|
||||
+ assert.equal(token.report(a)[0].count,10);assert.deepEqual(token.report(a)[0].path,['tokens','keys',key]);
|
||||
+ assert.equal(token.mayLaunch({...a,records:[{...native,input:9}]}).allow,true);
|
||||
+ assert.deepEqual(daily.report({...a,now:native.at}),[]);
|
||||
+});
|
||||
+for(const proxy of [false,true])test(`P5 R1 legacy account core lookup stays independent of ${proxy?'unrelated proxy metadata':'missing proxy metadata'}`,async t=>{
|
||||
+ const root=mkdtempSync(join(tmpdir(),'p5-legacy-')),store=new Store(root);t.after(()=>{store.close();rmSync(root,{recursive:true,force:true});});
|
||||
+ let lookups=0;
|
||||
+ const b={launch:{account:{name:key,credential:'FAKE_TOKEN_NAME'},limits:{tokens:{keys:{[key]:{limit:10,since}}}}},plugins:{'limit-check':['token-limit']}};
|
||||
+ const limits=createLimits({store,read:()=>b,log:()=>{},keyForSubject:(...args)=>{lookups++;return proxy?modelUsageKey([{service:'model',instance:'demo/coder',keyId:other,retiring:[]}],new Map(),'demo',args[1]):null;}});
|
||||
+ assert.deepEqual(await limits.mayLaunch('demo',{instance:'coder',account:key}),{allow:true});
|
||||
+ store.run(`INSERT INTO usage_records(at,business,run,instance,account,turn,source,phase,status,cursor,input,output,cache_write,cache_read)
|
||||
+ VALUES (?,'demo','legacy-run','coder',?,'turn','transcript','end','known',?,10,0,0,0)`,native.at,key,JSON.stringify({modelKeyId:other}));
|
||||
+ const hit={path:['tokens','keys',key],limit:10,count:10,unknownTurns:0};
|
||||
+ assert.deepEqual(await limits.mayLaunch('demo',{instance:'coder',account:key}),{allow:false,check:'token-limit',hit});
|
||||
+ assert.deepEqual(await limits.mustStop('demo',{instance:'coder',account:key}),{stop:true,check:'token-limit',hit});
|
||||
+ assert.equal(limits.report('demo')[0].count,10);assert.equal(lookups,0);
|
||||
+});
|
||||
+for(const leaf of [{limit:0,since},quota])test(`P5 R1 empty checks bypass model metadata for ${leaf.reset?'daily model':'legacy hex account'} leaves`,async t=>{
|
||||
+ const root=mkdtempSync(join(tmpdir(),'p5-no-checks-')),store=new Store(root);t.after(()=>{store.close();rmSync(root,{recursive:true,force:true});});
|
||||
+ let lookups=0;const limits=createLimits({store,read:()=>({plugins:{'limit-check':[]},launch:{limits:{tokens:{keys:{[key]:leaf}}}}}),log:()=>{},keyForSubject:()=>{lookups++;throw Error('MUST-NOT-LOOK-UP');}});
|
||||
+ assert.deepEqual(await limits.mayLaunch('demo',{instance:'coder',account:key}),{allow:true});
|
||||
+ assert.deepEqual(await limits.mustStop('demo',{instance:'coder',account:key}),{stop:false});assert.equal(lookups,0);
|
||||
+});
|
||||
+test('P5 R1 legacy hex account chief resets stay allowed; daily model old/new/removal/reset transitions stay human-only',t=>{
|
||||
+ const root=mkdtempSync(join(tmpdir(),'p5-fence-'));t.after(()=>rmSync(root,{recursive:true,force:true}));
|
||||
+ const rolesDir=rolesCopy(root),doc=businessDoc(root,'demo'),file=join(root,'businesses/demo.json');
|
||||
+ doc.launch.account={name:key,credential:'FAKE_TOKEN_NAME'};doc.launch.limits={tokens:{keys:{[key]:{limit:10,since}}}};writeJson(file,doc);
|
||||
+ let now='2026-10-26T12:00:00.000Z';const settings=launchSettings({dir:root,rolesDir,system:systemFor(root),now:()=>now});let v=settings.read('demo');
|
||||
+ v=settings.set('demo',{revision:v.revision,reset:[['tokens','keys',key]]},'chief');
|
||||
+ assert.equal(JSON.parse(readFileSync(file,'utf8')).launch.limits.tokens.keys[key].since,now);
|
||||
+ const dailyLeaf={limit:10,reset:'00:00',timeZone:'UTC'};
|
||||
+ assert.throws(()=>settings.set('demo',{revision:v.revision,limits:{tokens:{keys:{[key]:dailyLeaf}}}},'chief'),{code:'organization-model-quota-human-only'});
|
||||
+ v=settings.set('demo',{revision:v.revision,limits:{tokens:{keys:{[key]:dailyLeaf}}}},'jason');now='2026-10-26T13:00:00.000Z';
|
||||
+ for(const args of [{reset:[['tokens','keys',key]]},{limits:{}},{limits:{tokens:{keys:{[key]:{limit:10}}}}}])
|
||||
+ assert.throws(()=>settings.set('demo',{revision:v.revision,...args},'chief'),{code:'organization-model-quota-human-only'});
|
||||
+ v=settings.set('demo',{revision:v.revision,limits:{tokens:{keys:{[key]:{limit:10}}}}},'jason');
|
||||
+ v=settings.set('demo',{revision:v.revision,reset:[['tokens','keys',key]]},'chief');
|
||||
+ assert.equal(JSON.parse(readFileSync(file,'utf8')).launch.limits.tokens.keys[key].since,now);
|
||||
+});
|
||||
+
|
||||
+test('P5 R1 daily model matching/report is separate from legacy account and schema refuses partial or invalid daily shapes',async()=>{
|
||||
+ const {checkTokenLimits}=await import('../../business/src/launch.mjs');
|
||||
+ assert.deepEqual(checkTokenLimits({keys:{[key]:quota}}).keys[key],quota);
|
||||
+ const args={limits:{tokens:{keys:{[key]:quota}}},records:[native],subject:{account:key,modelKeyId:other},now:native.at};
|
||||
+ assert.deepEqual(token.report(args),[]);
|
||||
+ assert.equal(daily.mayLaunch(args).allow,true);assert.equal(daily.report(args)[0].count,0);
|
||||
+ const owned={...args,subject:{account:'other-account',modelKeyId:key},records:[{...native,account:'other-account',modelKeyId:key}]};
|
||||
+ assert.equal(daily.mayLaunch(owned).allow,false);assert.equal(daily.mustStop(owned).stop,true);assert.equal(daily.report(owned)[0].count,10);
|
||||
+ for(const leaf of [{...quota,reset:'25:00'},{...quota,timeZone:'Mars/Phobos'},{limit:10,since,reset:'00:00'},{limit:10,since,timeZone:'UTC'}])
|
||||
+ assert.throws(()=>checkTokenLimits({keys:{[key]:leaf}}));
|
||||
+});
|
||||
diff --git a/packages/bus/tests/p5-telemetry-fixture.mjs b/packages/bus/tests/p5-telemetry-fixture.mjs
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..99390f7d565a7d7db5344b574bc5a8623d5fa073
|
||||
--- /dev/null
|
||||
+++ b/packages/bus/tests/p5-telemetry-fixture.mjs
|
||||
@@ -0,0 +1,66 @@
|
||||
+// Fresh, made-up instance and local management listener only; no worker/provider.
|
||||
+import http from 'node:http';
|
||||
+import { createHash, randomBytes } from 'node:crypto';
|
||||
+import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'node:fs';
|
||||
+import { tmpdir } from 'node:os';
|
||||
+import { join } from 'node:path';
|
||||
+import { startBroker } from '../src/runtime.mjs';
|
||||
+import { Registry } from '../../seat/src/session.mjs';
|
||||
+import { businessDoc, rolesCopy, systemFor, writeJson } from '../../business/tests/helpers.mjs';
|
||||
+export async function telemetryFixture(t, { foreign = false, hold = false } = {}) {
|
||||
+ const root = mkdtempSync(join(tmpdir(), 'p5-telemetry-')), config = join(root,'config'), data = join(root,'data');
|
||||
+ mkdirSync(config,{mode:0o700}); mkdirSync(data,{mode:0o700});
|
||||
+ const rolesDir = rolesCopy(config), doc = businessDoc(config,'demo');
|
||||
+ doc.plugins = { usage:'cliproxy-queue', harness:['pi'], 'usage-source':['transcript'], 'limit-check':['token-limit'] };
|
||||
+ doc.usage = { cliproxyQueue:{pollSeconds:1} };
|
||||
+ writeJson(join(config,'businesses/demo.json'),doc);
|
||||
+ mkdirSync(join(config,'secrets'),{recursive:true,mode:0o700});
|
||||
+ writeFileSync(join(config,'secrets/proxy-management.key'),'p5-r1-made-up-management',{mode:0o600});
|
||||
+ new Registry(data);
|
||||
+ const tag = createHash('sha256').update(config).digest('hex').slice(0,12);
|
||||
+ const own = `msk-${tag}-sentinel-${randomBytes(32).toString('base64url')}`;
|
||||
+ const other = `msk-ffffffffffff-sentinel-${randomBytes(32).toString('base64url')}`;
|
||||
+ const state = { keys:[foreign?other:own], calls:[], queued:[{api_key:'msk-r1-unknown-fake',source:'p5-r1-upstream-canary',failed:false,tokens:{input_tokens:1,output_tokens:2}}], held:[], hold };
|
||||
+ const logs=[], waiters=[];
|
||||
+ const stderr = process.stderr.write;
|
||||
+ t.mock.method(process.stderr,'write',function(chunk,...args) {
|
||||
+ const text=String(chunk);logs.push(text);
|
||||
+ for(const waiter of [...waiters]) if(text.includes(waiter.fragment) && logs.length>waiter.from) { waiters.splice(waiters.indexOf(waiter),1);waiter.resolve(); }
|
||||
+ return stderr.call(this,chunk,...args);
|
||||
+ });
|
||||
+ const waitLog=(fragment,from=0)=> {
|
||||
+ if(logs.slice(from).some(line=>line.includes(fragment)))return Promise.resolve();
|
||||
+ return new Promise(resolve=>waiters.push({fragment,from,resolve}));
|
||||
+ };
|
||||
+ let queueWaiters=[];
|
||||
+ const waitQueue=(count)=> state.calls.filter(p=>p.includes('/usage/queue')).length>=count?Promise.resolve():new Promise(resolve=>queueWaiters.push({count,resolve}));
|
||||
+ const answerQueue=res=>{res.end(JSON.stringify(state.queued));state.queued=[];};
|
||||
+ const server=http.createServer(async(req,res)=>{
|
||||
+ state.calls.push(req.url);
|
||||
+ if(req.headers.authorization!=='Bearer p5-r1-made-up-management' && req.url.startsWith('/v8/management/')) {res.writeHead(401);res.end('{}');return;}
|
||||
+ if(req.url==='/v8/management/config/access/api-keys') {
|
||||
+ if(req.method==='PUT'){let body='';for await(const c of req)body+=c;state.keys=JSON.parse(body);res.end('{"status":"ok"}');}
|
||||
+ else res.end(JSON.stringify(state.keys));return;
|
||||
+ }
|
||||
+ if(req.url==='/v8/management/observability/usage/queue?count=100') {
|
||||
+ if(state.hold)state.held.push(res);else answerQueue(res);
|
||||
+ const count=state.calls.filter(p=>p.includes('/usage/queue')).length;
|
||||
+ for(const waiter of queueWaiters.filter(w=>count>=w.count))waiter.resolve();
|
||||
+ queueWaiters=queueWaiters.filter(w=>count<w.count);return;
|
||||
+ }
|
||||
+ res.writeHead(state.keys.includes(req.headers.authorization?.slice(7))?200:401);res.end('{}');
|
||||
+ });
|
||||
+ await new Promise(resolve=>server.listen(0,'127.0.0.1',resolve));
|
||||
+ let bus=null,startPromise=null,closePromise=null;
|
||||
+ const start=()=>startPromise??=(startBroker({dataRoot:data,businesses:{demo:{id:'demo',human:'jason',plugins:doc.plugins,arbiters:{technical:'coder',delivery:'coder'},roles:{coder:{definition:'coder',authority:{withinRole:[],crossRole:[]}}}}},
|
||||
+ organization:{dir:config,rolesDir,system:systemFor(config)},proxy:{port:server.address().port,binary:'/fixture-unused'}}).then(value=>(bus=value)));
|
||||
+ const release=(fail=false)=>{state.hold=false;for(const res of state.held.splice(0)){if(res.destroyed)continue;if(fail){res.writeHead(503);res.end('{}');}else answerQueue(res);}};
|
||||
+ const close=()=>bus?(closePromise??=bus.close()):Promise.resolve();
|
||||
+ t.after(async()=>{release();await startPromise?.catch(()=>{});await close();server.closeAllConnections();await new Promise(r=>server.close(r));rmSync(root,{recursive:true,force:true});});
|
||||
+ return {root,data,config,state,logs,own,other,start,waitLog,waitQueue,release,close,
|
||||
+ settleInitial:()=>Promise.race([waitLog('proxy-usage-read-failed'),waitLog('proxy.usage.reconcile')]),
|
||||
+ get bus(){return bus;},queueCalls:()=>state.calls.filter(p=>p.includes('/usage/queue')).length,
|
||||
+ human:()=>bus.broker.bindHuman({business:'demo',human:'jason',via:'cli',outsideAgent:true}),
|
||||
+ async pollSettledAfterTick(t){const from=logs.length,next=state.calls.filter(p=>p.includes('/usage/queue')).length+1;t.mock.timers.tick(1000);await Promise.race([waitQueue(next),waitLog('proxy-usage-read-failed',from)]);await new Promise(setImmediate);},
|
||||
+ };
|
||||
+}
|
||||
Binary file not shown.
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,301 @@
|
||||
8be7f2b7c210ff8ddf24d86c2e088da5827f5d7160326291f4750e4bb608e112 AGENTS.md
|
||||
c4eb0d3a8ba06097c784ee6e9acf3bb24b4d01e93d7c5a596ace87b23ea30150 RELEASE
|
||||
06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1 agents/codex/work/queue-333/trace-inputs.mjs
|
||||
95e2c9568498cbe628d62f1ef981dfb6819fc9acad0337086b67adc8717208fd docs/plans/2026-10-24_model-proxy-rows.md
|
||||
3038d65cd3e42c858445d92ac25675f7c5ae66babef1ef79799bd17ae59f0b17 docs/plans/2026-10-24_stack-model-proxy.md
|
||||
84e80f3bdcad8bd433951b503ad087705ee74341b374901b1eb8b3cbd6c04333 package-lock.json
|
||||
3baab27d3fe178da625a3bf48c87790d7fa7006098dd568131d5ee9944ac11cb package.json
|
||||
4f8057266af34f6c70ade88fc9bde45e2aff5a58ab3ee3b8a568a532385fc1cf packages/bus/package.json
|
||||
a2ba3a46f12e56139ecae9e55227d00847842aedec50c1d92aaae28844ca48e7 packages/bus/schema.sql
|
||||
232a1c77c2f17011c53b55fc6052f70985598210769d41d7c2c0b535328aad23 packages/bus/src/address.mjs
|
||||
c0144adade79c2cfc6b8247721393f0250b1d64f6c6c04d85738cb80939c42e5 packages/bus/src/broker.mjs
|
||||
ff927da3cf22fbacc9ace77b2e8b803bffc2953fb58cf7ab4e5f6f6493732996 packages/bus/src/business.mjs
|
||||
f3d483f61a24cbc9cce235e1e92889f09b8cecf513fcaf90c741f316f62262e2 packages/bus/src/client.mjs
|
||||
8b8609ae224bd7ed8e01be5a12c24c05291c7536723d7de9b8c9d1a46d630f22 packages/bus/src/console-cli.mjs
|
||||
86b4321dd436b97e389101873197dbab95b3d2202e5ef7da712c4978f4f9159f packages/bus/src/credential-verbs.mjs
|
||||
10485afcf94c29ac9f3d5ba30b12248a2379efd69185ff9fb90e9fed25fe0678 packages/bus/src/credentials.mjs
|
||||
27d7d5322c2f12641e350867d3ac6f838b33832951e69f057e3a7a28b8ac4d5b packages/bus/src/gitea-grant.mjs
|
||||
48337cdbc41d503f17962d3e3ad014183b1286165f97da6fd88b4faa50be3949 packages/bus/src/host-grant.mjs
|
||||
324c05b16253e0fcfc1a0299d1d8ab45850ea723fad1f67bcc07fc031f50d593 packages/bus/src/host-run.mjs
|
||||
271b9781d73cf31cc562a56180e3ebcd725b5fde148a83347a201fdef2fc28af packages/bus/src/human-cli.mjs
|
||||
bb13c146717cdc46d75d157177e400edac4d3e10f14fe511027a25fd44cec885 packages/bus/src/human.mjs
|
||||
56bfc8dcba476886d7de61a1e798aae8e3041c2434c62d44fc40a168d22bb3bd packages/bus/src/interpreter.mjs
|
||||
9919febc7679168e0a72c0ef51983120283e595fea290a5e8e948409bf5c911b packages/bus/src/landing.mjs
|
||||
18c1aacd280ebf0f200d5e6fc1dd1a7e098a3046c1cb8427140bb2198ac81cd3 packages/bus/src/limits.mjs
|
||||
b753f630301bf125e9e286b4156d0736930dd8fb9cd8eb2ebf316688f9191a07 packages/bus/src/migrations/3b-3c.sql
|
||||
179ffe356d4ff19a49b5ebad39b6c6bfd7771deb8e1b7c55b5e746f039d69e65 packages/bus/src/migrations/3b.sql
|
||||
0423832d05aa68f9191d7362827bd19310001165b895fb2de40b962fe68f9d56 packages/bus/src/migrations/3c-3d.sql
|
||||
d9aacc974d5047790e65c30a90068259bb9396dc92d4904eae3b9c5dbbb2f077 packages/bus/src/migrations/3d-3e.sql
|
||||
bf0b72c606b1a56a1610f09619b0c1118f1f300c636824ea13fd51a4ca6ac4b3 packages/bus/src/migrations/3e-3f.sql
|
||||
82f54b264919e34282bc214e34e9849f701cd3723b9b2f0a0d107c16f939dc05 packages/bus/src/migrations/3f-3g.sql
|
||||
76168e4f9f6b427286ddb8402fd833acadb01d6325a85f60e9ccf8d42fe2d1d0 packages/bus/src/migrations/3g-3h.sql
|
||||
e058e6cea8da7b6e649f3e03f2b81dc5444ee940a64274d0e367124c93545035 packages/bus/src/migrations/3h-3i.sql
|
||||
5ad122ca950e43e066f3d9ed215e73353e6b26de6687b961a8818d69c9465031 packages/bus/src/migrations/3i-3j.sql
|
||||
2e2bb1fe70076f5e24406a18a923b9e55c4192178a0a704a1b9716032676f9d4 packages/bus/src/migrations/3j-3k.sql
|
||||
eb2822c73e527697399691ae520092277ddbd4d2a9a42a0731b3c81cc3569e58 packages/bus/src/migrations/3k-3l.sql
|
||||
791879f06a3e97d3cfbe6112e2fb6502457af30b3e0198e3da1192038906d156 packages/bus/src/migrations/3l-3m.sql
|
||||
b40bc6a7bedc459d6827cbf0414619e48fc5dce2febdeff70a647345f2281c3a packages/bus/src/migrations/3m-3n.sql
|
||||
b4e11975bd56db4c816ada297902f033b3db7754d4a05319f03d640e17374550 packages/bus/src/model-keys.mjs
|
||||
29c88655e8b9aed8db604573c9213fd9f3c40ef35ff04f4eda8fbe8f1b8a32d7 packages/bus/src/peercred.mjs
|
||||
d1536a8f472fa5b3773adb10555529ed049ad63b647c0b44c00ce5f25ce09f85 packages/bus/src/peercred.py
|
||||
2b1e18be825e8264b16506d6294863acbba812956cfdf8e056f21faaa94f7137 packages/bus/src/principal.mjs
|
||||
ed13afdce6359df31d35a79496ebb4afdefef82030a8326a76b2a25b37e98d9d packages/bus/src/process.mjs
|
||||
cec059ea4bef5ef62f6181123bfe64bca21d8985d5357471da8c0a3199a877f9 packages/bus/src/proxy-page-vocabulary.mjs
|
||||
af36aae674f46a4e5eacfe176fde8b58cd0b171a6d70e07ee6d479e0f558cce7 packages/bus/src/proxy-page.mjs
|
||||
5a6c3707e6a64304cfd37f1875eb378c6eb58bf438cc40365fe913eaec7cee59 packages/bus/src/proxy-usage.mjs
|
||||
969d04eb06b97093c7f9f0dfa6b51084c781e967e2668814083bbba84a2af7b6 packages/bus/src/runtime.mjs
|
||||
8318bed9168ac3f58c09de40a139b68aacefd684e6c117406e181e2ca5ab4ec7 packages/bus/src/server.mjs
|
||||
dd7fce9706402efd1c5a5b81f7d0fa3793de203e7a6aef4e118e934aebdc7c84 packages/bus/src/store.mjs
|
||||
c04c434ec76252fbc93fb047e7a0c996225590e805f2c82a8d521c161cc9b80b packages/bus/src/tester-cli.mjs
|
||||
5e9e08ca8069e1de35232f26d48a77792388128dda659893909f2d34b5af2346 packages/bus/src/tester.mjs
|
||||
4ae57d053c4b217e1c1a22ada3ed1c5d4a3f0e61b8d2798e9db37997cd071a29 packages/bus/src/usage.mjs
|
||||
38228759eb2030232811669ef44a3c89874c80baf1f6af1da933decc1621e21a packages/bus/src/user-cli.mjs
|
||||
1f31aefa71984fba90c5390df5cc595d929681965f57485ad4972143d5c4b15f packages/bus/src/views.mjs
|
||||
68efa3c9d0a72095f503208ed5c2e660ef9bca68d3ea15f0fc2f1826a68e09cc packages/bus/src/web.mjs
|
||||
dbbfa80b4082fd44e2f08539b5455653fac062321b8f2106f638e2d8161fa3eb packages/bus/tests/daily-quota-runtime.test.mjs
|
||||
45870a4903d1996915c0086a6beb4d0a4c75b38386b7c5e6d98b5bc811c3b541 packages/bus/tests/limit-checks.test.mjs
|
||||
561d0950b788d08ad9a79ccd6572ad6976ba4b2e2b1c79d1e4d06827a84c131b packages/bus/tests/limit-stop.test.mjs
|
||||
a2e553025edbe6e930c9d03b48289c53b51b153ac9ae49bb21bf721b725f1913 packages/bus/tests/limits-runtime.test.mjs
|
||||
a8038fbad6fc666d5d033da4b35dffbf5f679eae6d1d6e042bea8d211c298360 packages/bus/tests/model-keys.test.mjs
|
||||
8a7889bb9aacde4faced9ab97faf6603eb7c5f7e1b78df9e5b28279c3b5ebab1 packages/bus/tests/p5-background.test.mjs
|
||||
1d57b286993b4fe7098433703462c1e5bea715c5e4e88c52f6676cc1757fd153 packages/bus/tests/p5-identity.test.mjs
|
||||
0c55ced6c8f30dbdc6572705f831a5c1a3375116cc169ca3005d36eeda35e737 packages/bus/tests/p5-key-compatibility.test.mjs
|
||||
e37114eab9c5f21015ea8e429f0574d3ea34b06263f1e42b83b31b8d2df222a7 packages/bus/tests/p5-key-context.test.mjs
|
||||
241e779016ffd0b54c5646cb4fac7e21ea1167e77afbd652ff4e01f8d238f99c packages/bus/tests/p5-runtime.test.mjs
|
||||
0ba3a1937cd58a907581426a5dfdcd3f6d0ebcec63ef0eeeaa333c625fbdcfab packages/bus/tests/p5-telemetry-fixture.mjs
|
||||
895ffddbcca1b38fdaa17eefdeca9092a9b9a934d3a54a3bf7857f42fe99fba7 packages/bus/tests/plugins-verb.test.mjs
|
||||
84c8351029272b6ee05e7fd81b4cc4453553ceeb7a5127a1333dae63d1336ad5 packages/bus/tests/proxy-usage.test.mjs
|
||||
4b2149ea4219f49db19669ada9f88931f7691cdd73dd27dceec6e8fe1f76dd0c packages/bus/tests/usage-broker.test.mjs
|
||||
5abe93fca8442f06ff68760623e91262d863e1191fa35a3d0c87d7b0e6c0a4c6 packages/bus/tests/usage-runtime.test.mjs
|
||||
2613ba0561572a7d4f753066922fddc90cca812cb0ce2b3e0a9a4d249a15e340 packages/bus/tests/usage.test.mjs
|
||||
0e15a5be600573ff7fa0b41c425ee6e57dad788be3d42991185c3a84d6090fe9 packages/business/package.json
|
||||
af028c999a6ab4d42b321c3f047e683b226c7ad232a2ae9cfc623b7dd5a4dd5f packages/business/src/access.mjs
|
||||
aaa4578fd4133f64119de6c8786a14759240a8910677529fdeae57173058b7d9 packages/business/src/business.mjs
|
||||
c3422b1e144177f9dd3015ac036ee1d2cde02bd2b3be406364f3b3f45d8c9b73 packages/business/src/credentials.mjs
|
||||
cd4eb5960c17ce32f26d1a49196866ce04efc42c1d90b18b046af5fda8b9ff0a packages/business/src/errors.mjs
|
||||
e08b11b70b54f13e3b18996dd903f841e04fd6c64791e96063df8b164c663882 packages/business/src/hosts.mjs
|
||||
a386ce5bd1d41d86f7b90641a423a2b651b491c8989d5085412c7d202ac1cb30 packages/business/src/index.mjs
|
||||
09f2bde85a6d7a8f0b1d1c60ac589b845b0c95e991b2f807758878416b13c6bd packages/business/src/instance-settings.mjs
|
||||
e14d73f719664499d809909962a6ecc16d4ffb9d824fcdee699e0778809d9e96 packages/business/src/launch-settings.mjs
|
||||
0aa94dbd14acd379a4837cc3e70b9618b3fa797d74124314e7245a8a3070e98c packages/business/src/launch.mjs
|
||||
93a7fddac9a08b5f740a0a277b29b8a3459e6f5a4fd33a37212437cb456b9b62 packages/business/src/library-seats.mjs
|
||||
44fa089c9024934a2f9fb5ef99552eb18d616842210cbc0fc860ea32ce0b1524 packages/business/src/migrate-launch.mjs
|
||||
fa4ba1ae878cd27287865fa12115f8a6c1175a2dfd1011d5f8aca11e46e669c7 packages/business/src/organization.mjs
|
||||
9d2c68dd21c6c9553af75f4b137c4f169e95761f32528767e0518d0313311f50 packages/business/src/plugin-settings.mjs
|
||||
9472996134c520c31971e66006d1c1683709f6df4f76fe3445bdc97a18637eff packages/business/src/project.mjs
|
||||
712183465fee099606223d84423afc54e3386a0c8e468c68d5ac39c1e676d109 packages/business/src/resolve.mjs
|
||||
b10af84d7422da4d0e8c0a4fea1064eebbc2fac6a838a1b3939b554e22dedfc9 packages/business/src/role.mjs
|
||||
e1f0e70a4bbba8ae2ad6185ab61770b15acda403e90fc708e13027a1e9ec663c packages/business/src/util.mjs
|
||||
f6b15ee8dad2d985c0ae66b1f106ca46cb56ec86ac8cd5dec8a05c887596a421 packages/business/src/vars.mjs
|
||||
de1f04628e400084a46e77fd7e03c7a039f0f80c9e07bb486c9c012f187aa3eb packages/business/src/vocabulary.mjs
|
||||
a6a9971b42ddf176d9415caee3efc2eb16791dead5f0f0557d28449a550aefa1 packages/business/tests/helpers.mjs
|
||||
f0dfe004905dce31317d85d89a05802db878c3472e765e85dc9f1e04166e1df6 packages/business/tests/plugin-settings.test.mjs
|
||||
bc6b3a31e8918d70aced7151b91ac4b39afec4081054024b162acb0e8f8fae07 packages/business/tests/token-limit-settings.test.mjs
|
||||
6c9c952d8637206697bc3273f2ee247185cad624b3db84fe4d2ead0b5c1013b3 packages/cli/package.json
|
||||
c4949a16173d11f9d32d10d3ddd58a181631848b259bef1998820a78f5694808 packages/cli/src/access.mjs
|
||||
15a8ee212fc37cea28e389f60ddb8916f9e1509cdcfb2e522acfe548702a16dc packages/cli/src/app.mjs
|
||||
147a17bbdcbc34efe20a88a4cabe796c101cb63dce621d28103f4de29def4cc2 packages/cli/src/boot-status.mjs
|
||||
1e663b175e18e39ff68c9ac3a65ff71fc777a6c37ebca035fce6a2783d0aaac3 packages/cli/src/cli.mjs
|
||||
d960c2a9df3f7c84deff22dad1f0ab120f95ee365984e390de98eba7292b65a1 packages/cli/src/config.mjs
|
||||
19755f7bb002d8455990c5dc7c458e64aeb95252ec7231a2ed2fd9c638fcb511 packages/cli/src/credentials.mjs
|
||||
c7bdd98a3ddeeb9bc4415d907b92555d723c566eba314075d91486da9b5e85dc packages/cli/src/errors.mjs
|
||||
481d9956698df7765ca8556d57164fb78f131708a09900d5a55b9048b5638f5f packages/cli/src/format.mjs
|
||||
3076a53b9891d4d0e084306567b88ded12c4de53a943c029646a424bf59d8e49 packages/cli/src/git-socket.mjs
|
||||
b586907ca8f351f60dc19ec2683df75d2d70ddb12955d09fb14560c9d3bed3dc packages/cli/src/grants.mjs
|
||||
a0936aee783ff47dd58fc907fefd86f63e571809a3ce5b0d6d931f71e756b15e packages/cli/src/host.mjs
|
||||
60419503898f5e7f3046df5e749098728fbdfea76eb5c53b5dc9b909329abe2e packages/cli/src/hosts.mjs
|
||||
8d6dab8da62b4458477572ca1956adad57bc0b0d308df6eae57477175c345d7a packages/cli/src/instances.mjs
|
||||
373d4c028dfa6d85c748d56f56359789fe2b81987f522ac23747fd37bb5478ed packages/cli/src/launcher.mjs
|
||||
2f291a71f490f2741edada7a3e3788500f8976a08eb8ab1411f6c5982f778260 packages/cli/src/limits.mjs
|
||||
9a043f122e1d49103bab64716d0eb80cfc09da3c91f7e2eb014b0d8ff0b02f3d packages/cli/src/model-proxy.mjs
|
||||
0bdc91dcaa096bd3dc9d08a1dea59893a21f6505c843e698ad9c8daa4b74364b packages/cli/src/model-stall.mjs
|
||||
b325b4f5133d40f8b1288e666ef36c5890f7f3a3de20f1dfc1ca27ec172a6372 packages/cli/src/notifier-process.mjs
|
||||
400f4af8c72915101e00f25c0817534a34e7fcf29f960f5cdd78ed9884707f3f packages/cli/src/notifier.mjs
|
||||
f8d9fc24ccd71494fb2914914949cb08948ae93fb3180b9531eb807c921a6f53 packages/cli/src/plugins.mjs
|
||||
6cfe7fd5086ddb59c5666060c6f8044c2852e0f3d5755b1fa206f7521173f300 packages/cli/src/project.mjs
|
||||
9d03335628ae62e85c5fbc08c2e739ed0bd43b10d486faf397129a56a1b343e0 packages/cli/src/screens.mjs
|
||||
1a30048032f5bb64419ae9716a1692978bc1a137220a094d1900298aca6ba1d7 packages/cli/src/session.mjs
|
||||
58888b7731f8009d4c3f8be2caf4445f13dd8f534e1633f6e2720b259fcc3f92 packages/cli/src/thread.mjs
|
||||
662642a8ce739fcb6c188ad07125a94e008c8a305eced127c8041d472c56e55b packages/cli/src/transport.mjs
|
||||
f9e0c69849633ae36a7a6aa22729a690dc40292178ac3db43accbb131fd7b4ca packages/cli/src/usage.mjs
|
||||
1e1aef2c74434e388d61b03407cd323336d20b7ef2106893d16a39638ee12a64 packages/control-board/package.json
|
||||
8966f1f98ea81b4525345fc4889db5e0e5263ca41b5132ac8dd9bd99a2c88522 packages/control-board/src/discord.mjs
|
||||
6d74b131af360268be748a1f8f7f2b3f5a9180365e7279426640883fc295a676 packages/control-board/src/scan.mjs
|
||||
2eb25c46e85ddadd3bdbdbe605db54a6e09845155384a209622554d78307e583 packages/control-board/src/serve.mjs
|
||||
2ed3790eb877414b8e985ca16031d8963adfb5c9555d415efb76288b76a5e1a6 packages/conversation/package.json
|
||||
a45beb82438bb42d97d1e322010e175e785767664e548b90c4125e98b7660003 packages/conversation/src/client.mjs
|
||||
eaf0772b60bb17fbf9548267c9cfeb0104f92f5cbafdfcb60c1633883eec6432 packages/conversation/src/framing.mjs
|
||||
da336ed2a2a149ff56ac12af2440a8353d4573c33e9069381be60f1a0ca70151 packages/conversation/src/parts.mjs
|
||||
20e781240846298fa65f9a8226b5e1ee1e81338b81229334666d845c17c99ac1 packages/conversation/src/pi.mjs
|
||||
75d0cc982c36b0a81ff23f0da9da1b56906c496250a043f91d3a3b18ffa8e51b packages/conversation/src/reader.mjs
|
||||
96f7b64c2e2c3493e270224542818fd14f042e3cf0ac14788b3f881010bc25b1 packages/conversation/src/records.mjs
|
||||
62b0f7e9f798f584fcc0e4ead0522e44fd113bd0803f2bad92ffa480cadb7527 packages/conversation/src/safe-fs.mjs
|
||||
c24d28a073659640b8b027eb12ad150ba895c3001091b892ecef2ec1da40d5cd packages/conversation/src/terminal.mjs
|
||||
f834ee740e7149e7d2ed976112d0719ce0660270e3b61cf93e1774d112c992a2 packages/conversation/src/transcript.mjs
|
||||
bdbfc8073d2073dd2ca4cb1460e3c376f087fff387d053d883932e5a67f85948 packages/discord/bin/git-credential.mjs
|
||||
a52c6bfc9bd26a3b021d3a96bddb0f5c45845d752ca4579ef04ef60667f110f3 packages/discord/package.json
|
||||
5ab69c4111dd9589a197172ffe6968bf414f41c552b7910e5478a27c446cfaec packages/discord/src/binding.mjs
|
||||
917b0e6c4f100e93f056b925e38d97eacdd8b2596e39fbd3f88c0b62b973d8ed packages/discord/src/errors.mjs
|
||||
c28e04a0055997ea0b34bea1ad2912adb248d5fd43713df1e6f5a661d87949b7 packages/discord/src/git.mjs
|
||||
12684e926574c3fe7f693a03b60d1393df483f5feb4b47c9dd7c5a7ac050aec5 packages/discord/src/journal.mjs
|
||||
aa7c1e328d6664b53e4d9cb5a1ab83c8ff71cc31deb9d3ce91a7dc6715c887aa packages/discord/src/notify.mjs
|
||||
8fa9968862dff77fa6d8be5210c22d13712fd622a8cbc722d167be5be80d0783 packages/discord/src/processing.mjs
|
||||
0b0b8f4dc25b8fbd4d948c962453c63084b0797b0ec5f0420e3f4f174837ccd5 packages/discord/src/rest.mjs
|
||||
ba09d286e707860afa53300f8802ac8e6193ab2d2e7abe9d2b07cbdef3822387 packages/discord/src/setspark.mjs
|
||||
975503616245bb6051f06ecbf47436ce7d030f21af23042df7f3341062df967f packages/discord/src/tools.mjs
|
||||
e5a7b64720872b12b34223549537ace05ebf0ca8a29b2f844d2b7c5cc9ea41f7 packages/discord/src/web.mjs
|
||||
34ef8212e27f052223443c66830839517f7a54ecb6ef7d85795b3e89c65b4d4c packages/harness/package.json
|
||||
e944a4c7a26d1fe55e13ac1eca31dd86c302dc7c868224b8b000b27255976153 packages/harness/src/bundle.mjs
|
||||
32b5090760c95eea0e1232ff36ec13a1d9b58335b2eade621196dec1ebdbe784 packages/harness/src/claude-gate.mjs
|
||||
a74ef2db4093c0c797ba9e7e28e4e4df0ceac9040385f00e60a273f39af9610b packages/harness/src/gate.mjs
|
||||
ce0107c3b21e07925b6543b6b925da8b8768823448d4fcf30b620883cfd2d39e packages/harness/src/mcp-server.mjs
|
||||
fcba4b8dfd9dde947a79f88376d880f383e2a04ee3c0a9ba2fa5af641fe61b35 packages/harness/src/pi-extension.mjs
|
||||
38fe84040a78c3f8a8dcde4339d88db3b5df9ef669d605ad1d92ff3e8b646b40 packages/harness/src/tools.mjs
|
||||
5c9b528fd69a2493f04933fc84f352b1101d276d69d9982806975def614fd740 packages/library/bin/askpass
|
||||
f6208a6b9e233baca38dd0ed9fd435cf2c7a3e34160c2c07cea1fea66893513b packages/library/package.json
|
||||
f710d9600a17f6e2989a289cfe84e58f161d86c7306605946ce05fa71b364eb2 packages/library/src/guard.mjs
|
||||
70c1fe75cb2149c9a074d55a6301d5b66157c2dc2e777b92bac338cce09d89c7 packages/library/src/index-build.mjs
|
||||
98c2c2877549c3e2c5963ec4e49d99ab3b6d6ad54fb3bfae86cf98542207157e packages/library/src/index.mjs
|
||||
98ef45ed61144aaea44d8aea1ac43082b6d340297e46846d01772da38728e530 packages/library/src/limits.mjs
|
||||
def32a176cb70c86248e45908edde22f9c4c5f88575a4af0a396a05f617358bc packages/library/src/links.mjs
|
||||
c83c626c7cdc2a00ba4217c34b889ca0517cd2022d1f8fc9e7d3a14a0293a802 packages/library/src/mapping.mjs
|
||||
26b824d6885e5c6d1b8bd71e754a9fa333c26307693f7e6a0c6a8e6300ecb4ae packages/library/src/mirror.mjs
|
||||
0c8764b03dae0150c56af74bcb113cf583dcbe1fa0c6f7386ef2d48d59a6bd31 packages/library/src/problems.mjs
|
||||
bafe113bee70f17bd249876d6bdd1c08fa051223c2111955e5d5f275bd76bba0 packages/library/src/query.mjs
|
||||
ea126533afb7e74b71419eb943febb6b242eb96fc6917d9df1019db3e7e6ce8d packages/library/src/reader.mjs
|
||||
bfc3de029d3c8f0dcc96c90fde30d6da58bbb5b72d8f13e3f536c0d735c73ca5 packages/library/src/render.mjs
|
||||
7b46f47b5e9d6b554b5d39bce2cd95c4610f5f35b8ab8fdc5a2864b3214be809 packages/library/src/reply-protocol.mjs
|
||||
97e12255f52ad638eeacd152eb26822f9a2aa72cd30e2fed1193f51cd6e56192 packages/library/src/scope.mjs
|
||||
6a3b4de2070e62b1cca1c0ab20f2883d3153fc61608d1bf7670cecea08765b4c packages/library/src/supporting.mjs
|
||||
016bfa5c80572c0baf90ced39cb3d3ec66d395f0be15c2727b9552a9dd849093 packages/library/src/survey.mjs
|
||||
a58f3aec5ed9b3530b363e2fdbd38bc9ded7635d261ab2fca3cb31c45dcd3dfa packages/library/src/sync.mjs
|
||||
a301b7c7e3f42f66cb69d88991220f4e236f25a6e5951c61e79ec4ef2b714198 packages/library/src/write.mjs
|
||||
889ac9589fadf7654d4dbb914f968cbafe4255ed215bd6a9ff3f331757c9017b packages/model-proxy/PIN
|
||||
8fbfb3d1562e9ea824a1bd399b17cb2048c92b125e7699ccf27abdcc6e31e40b packages/model-proxy/package.json
|
||||
f5f86cad661034f223a76352d877fa8d7883bfa921a7a01282347a9a03272441 packages/model-proxy/src/client.mjs
|
||||
a6fb88352018b8f21593a0bb9311f87162c80d8b1e05e62b4d43b1e69af21b23 packages/model-proxy/src/common.mjs
|
||||
00378d2ea95ac4945899696462f8ff4c70dc020cc58d93663d731d2f2f333783 packages/model-proxy/src/fetch.mjs
|
||||
1eac4b5741b360a077bb1c871c008b64f7c7119afc64be4d6e4a0dcdb3a313bb packages/model-proxy/src/settings.mjs
|
||||
e66453cf6662677cf28cbad1ae8f7509917d333e5b80404ab02c53f5cf75e9e1 packages/model-proxy/src/validation.mjs
|
||||
77327681d6eb51f25d7aeffcc532b7e8269c1dc59139cb03adb4a3a1409f63e9 packages/model-proxy/tests/client-probe.test.mjs
|
||||
790c6a50ec030a8b27a28fac7fd129bd9eabe79774adf11d6620c00df9b6ae86 packages/model-proxy/tests/client.test.mjs
|
||||
95e39a519f7ac8b9592876e6157191169f9b14d002163867a6ff6ab808e42c14 packages/model-proxy/tests/management-key-encoding.test.mjs
|
||||
f24e1d121a340cbcaa3f6cd6390eeb7d4b05f778dd498d76ba099cba5a719dea packages/model-proxy/tests/page-client.test.mjs
|
||||
1ad66d56800a31cfbd387939e640653bc72150f4e73822d9e3c777b3bffbf1e1 packages/model-proxy/tests/usage-client.test.mjs
|
||||
5e7e1ec169392ee3065f8f47d19732ebbe8bdd90f9193581425b956e66da6b73 packages/plugins/channel/cli/index.mjs
|
||||
789132601745a94027f9e9184e7fef1f70cff0cba450afed5cca647f683591f4 packages/plugins/channel/webui/index.mjs
|
||||
a317ac544359d321bb91b67cd87fc6ef431b72df9ac9f7f2a9ff291ed1a9109a packages/plugins/harness/claude-code/index.mjs
|
||||
aabaf5c4602e28f025c18b2e2ddd6fa0d1648870101a5de0c4424d97b24472dd packages/plugins/harness/pi/compactions.mjs
|
||||
39c225f157b8f66b416625bda689153505743ffcfdc32964bb1f3d2c6fcb73af packages/plugins/harness/pi/index.mjs
|
||||
3749b9f6dd681ef424ee7d7e4d80ccee87b3655df8cd8fe9ccd0d505dcaaee9b packages/plugins/limit-check/daily-quota/index.mjs
|
||||
4d0c6f5f87101f94608c02001a49d62cef113da48c539b2d2488dfbed1a4c524 packages/plugins/limit-check/token-limit/index.mjs
|
||||
90a9ac59a9ea2287e9a3d4b2f4286d025e727f2a6ce149464f8d0420fd9a8ef1 packages/plugins/package.json
|
||||
8be381a7e5dc7dd5ad18e89bb17f17d4b7074bbac490331fc61c65ac2b824057 packages/plugins/search-source/harness-builtin/index.mjs
|
||||
92618d0cd2f1b79c7d0230ec0ecd80ff628744524847d6b5f33ddbae9d7a3a09 packages/plugins/search-source/searxng-bundled/index.mjs
|
||||
fe4603b69596c3758ef8d7f794e403273e24e0fb950a92f15f8e651e193955ec packages/plugins/search-source/searxng-url/index.mjs
|
||||
5fcecf8336ee247e8ac2f626b21e4c79b1edc49082eadfd536cd23016c6bb756 packages/plugins/src/channel.mjs
|
||||
eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78 packages/plugins/src/kinds.mjs
|
||||
2e99f9222424cf9503253701568f0bb5ef579a22930f9f224e5b63ad6b4f745f packages/plugins/src/loader.mjs
|
||||
3d4fab56fea4c45c6a317ef41121aa5b6da0502a6ef614b7931f91cafdfc1f71 packages/plugins/tests/daily-quota.test.mjs
|
||||
5d5e5dccdae3f94b8540d187a8899ec36f9c9933cae3933249c2d8c400c75aa2 packages/plugins/tests/helpers.mjs
|
||||
f3081e1dbdac20ade2246c743bcbb3934be686f79f378af21c365cd1451893ba packages/plugins/tests/kinds.test.mjs
|
||||
8588ad7eee0c9ce5de3b53e3b88562812a155a3d791a2bd3413bb1754655d78b packages/plugins/tests/loader.test.mjs
|
||||
6e96bb96278ec754ca1816a24f49ef677771615ab5cf186ae41969fc2f93d8cc packages/plugins/tests/token-limit.test.mjs
|
||||
d09ae19db3eb69477783163559bd6a8e5b59a6f5af0eafd62d0e2e3bd325065e packages/plugins/usage-source/transcript/index.mjs
|
||||
e9deb2504741f45645cd52ea6a1daee031cd2d3d44775a1221e76cec73c6b480 packages/plugins/usage/cliproxy-queue/README.md
|
||||
6096a577cd5d7e8bf84fd6b98ab284e2f47d5facebd027548e07e6aeec442f96 packages/plugins/usage/cliproxy-queue/index.mjs
|
||||
83aa9ed92f6ea3e1f68a6325ee61250a3167cefb360fd7154b89ed026b1aa8fa packages/processing-control/package.json
|
||||
781973277c09133de15fc39be35b372a79066479097d46923c8ab7782f011dcd packages/processing-control/src/containers.mjs
|
||||
ddc7318297abc4ec4dd03d425820b7323db609e554cfc5341cfdfa6934271e73 packages/processing-control/src/coordinator.mjs
|
||||
3bc600649267f011e21ed8266fb16927b0ad3a0e2c49e4b54062d34c544d0c17 packages/processing-control/src/effects.mjs
|
||||
7145420aa354180689a5c84423928fc60c8123476dcfed3364c9cf4542f8c7ea packages/processing-control/src/runtimes.mjs
|
||||
ed834770fed863cb0c15b75062de1fd63dea940f3b42020b769a7e62b319c8ed packages/processing-control/src/state.mjs
|
||||
13664e88d0f233bcf18f05e75946e70a1f2a7ba8d099248b73936230cefadd8d packages/project/package.json
|
||||
925bb03ac99e5845e4bfa20b4561a331f034f88e187db82213df6602a7ceee4b packages/project/schemas/decision.schema.json
|
||||
f069c012e9660d5d0491a21f98e936b725f6818e1c3136dfec61b3c800bd58de packages/project/schemas/project.schema.json
|
||||
79a1e7b567af7162bb88ca69861075fc579a858e8aec4e49824ccdc370b690c3 packages/project/schemas/requirement.schema.json
|
||||
af6865a4cace92ef27910098507ffedfc8dfe768cea088b1fee21d0876cc556e packages/project/src/git.mjs
|
||||
3ab38cc40ce9ed1a714a59a1f2c336c3792a59431a6a9cc655ba6a2f47513899 packages/project/src/index.mjs
|
||||
bd9debcf3f9bb92560e74f220a0b108dfe24154bc6d1fb03c5ec414356d451f9 packages/project/src/paths.mjs
|
||||
42113cd20eb8f04dd252f9963a6f1a84806af9cae7beb6808c4d584a2548220c packages/project/src/read.mjs
|
||||
e49ab5e825f0706da2f3c8dfcf33c1331a38d77ca2d35b03359ee68ea74652c5 packages/project/src/validate.mjs
|
||||
24b7e3224dba45753e2d6139fcf05d2ed8c29d999752b02a637cfb8489fd9e0a packages/project/templates/north-star.md
|
||||
26ee149f870ff56ad6d1c3d7c3b4b2301879c59f02d5840078c07e7964cc2175 packages/seat/package.json
|
||||
5aca02491fe8df51487968ce62c776d493d0fe693cc41478b84bef7b49c8948d packages/seat/src/checkout.mjs
|
||||
c5de99284b8fa61763b8dd30a58809bbc086529eeb10587586d52b0df2754774 packages/seat/src/compactions.mjs
|
||||
6f7c938a32b349ee49ce95b89ad499e599f6016e5e9d7efd79a9ea4177b4d175 packages/seat/src/landing.mjs
|
||||
382cbf7e0ff336911e288ce858bdbfbec693bc2b69879720d1f0b4c7d8455198 packages/seat/src/proc.mjs
|
||||
0868f393f6fb117d430428ec390e435359737eae0792b4a4d1f54797c7a6c1bf packages/seat/src/sandbox.mjs
|
||||
eec970961a667c9e614d1474d33c31a019b2cf1b0bf931a51458d874bca13a15 packages/seat/src/seat.mjs
|
||||
c37a6ef6f6d2b4e61443e77d800656bf31e38913bf7dbdc4ca955f4a83b13a41 packages/seat/src/session.mjs
|
||||
621f5c223811444336f0f5d6ad10bc7afce075491653c0527d6c26ca568b79c3 packages/seat/src/working.mjs
|
||||
2018701876f26c0566307335eae992efb3551b75af200b7c249b615757bf311a packages/tasks/fields.json
|
||||
269161444d253da7886d83f7b2f7bd79792b6c6b798c6e72f05f69bb99ad5295 packages/tasks/package.json
|
||||
80b58323994d70e8bb496d81225aeb3d2cdfda464654b68b3b082e9af1fac5c1 packages/tasks/requirements.json
|
||||
ff0f30ef6b2f4b758082913c34062d4749a71c157e994a06de692bb70dc8014b packages/tasks/src/adapter.mjs
|
||||
b5580224e931198c7024326135db5bd4f660dfa42834f19e4cd3c08550845bc9 packages/tasks/src/digest.mjs
|
||||
c9a883e9a1649277edce97adca40bca2874df7b5312c70e4ac6f6d4a1c860841 packages/tasks/src/fields.mjs
|
||||
38e7b85650247759f06c09fce205b2970b8368bc81491f51dc6b3c90ba2a846d packages/tasks/src/requirements.mjs
|
||||
c538cb5ac1c9bc96c50b8d6ca01136361369ec463606684a21d81e3b5c2e46a5 packages/tasks/src/startup.mjs
|
||||
39887268258c3b651246b3596a866005fc193cd8ee5f151a02492967069f2d06 packages/tasks/src/sync.mjs
|
||||
1c10dfcd37b0435e199aed2535b71909728ef358dc145ca9eec4f5beb37bfb87 packages/tasks/src/verbs.mjs
|
||||
0d76911dac358d195be4293ae03ae53476ea4d1b0fff4fbdb1a2de33f46ef952 packages/tasks/src/vikunja.mjs
|
||||
0bb346f598380c2bcdb39db92a006959442d3ce5dc645503ef76405aae53311c packages/webui/package.json
|
||||
c521be48ddbc473c61431424838cb9c6d67a0086082141000882013bde62379f packages/webui/src/access.mjs
|
||||
4ebf6c2b5d71c23d85cbde83f69aa671058dc2195c9ae4bdda624f6940729d1b packages/webui/src/bus.mjs
|
||||
3a5321a5f492a98d342e4ddcc1e9da3522cfff89a4f9bc3f51d2ab1426d3de1b packages/webui/src/chat-http.mjs
|
||||
fe2072a7198771a82f58dca5fc05aa4d697dd3db25a206fb2a24c8514010b069 packages/webui/src/chat.mjs
|
||||
5988c015b7f03b56654311039874f8c42a1d93012b330ee389a42fb88af70279 packages/webui/src/cli.mjs
|
||||
79cfb474308d148293b702c0132927acb31ac4f1400fde9a9ee78c99a7a558af packages/webui/src/console-bus.mjs
|
||||
93d4d0c36d0b74eaace24bce4c3e7179b7418377eb4df6d0f6a9ca89d5eb8e39 packages/webui/src/decision-http.mjs
|
||||
c3825a02c3b4f4e5537db4a945439d707e177e74c3e8b1fc2cb777515e610b64 packages/webui/src/processing-http.mjs
|
||||
a09028cd5ca57367f597d0681e84926ca871fd4626769e9947927d949c2b6ab7 packages/webui/src/proxy-http.mjs
|
||||
3c7a35e25b4c1cfda19ac9466d4b2fbc86c880761a1d04ad3ece8bc485f60f93 packages/webui/src/public/bus.js
|
||||
46defeb3b4be0e1a22e4b89445872ad6b15cdee182076e9e6222219ae29997f4 packages/webui/src/reads.mjs
|
||||
7b7bee91604b7bd973027b177de83205db9aed366e694072fc6343b46465b5ba packages/webui/src/serve.mjs
|
||||
37b01ab0479d5f2a7ab9aac790931c6d88c790465392d9c0b65a105513f3e36b packages/webui/src/sso-config.mjs
|
||||
9a3442739e95407deb0afe3e2a2aa77741d40f3eb899db985f45af49c38b34a0 packages/webui/src/sso.mjs
|
||||
1c1fe0c795adac97f28502564a75f26d5666d9be5ae51169f7dd5bb7741fad16 packages/webui/src/tester-socket.mjs
|
||||
b35d3f3471d6d83ef2d19d6102eaecce2ddec9330f337d7194f1d7be03cbd216 packages/webui/tests/fixture.mjs
|
||||
39f50991578b98594183390a00efbca84fda90ef61617eea4215e2c75f90b82c packages/webui/tests/usage-render.test.mjs
|
||||
f96d06974bc83051c0d5c9000e38161ea0cc231997410bcc6c42ed7f55718dfd packages/webui/tests/usage.test.mjs
|
||||
5f63ff52aaccf06a0f2415ffdd9d1903c202679cf953bef5266a6841b5e39ab7 roles/assistant.json
|
||||
7d2d50a1278c62daa4f6c4a5ac7809817409f2f1d0d75787802300739d3fba15 roles/assistant.md
|
||||
314074c8081953923f962f2df045d4c14629010ea99d1f23449ed45294b46bcc roles/chief-executive-officer.json
|
||||
a6bc3aad543cfb3a03f93efda60859221c56f78d0f1094da33afd458399b4ffa roles/chief-executive-officer.md
|
||||
539d531a0f5744aebb933ca685b52022554e3e93ae54cc8b67e4de0eb27d3460 roles/chief-financial-officer.json
|
||||
09347759baf8fdbf0a8105106e8d27b500f3d0b76dcaa91dc2cdc20b3b000b00 roles/chief-financial-officer.md
|
||||
8ee8e7213d4c073e2d9ba7732fd84b3b3130d9bbb930d07595b7f692bb9fc5dc roles/chief-information-officer.json
|
||||
0a7041dd3ae5f05ba6f37baa2aeeca35a430ed3e387a3e2407daae2c431efda2 roles/chief-information-officer.md
|
||||
a550428603979f4342e57ad9ccddd4d2e44a5203a64f19027ce09a24f1dbfc0e roles/chief-information-security-officer.json
|
||||
1da83baca46abb75c6b2e74df7a3fb9424e1556ce37ff5f8c7802e85100d6b16 roles/chief-information-security-officer.md
|
||||
3cdd799159d3e676529efee01f467a4ed7d67920253cddba2e098566368a1e36 roles/chief-marketing-officer.json
|
||||
4d414c02485b6a83f9d8fc2498a53d275019fd45e9ad948fdf61777a3a983bfa roles/chief-marketing-officer.md
|
||||
c781c4108824db7f17cc4b514e3b0d446120dc1ad7c05e5bf5a72edcac70d054 roles/chief-of-staff.json
|
||||
db16c358820e199910eabe06f885a53a4bde2502aeafa5444c12d9b29c74880c roles/chief-of-staff.md
|
||||
13713c4e64ade3b1b1eedabed75f5f76fe65e73f6df336b771d1e34881d111f3 roles/coder.json
|
||||
d29d469aaae2a97705dd0d5b057b6eef20c5f22d37791aaee9d886c8bb46700f roles/coder.md
|
||||
962f1e8ca9d56d7ad7dd4f82a57b97b834bacdc72c3fe774f9a9afccf7dd72e9 roles/companion.json
|
||||
cad0360c16db9b2659370e6363937a27d61e9f6c4fae711a2dfc5b89aadead81 roles/companion.md
|
||||
42e751413a649e03c5e1eb87acdf59e0a0fcd54f519bca297463f88ee07e3043 roles/conductor-policy.json
|
||||
031807451adfe5e4643da2ff59fab0a041fce519f4cb84d749ec6f10edff8f36 roles/continuity.json
|
||||
75522c66ccd242971b4b00786112ef37b41c972af5b0d98c011697169fba7db2 roles/continuity.md
|
||||
60b6482a29a578234b4e5bf0d4c9a123bd3a65a65dc6e488f474546cf4456bb2 roles/cto.json
|
||||
b5603cbdfc1a79d4b986c97aa2a94e2c57164f9abfd5117b348086025dd50993 roles/cto.md
|
||||
1dfc6629dc70dd8020483456db140751010e81a44fbd49308580f0c6356c2471 roles/fact-checker.json
|
||||
2d01f771831d52a1d9ddde8c1183601051782efd39899605949761fdd5e07291 roles/fact-checker.md
|
||||
2c69c26460574948584eae487e944b7240cfa37a0a0f3ddeaabd682815ebf6ed roles/ideas.json
|
||||
bb403867a2ba33ea271d2d576165c6131e43446f2d5deb4eb86389398cb0592d roles/ideas.md
|
||||
14dbbbaa98670ebab8612555e3f813793ff12caf6a3aaef3883c2007ebc9bfe8 roles/merge-gate.json
|
||||
b8bbccbf7e10e090f3514664384cba44c86fbb514c79d182d31a209045fdcc1d roles/merge-gate.md
|
||||
1af1cb70512163eb5c39ae942496a4cc309b0b1d47b9cb48253ac788862f0e9f roles/pm.json
|
||||
d1016f8c34ee04601ab751c7514a20dfbeec0359d46dba8f94c44538dcc16133 roles/pm.md
|
||||
3a55947b867241dd42b78588276f6f901d374b519f3964ba0acc4b782513224c roles/proofreader.json
|
||||
054f6f888064eca4c6b7b1c0180bd2ad968b10429f045db7aaa92453cbddd1ab roles/proofreader.md
|
||||
38d36d8cca7f4f7141af5469f0a17dd2a44a5ec26ef113ad9a01c9b013968501 roles/research.json
|
||||
2a66291a7a8d21b9f587c6226d408667a775b2846bc9950606e73b210f4ac0d1 roles/research.md
|
||||
3b5f0c39b72eb1ef1d546899ea5b02da6ce0c22a5d30d67058530b1bdc67964f roles/researcher.json
|
||||
4d2b2ab1208aced3a82d7de1ace879574fae2930ac1bc684f76e1d16e58cec8f roles/reviewer.json
|
||||
f7418c27a5b84f258041b87e87ccf9f441fcb9c638a322e50aafcfdb0ce7f364 roles/reviewer.md
|
||||
d84bd99dda657fc44b6272cc35a89c490315117c7102d8936042ac1cf58978cb roles/security-reviewer.json
|
||||
eb5ad42d4fcd98a2c89afb8b2286edc5eb666f993e21fbbda838e5c472f34dd8 roles/security-reviewer.md
|
||||
@@ -0,0 +1,311 @@
|
||||
diff --git a/packages/bus/src/limits.mjs b/packages/bus/src/limits.mjs
|
||||
index cb47c5df6c97fad2a18cf6a482b6976376ea7fa7..c4bb3a75ecd47b94f83dcc4df28f11e252d5f460 100644
|
||||
--- a/packages/bus/src/limits.mjs
|
||||
+++ b/packages/bus/src/limits.mjs
|
||||
@@ -12,7 +12,7 @@
|
||||
//
|
||||
// refresh, mayLaunch and mustStop are async: they re-read the file and reload first. report is
|
||||
// sync, so the organization verbs stay sync; it uses the modules the last refresh loaded.
|
||||
-import { createLoader } from '../../plugins/src/loader.mjs';
|
||||
+import { createLoader, isDailyModelQuota } from '../../plugins/src/loader.mjs';
|
||||
import { turnRecords } from './usage.mjs';
|
||||
|
||||
const KIND = 'limit-check';
|
||||
@@ -122,8 +122,9 @@ export function createLimits({ store, read, log, makeLoader = createLoader, keyF
|
||||
log({ event: 'limit-check-failed', business, check: st.missing, export: name, code: 'not-loaded' });
|
||||
return halt({ check: st.missing, code: 'not-loaded' });
|
||||
}
|
||||
+ if (!st.checks.length) return { [key]: go };
|
||||
const leaves = limitLeaves(st.limits);
|
||||
- if (Object.keys(st.limits?.tokens?.keys ?? {}).some(k => /^[a-f0-9]{12}$/.test(k))) {
|
||||
+ if (Object.entries(st.limits?.tokens?.keys ?? {}).some(([k, entry]) => isDailyModelQuota(k, entry))) {
|
||||
let modelKeyId;
|
||||
try {
|
||||
if (name === 'mustStop' && (typeof context?.run !== 'string' || !context.run)) throw new Failure('proxy-key-refused');
|
||||
diff --git a/packages/bus/src/model-keys.mjs b/packages/bus/src/model-keys.mjs
|
||||
index 560c8474838ca69a88539ecbc44961c2f157a84b..a998576434fa604912732b0131b9e31ca62f08b4 100644
|
||||
--- a/packages/bus/src/model-keys.mjs
|
||||
+++ b/packages/bus/src/model-keys.mjs
|
||||
@@ -36,6 +36,17 @@ export class ModelKeys {
|
||||
if (this.#record(instance)?.state === 'revoking') fail('proxy-key-revoking');
|
||||
if (!this.#ready) fail(this.#failure);
|
||||
}
|
||||
+ // P5's destructive queue read needs this instance's current identity, not
|
||||
+ // an issued agent credential. A sentinel refusal stays closed until explicit
|
||||
+ // reconcile; telemetry never retries around it or performs reconciliation.
|
||||
+ verifyIdentity() {
|
||||
+ return this.#exclusive(async () => {
|
||||
+ if (!this.#ready) fail(this.#failure);
|
||||
+ let keys;
|
||||
+ try { keys = await this.#client.getKeys(); } catch { fail('proxy-down'); }
|
||||
+ this.#sentinel(keys);
|
||||
+ });
|
||||
+ }
|
||||
async #replace(before, after) {
|
||||
this.#sentinel(before); this.#sentinel(after);
|
||||
await this.#client.putKeys(after);
|
||||
diff --git a/packages/bus/src/proxy-usage.mjs b/packages/bus/src/proxy-usage.mjs
|
||||
index 71d9a72fa348cf24003e02d36ebe0c1280597f30..754c8c022185014c39183dae0456ac6235ff87a9 100644
|
||||
--- a/packages/bus/src/proxy-usage.mjs
|
||||
+++ b/packages/bus/src/proxy-usage.mjs
|
||||
@@ -28,7 +28,7 @@ export function createProxyUsage({ store, read, client, records, log, now = Date
|
||||
due = now() + Math.min(...enabled.map(b => b.pollSeconds)) * 1000;
|
||||
try {
|
||||
await loader.load({ usage: 'cliproxy-queue' });
|
||||
- const module = loader.modules('usage')[0], management = client();
|
||||
+ const module = loader.modules('usage')[0], management = await client();
|
||||
if (!module || !management) throw Error('unavailable');
|
||||
const events = await module.read({ client: management });
|
||||
const owners = new Map();
|
||||
diff --git a/packages/bus/src/runtime.mjs b/packages/bus/src/runtime.mjs
|
||||
index c21103a447c2e77fa1b8e487fef1a7c4a0dba6b2..8bb0b0585df10f38d3bf563f3bb6b4dc15ef33ab 100644
|
||||
--- a/packages/bus/src/runtime.mjs
|
||||
+++ b/packages/bus/src/runtime.mjs
|
||||
@@ -384,7 +384,11 @@ export async function startBroker({
|
||||
const keyForRun = (business, run) => modelRuns.get(business + ':' + run)?.keyId ?? null;
|
||||
const usage = await createUsage({ store, dataRoot, businesses, log: usageLog, keyForRun,
|
||||
proxyView: business => proxyUsage?.view(business) ?? null });
|
||||
- proxyUsage = createProxyUsage({ store, log: usageLog, client: () => modelProxyClient,
|
||||
+ proxyUsage = createProxyUsage({ store, log: usageLog, client: async () => {
|
||||
+ if (!modelKeys) return null;
|
||||
+ await modelKeys.verifyIdentity();
|
||||
+ return modelProxyClient;
|
||||
+ },
|
||||
records: () => credentials.status(),
|
||||
read: () => Object.fromEntries(Object.keys(businesses).map(id => [id, settings ? settings.current(id) : businesses[id]])) });
|
||||
// Row 125 (#1619, REQ-LIMIT-3, REQ-LIMIT-4): the limit checks read the organization file at
|
||||
@@ -862,9 +866,10 @@ export async function startBroker({
|
||||
}
|
||||
// One bounded queue read at a time. The service applies the configured
|
||||
// 1..59 second poll deadline; this tick only checks whether a read is due.
|
||||
- usageTimer = setInterval(() => { proxyUsage.tick().catch(() => usageLog({ action: 'proxy.usage', code: 'proxy-usage-read-failed' })); }, 1000);
|
||||
+ const usageTick = () => { proxyUsage.tick().catch(() => usageLog({ action: 'proxy.usage', code: 'proxy-usage-read-failed' })); };
|
||||
+ usageTimer = setInterval(usageTick, 1000);
|
||||
usageTimer.unref();
|
||||
- await proxyUsage.tick();
|
||||
+ usageTick(); // Optional telemetry never blocks the native ready answer.
|
||||
return {
|
||||
broker,
|
||||
credentials,
|
||||
diff --git a/packages/bus/tests/limit-checks.test.mjs b/packages/bus/tests/limit-checks.test.mjs
|
||||
index b9b7660723e4e2fe115cc786b8af2121b23e2403..a0264cc77cb2f9802d42adf4df5dbb01165a5bcc 100644
|
||||
--- a/packages/bus/tests/limit-checks.test.mjs
|
||||
+++ b/packages/bus/tests/limit-checks.test.mjs
|
||||
@@ -327,7 +327,7 @@ test('REQ-LIMIT-3 core reaches limit checks only through the plug-in loader', ()
|
||||
|
||||
test('P5 missing, ambiguous or invalid model key lookup fails closed without leaking a lookup error', async t => {
|
||||
const root=mkdtempSync(join(tmpdir(),'p5-limit-')),store=new Store(root),log=[];t.after(()=>{store.close();rmSync(root,{recursive:true,force:true});});
|
||||
- const key='012345abcdef',doc={plugins:{'limit-check':['token-limit']},launch:{limits:{tokens:{keys:{[key]:{limit:5,since:SINCE}}}}}};
|
||||
+ const key='012345abcdef',doc={plugins:{'limit-check':['daily-quota']},launch:{limits:{tokens:{keys:{[key]:{limit:5,since:SINCE,reset:'00:00',timeZone:'UTC'}}}}}};
|
||||
for(const lookup of [()=>null,()=>['012345abcdef','abcdef012345'],()=> 'msk-private-lookup',()=>{throw Error('PRIVATE-LOOKUP-CANARY');}]) {
|
||||
const l=createLimits({store,read:()=>doc,log:e=>log.push(e),keyForSubject:lookup});
|
||||
assert.deepEqual(await l.mayLaunch('demo',SUBJECT),{allow:false,check:null,code:'proxy-key-refused'});
|
||||
@@ -337,7 +337,7 @@ test('P5 missing, ambiguous or invalid model key lookup fails closed without lea
|
||||
});
|
||||
test('P5 trusted lookup uses the retiring run key rather than the agent current key',async t=>{
|
||||
const root=mkdtempSync(join(tmpdir(),'p5-old-key-')),store=new Store(root);t.after(()=>{store.close();rmSync(root,{recursive:true,force:true});});
|
||||
- const old='012345abcdef',current='abcdef012345',doc={plugins:{'limit-check':['token-limit']},launch:{limits:{tokens:{keys:{[old]:{limit:0,since:SINCE}}}}}};
|
||||
+ const old='012345abcdef',current='abcdef012345',doc={plugins:{'limit-check':['daily-quota']},launch:{limits:{tokens:{keys:{[old]:{limit:0,since:SINCE,reset:'00:00',timeZone:'UTC'}}}}}};
|
||||
const l=createLimits({store,read:()=>doc,log:()=>{},keyForSubject:(_,s)=>s.run==='old-run'?old:current});
|
||||
assert.equal((await l.mayLaunch('demo',SUBJECT)).allow,true);
|
||||
assert.equal((await l.mustStop('demo',SUBJECT,{run:'old-run'})).stop,true);
|
||||
diff --git a/packages/bus/tests/p5-key-context.test.mjs b/packages/bus/tests/p5-key-context.test.mjs
|
||||
index 8b2ebe0947591589f83d5c89b49bbd8fcf261e10..46b7a87c8e9cbfe4515e35be768f619dffc4a2b6 100644
|
||||
--- a/packages/bus/tests/p5-key-context.test.mjs
|
||||
+++ b/packages/bus/tests/p5-key-context.test.mjs
|
||||
@@ -22,7 +22,7 @@ test('P5 broker preserves original plugin subject and derives internal run conte
|
||||
});
|
||||
test('P5 configured key quotas never use a supplied safe-looking ID when trusted metadata lookup is missing',async t=>{
|
||||
const root=mkdtempSync(join(tmpdir(),'p5-no-bypass-')),store=new Store(root);t.after(()=>{store.close();rmSync(root,{recursive:true,force:true});});
|
||||
- const doc={plugins:{'limit-check':['token-limit']},launch:{limits:{tokens:{keys:{[key]:{limit:10,since:'2026-01-01T00:00:00.000Z'}}}}}};
|
||||
+ const doc={plugins:{'limit-check':['daily-quota']},launch:{limits:{tokens:{keys:{[key]:{limit:10,since:'2026-01-01T00:00:00.000Z',reset:'00:00',timeZone:'UTC'}}}}}};
|
||||
const limits=createLimits({store,read:()=>doc,log:()=>{},keyForSubject:()=>null});
|
||||
assert.deepEqual(await limits.mustStop('demo',{instance:'coder',modelKeyId:key},{run:'forged-run'}),{stop:true,check:null,code:'proxy-key-refused'});
|
||||
});
|
||||
@@ -38,7 +38,7 @@ test('P5 internal context resolves exactly current or retained generation; wrong
|
||||
|
||||
test('P5 model-key mustStop without native run context fails closed even when the current key resolves',async t=>{
|
||||
const root=mkdtempSync(join(tmpdir(),'p5-missing-context-')),store=new Store(root);t.after(()=>{store.close();rmSync(root,{recursive:true,force:true});});
|
||||
- const doc={plugins:{'limit-check':['token-limit']},launch:{limits:{tokens:{keys:{[key]:{limit:10,since:'2026-01-01T00:00:00.000Z'}}}}}};
|
||||
+ const doc={plugins:{'limit-check':['daily-quota']},launch:{limits:{tokens:{keys:{[key]:{limit:10,since:'2026-01-01T00:00:00.000Z',reset:'00:00',timeZone:'UTC'}}}}}};
|
||||
const limits=createLimits({store,read:()=>doc,log:()=>{},keyForSubject:()=>key});
|
||||
assert.deepEqual(await limits.mustStop('demo',{instance:'coder'}),{stop:true,check:null,code:'proxy-key-refused'});
|
||||
});
|
||||
diff --git a/packages/business/src/launch.mjs b/packages/business/src/launch.mjs
|
||||
index 4ee37c5c6514bdf541b20e7001873fb5d8e878f3..7871fdda595d23c3645b417dbf96783faac9047e 100644
|
||||
--- a/packages/business/src/launch.mjs
|
||||
+++ b/packages/business/src/launch.mjs
|
||||
@@ -1,5 +1,6 @@
|
||||
// REQ-LIMIT-1: editable concurrency policy, never a compiled-in capacity ceiling.
|
||||
import { requireObject, requireId, requireString, rejectUnknownKeys } from "./util.mjs";
|
||||
+import { isDailyModelQuota } from "../../plugins/src/model-quota.mjs";
|
||||
import { refuse } from "./errors.mjs";
|
||||
|
||||
const name = (value, at) => requireString(value, at, { max: 200 });
|
||||
@@ -67,12 +68,16 @@ export function checkTokenLimits(value, where = "launch.limits.tokens") {
|
||||
if (Object.hasOwn(value, "models")) {
|
||||
out.models = tokenMap(value.models, `${where}.models`, name, (models, at) => tokenMap(models, at, name, tokenLimit));
|
||||
}
|
||||
- // P5: model key IDs are 12 hex characters (including digit-leading IDs).
|
||||
- // A model key may use the daily quota shape; existing account limits retain theirs.
|
||||
- if (Object.hasOwn(value, "keys")) out.keys = tokenMap(value.keys, `${where}.keys`,
|
||||
- (key, at) => /^[a-f0-9]{12}$/.test(key) ? key : requireId(key, at),
|
||||
- (entry, at) => Object.hasOwn(entry ?? {}, "reset") && /^[a-f0-9]{12}$/.test(at.split('.').at(-1))
|
||||
- ? dailyQuota(entry, at) : tokenLimit(entry, at));
|
||||
+ // P5 adds daily model leaves, including digit-leading IDs; plain keys keep
|
||||
+ // their existing account-name schema and cumulative account semantics.
|
||||
+ if (Object.hasOwn(value, "keys")) {
|
||||
+ requireObject(value.keys, `${where}.keys`);
|
||||
+ out.keys = Object.fromEntries(Object.entries(value.keys).map(([key, entry]) => {
|
||||
+ const at = `${where}.keys.${key}`;
|
||||
+ if (isDailyModelQuota(key, entry)) return [key, dailyQuota(entry, at)];
|
||||
+ return [requireId(key, `${where}.keys`), tokenLimit(entry, at)];
|
||||
+ }));
|
||||
+ }
|
||||
// One quota per account; the business read checks each key names launch.account.
|
||||
if (Object.hasOwn(value, "daily")) out.daily = tokenMap(value.daily, `${where}.daily`, requireId, dailyQuota);
|
||||
return out;
|
||||
diff --git a/packages/business/src/organization.mjs b/packages/business/src/organization.mjs
|
||||
index 6d358631d81464dcac98ec0db2388f08e9eceb39..2acb92e417f32f9080396b41d1a2f565272a01d4 100644
|
||||
--- a/packages/business/src/organization.mjs
|
||||
+++ b/packages/business/src/organization.mjs
|
||||
@@ -8,6 +8,7 @@ import { join, dirname } from "node:path";
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { businessFilePath, validateBusinessDocument } from "./business.mjs";
|
||||
import { requireId, sha256, canonicalJson } from "./util.mjs";
|
||||
+import { isDailyModelQuota } from "../../plugins/src/model-quota.mjs";
|
||||
import { checkReplyLimits } from "../../library/src/limits.mjs";
|
||||
|
||||
export class OrganizationError extends Error {
|
||||
@@ -84,7 +85,7 @@ function changes(old, next, path = "") {
|
||||
// P5/Q222: every writer protects per-model-key quotas, including removal/reset.
|
||||
function modelQuotaFence(old, document, actor) {
|
||||
const keys = doc => Object.fromEntries(Object.entries(doc?.launch?.limits?.tokens?.keys ?? {})
|
||||
- .filter(([key]) => /^[a-f0-9]{12}$/.test(key)));
|
||||
+ .filter(([key, entry]) => isDailyModelQuota(key, entry)));
|
||||
if (canonicalJson(keys(old)) === canonicalJson(keys(document))) return;
|
||||
const agents = Object.entries(old.roles ?? {}).flatMap(([instance, entry]) => [instance, `${entry?.definition}.${instance}`]);
|
||||
if (actor === old.human && actor !== "tester" && !agents.includes(actor)) return;
|
||||
diff --git a/packages/plugins/limit-check/daily-quota/index.mjs b/packages/plugins/limit-check/daily-quota/index.mjs
|
||||
index 38b445803d13a05803ec91e11556346e868a2437..096aa2ead37a18cfa17b2e2d43e19fb5604350f6 100644
|
||||
--- a/packages/plugins/limit-check/daily-quota/index.mjs
|
||||
+++ b/packages/plugins/limit-check/daily-quota/index.mjs
|
||||
@@ -4,6 +4,7 @@
|
||||
// timeZone}. A count is every kind summed over the account's known records since the later of the
|
||||
// day's reset and the leaf's `since`; an unknown turn adds nothing and is counted on its own.
|
||||
// It copies token-limit's tally helpers rather than importing a sibling check, so each loads alone.
|
||||
+import { isDailyModelQuota } from '../../src/model-quota.mjs';
|
||||
export const interfaceVersion = 2;
|
||||
|
||||
const KINDS = ['input', 'output', 'cacheWrite', 'cacheRead'];
|
||||
@@ -63,7 +64,7 @@ function windowStart(entry, now) {
|
||||
function leaves(limits) {
|
||||
const daily = limits?.tokens?.daily ?? {};
|
||||
const entries = [...Object.entries(daily).map(([account, entry]) => ({ path: ['tokens', 'daily', account], entry, match: x => x.account === account })),
|
||||
- ...Object.entries(limits?.tokens?.keys ?? {}).filter(([key, entry]) => /^[a-f0-9]{12}$/.test(key) && Object.hasOwn(entry, 'reset'))
|
||||
+ ...Object.entries(limits?.tokens?.keys ?? {}).filter(([key, entry]) => isDailyModelQuota(key, entry))
|
||||
.map(([key, entry]) => ({ path: ['tokens', 'keys', key], entry, match: x => x.modelKeyId === key }))];
|
||||
return entries.map(({ path, entry, match }) => {
|
||||
if (!Number.isSafeInteger(entry?.limit) || entry.limit < 0 || typeof entry.reset !== 'string' || !RESET.test(entry.reset) ||
|
||||
diff --git a/packages/plugins/limit-check/token-limit/index.mjs b/packages/plugins/limit-check/token-limit/index.mjs
|
||||
index 8f26fcb9c7cbcae4c6cf953a6827af53590771be..b20cea356ca7081a6cf571949a0f6aa31dfec89d 100644
|
||||
--- a/packages/plugins/limit-check/token-limit/index.mjs
|
||||
+++ b/packages/plugins/limit-check/token-limit/index.mjs
|
||||
@@ -3,6 +3,7 @@
|
||||
// launch limits and its per-turn usage records, and nothing here reads a file
|
||||
// or a store. A count is every kind summed over the known records since the
|
||||
// limit's `since`; an unknown turn adds nothing and is counted on its own.
|
||||
+import { isDailyModelQuota } from '../../src/model-quota.mjs';
|
||||
export const interfaceVersion = 2;
|
||||
|
||||
const KINDS = ['input', 'output', 'cacheWrite', 'cacheRead'];
|
||||
@@ -31,8 +32,8 @@ function leaves(limits) {
|
||||
// A key is the record's account. Accounts are null until row 126 names them,
|
||||
// so a key limit matches nothing until then.
|
||||
for (const [k, entry] of Object.entries(tokens.keys ?? {}))
|
||||
- if (!Object.hasOwn(entry, 'reset')) out.push({ path: ['tokens', 'keys', k], entry,
|
||||
- match: x => /^[a-f0-9]{12}$/.test(k) ? x.modelKeyId === k : x.account === k, key: true });
|
||||
+ if (!isDailyModelQuota(k, entry)) out.push({ path: ['tokens', 'keys', k], entry,
|
||||
+ match: x => x.account === k, key: true });
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -73,7 +74,7 @@ export function mustStop(args) {
|
||||
// while no record names an account (lead decision 150, Q1).
|
||||
export function report({ limits, records }) {
|
||||
if (!Array.isArray(records)) refuse('bad-records');
|
||||
- const named = records.some(r => r.account != null || r.modelKeyId != null);
|
||||
+ const named = records.some(r => r.account != null);
|
||||
return leaves(limits).map(leaf => {
|
||||
const { path, entry: { limit, since } } = leaf;
|
||||
if (leaf.key && !named) return { path, limit, since, notEnforced: 'no records name a key' };
|
||||
diff --git a/packages/plugins/src/loader.mjs b/packages/plugins/src/loader.mjs
|
||||
index 04731ee91b04329a3956fd751f4d7fb215f845c3..5634a90664ea98022074cd9fff9bbfbd279692e8 100644
|
||||
--- a/packages/plugins/src/loader.mjs
|
||||
+++ b/packages/plugins/src/loader.mjs
|
||||
@@ -162,3 +162,6 @@ export function createLoader({ log, barrier = () => {} }) {
|
||||
|
||||
return { load, loaded, modules, snapshot };
|
||||
}
|
||||
+
|
||||
+// Shared pure plug-in setting classification; no check implementation is loaded.
|
||||
+export { isDailyModelQuota } from "./model-quota.mjs";
|
||||
diff --git a/packages/plugins/src/model-quota.mjs b/packages/plugins/src/model-quota.mjs
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..1350eb56b5947e759ec8d32f0c429813c352f2a9
|
||||
--- /dev/null
|
||||
+++ b/packages/plugins/src/model-quota.mjs
|
||||
@@ -0,0 +1,17 @@
|
||||
+// The new P5 namespace is the validated DAILY leaf, never a twelve-hex name
|
||||
+// alone. Plain {limit,since} keys remain legacy account limits.
|
||||
+const ID = /^[a-f0-9]{12}$/;
|
||||
+const RESET = /^([01]\d|2[0-3]):[0-5]\d$/;
|
||||
+const ZONE = /^[A-Za-z][A-Za-z0-9_+-]*(\/[A-Za-z0-9_+-]+)*$/;
|
||||
+const SINCE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
|
||||
+export function isDailyModelQuota(key, value) {
|
||||
+ if (typeof key !== 'string' || !ID.test(key) || !value || typeof value !== 'object' || Array.isArray(value)
|
||||
+ || Object.keys(value).some(k => !['limit','since','reset','timeZone'].includes(k))
|
||||
+ || !Number.isSafeInteger(value.limit) || value.limit < 0
|
||||
+ || typeof value.since !== 'string' || !SINCE.test(value.since) || Number.isNaN(Date.parse(value.since))
|
||||
+ || new Date(value.since).toISOString() !== value.since
|
||||
+ || typeof value.reset !== 'string' || !RESET.test(value.reset)
|
||||
+ || typeof value.timeZone !== 'string' || !ZONE.test(value.timeZone)) return false;
|
||||
+ try { new Intl.DateTimeFormat('en-US', { timeZone:value.timeZone }); return true; }
|
||||
+ catch { return false; }
|
||||
+}
|
||||
diff --git a/packages/plugins/tests/token-limit.test.mjs b/packages/plugins/tests/token-limit.test.mjs
|
||||
index d8f8d3db7928f034d7126d479f4255637d0f8646..2c08be007564e5d4b223a7f93bcf4b36535fe739 100644
|
||||
--- a/packages/plugins/tests/token-limit.test.mjs
|
||||
+++ b/packages/plugins/tests/token-limit.test.mjs
|
||||
@@ -150,11 +150,11 @@ test("REQ-LIMIT-3 token-limit ignores tokens.daily, which the daily-quota check
|
||||
assert.deepEqual(check.report(a), []);
|
||||
});
|
||||
|
||||
-test('P5 a model key ID limit counts stack records by key ID without an account', () => {
|
||||
- const keyId = '012345abcdef';
|
||||
+test('P5 plain twelve-hex keys keep legacy account matching rather than cumulative model matching', () => {
|
||||
+ const keyId = 'abcdef012345';
|
||||
const args = { business: 'demo', limits: { tokens: { keys: { [keyId]: { limit: 5, since: '2026-10-18T00:00:00.000Z' } } } },
|
||||
- subject: { instance: 'coder', modelKeyId: keyId, account: null }, records: [{ at: '2026-10-18T01:00:00.000Z',
|
||||
- run: 'run', turn: 'turn', modelKeyId: keyId, account: null, status: 'known', input: 5, output: 0, cacheWrite: 0, cacheRead: 0 }] };
|
||||
+ subject: { instance: 'coder', modelKeyId: '012345abcdef', account: keyId }, records: [{ at: '2026-10-18T01:00:00.000Z',
|
||||
+ run: 'run', turn: 'turn', modelKeyId: '012345abcdef', account: keyId, status: 'known', input: 5, output: 0, cacheWrite: 0, cacheRead: 0 }] };
|
||||
assert.equal(check.mayLaunch(args).allow, false);
|
||||
assert.equal(check.report(args)[0].count, 5);
|
||||
});
|
||||
diff --git a/packages/plugins/usage/cliproxy-queue/README.md b/packages/plugins/usage/cliproxy-queue/README.md
|
||||
index 98aa6e8a2757e170dc2a27752e0b474a9fb3fab3..7e1b0c1996b536deb0013d4d58c8ee1d2697ad8e 100644
|
||||
--- a/packages/plugins/usage/cliproxy-queue/README.md
|
||||
+++ b/packages/plugins/usage/cliproxy-queue/README.md
|
||||
@@ -35,8 +35,9 @@ usage cursor, preserved at turn begin and end. The Console exposes `byKey`.
|
||||
A business can set a daily per-key quota at
|
||||
`launch.limits.tokens.keys.<12-hex-key-id>` with `{limit, since, reset, timeZone}`;
|
||||
the human writer stamps `since`. Enable `limit-check: ["daily-quota"]` to apply
|
||||
-that quota. Cumulative model-key limits retain `{limit,since}` and use
|
||||
-`token-limit`. Omitting a limit means no quota. Existing named account keys and
|
||||
+that quota. Plain `{limit,since}` keys leaves remain cumulative legacy account limits, even
|
||||
+when the name is twelve hex characters. They use `token-limit` and never resolve
|
||||
+model metadata. Omitting a limit means no quota. Existing named account keys and
|
||||
`tokens.daily.<account>` retain their existing behavior. Model-key limits and
|
||||
resets are human-only through every organization writer. Missing, ambiguous or
|
||||
foreign run-key metadata fails closed with `proxy-key-refused`; a retiring run
|
||||
@@ -0,0 +1,128 @@
|
||||
[
|
||||
{
|
||||
"bytes": 12448,
|
||||
"git_blob": "c4bb3a75ecd47b94f83dcc4df28f11e252d5f460",
|
||||
"head_git_blob": "cb47c5df6c97fad2a18cf6a482b6976376ea7fa7",
|
||||
"path": "packages/bus/src/limits.mjs",
|
||||
"sha256": "83f6538a40d6b2a341e5755fa19992f091544746db47f1a25ae8d5794ba83547"
|
||||
},
|
||||
{
|
||||
"bytes": 17664,
|
||||
"git_blob": "a998576434fa604912732b0131b9e31ca62f08b4",
|
||||
"head_git_blob": "560c8474838ca69a88539ecbc44961c2f157a84b",
|
||||
"path": "packages/bus/src/model-keys.mjs",
|
||||
"sha256": "ef2711a80200686496ef42b6f154ffd44e3b5b9a983c38e20c19a5cd1a6bb4b8"
|
||||
},
|
||||
{
|
||||
"bytes": 5748,
|
||||
"git_blob": "754c8c022185014c39183dae0456ac6235ff87a9",
|
||||
"head_git_blob": "71d9a72fa348cf24003e02d36ebe0c1280597f30",
|
||||
"path": "packages/bus/src/proxy-usage.mjs",
|
||||
"sha256": "f673bc899f1eea07bb016e77203abfbbf19890079913a52e6c16bf737d25e44f"
|
||||
},
|
||||
{
|
||||
"bytes": 57938,
|
||||
"git_blob": "8bb0b0585df10f38d3bf563f3bb6b4dc15ef33ab",
|
||||
"head_git_blob": "c21103a447c2e77fa1b8e487fef1a7c4a0dba6b2",
|
||||
"path": "packages/bus/src/runtime.mjs",
|
||||
"sha256": "311e722440e1ea6a255b0b2c3788a66299e1f27ed379e41463e4447b659df553"
|
||||
},
|
||||
{
|
||||
"bytes": 23179,
|
||||
"git_blob": "a0264cc77cb2f9802d42adf4df5dbb01165a5bcc",
|
||||
"head_git_blob": "b9b7660723e4e2fe115cc786b8af2121b23e2403",
|
||||
"path": "packages/bus/tests/limit-checks.test.mjs",
|
||||
"sha256": "da07fe8a464e636040eaf676131b2482732f40fa9d0e89d4a413252d9bba4193"
|
||||
},
|
||||
{
|
||||
"bytes": 3776,
|
||||
"git_blob": "bb51ad3527280f0db0449c27eb42474dd8b9e894",
|
||||
"head_git_blob": null,
|
||||
"path": "packages/bus/tests/p5-background.test.mjs",
|
||||
"sha256": "8a7889bb9aacde4faced9ab97faf6603eb7c5f7e1b78df9e5b28279c3b5ebab1"
|
||||
},
|
||||
{
|
||||
"bytes": 2772,
|
||||
"git_blob": "4ee111f7c9ec75dbae24c184c3310b71973fc7c2",
|
||||
"head_git_blob": null,
|
||||
"path": "packages/bus/tests/p5-identity.test.mjs",
|
||||
"sha256": "1d57b286993b4fe7098433703462c1e5bea715c5e4e88c52f6676cc1757fd153"
|
||||
},
|
||||
{
|
||||
"bytes": 6406,
|
||||
"git_blob": "331032ecb48644587057a9ec4799e69d5fa3cdc8",
|
||||
"head_git_blob": null,
|
||||
"path": "packages/bus/tests/p5-key-compatibility.test.mjs",
|
||||
"sha256": "0c55ced6c8f30dbdc6572705f831a5c1a3375116cc169ca3005d36eeda35e737"
|
||||
},
|
||||
{
|
||||
"bytes": 3922,
|
||||
"git_blob": "46b7a87c8e9cbfe4515e35be768f619dffc4a2b6",
|
||||
"head_git_blob": "8b2ebe0947591589f83d5c89b49bbd8fcf261e10",
|
||||
"path": "packages/bus/tests/p5-key-context.test.mjs",
|
||||
"sha256": "6326f25430a4185e7031b5ae9893fc1ab20caa78f89b92e10266a93f165ab0f6"
|
||||
},
|
||||
{
|
||||
"bytes": 5146,
|
||||
"git_blob": "99390f7d565a7d7db5344b574bc5a8623d5fa073",
|
||||
"head_git_blob": null,
|
||||
"path": "packages/bus/tests/p5-telemetry-fixture.mjs",
|
||||
"sha256": "0ba3a1937cd58a907581426a5dfdcd3f6d0ebcec63ef0eeeaa333c625fbdcfab"
|
||||
},
|
||||
{
|
||||
"bytes": 8036,
|
||||
"git_blob": "7871fdda595d23c3645b417dbf96783faac9047e",
|
||||
"head_git_blob": "4ee37c5c6514bdf541b20e7001873fb5d8e878f3",
|
||||
"path": "packages/business/src/launch.mjs",
|
||||
"sha256": "2fbc6643133110236814ba403ac3efb5782b1e5f3c305b71aedd582adab6f9b6"
|
||||
},
|
||||
{
|
||||
"bytes": 14358,
|
||||
"git_blob": "2acb92e417f32f9080396b41d1a2f565272a01d4",
|
||||
"head_git_blob": "6d358631d81464dcac98ec0db2388f08e9eceb39",
|
||||
"path": "packages/business/src/organization.mjs",
|
||||
"sha256": "63ed59a21ed03514c2ea1b51db2e730831dc6a0cf38608156a92e6534f2495b4"
|
||||
},
|
||||
{
|
||||
"bytes": 5708,
|
||||
"git_blob": "096aa2ead37a18cfa17b2e2d43e19fb5604350f6",
|
||||
"head_git_blob": "38b445803d13a05803ec91e11556346e868a2437",
|
||||
"path": "packages/plugins/limit-check/daily-quota/index.mjs",
|
||||
"sha256": "3dc8244502eb42b9d5b94d66bda7cb10f75fde0f83683e9795feb768bdd7072f"
|
||||
},
|
||||
{
|
||||
"bytes": 3944,
|
||||
"git_blob": "b20cea356ca7081a6cf571949a0f6aa31dfec89d",
|
||||
"head_git_blob": "8f26fcb9c7cbcae4c6cf953a6827af53590771be",
|
||||
"path": "packages/plugins/limit-check/token-limit/index.mjs",
|
||||
"sha256": "a40c456dbbbfa010ca23b7c008132958e463f0b9d04088314db2a6a2a4e01895"
|
||||
},
|
||||
{
|
||||
"bytes": 6826,
|
||||
"git_blob": "5634a90664ea98022074cd9fff9bbfbd279692e8",
|
||||
"head_git_blob": "04731ee91b04329a3956fd751f4d7fb215f845c3",
|
||||
"path": "packages/plugins/src/loader.mjs",
|
||||
"sha256": "49346a27e6b5487ba28770c5d983355f9fbe1e2e7921b0bcc50f2b4ed674eaf2"
|
||||
},
|
||||
{
|
||||
"bytes": 1092,
|
||||
"git_blob": "1350eb56b5947e759ec8d32f0c429813c352f2a9",
|
||||
"head_git_blob": null,
|
||||
"path": "packages/plugins/src/model-quota.mjs",
|
||||
"sha256": "127fc77d461ef1d8f62d0686608ad954d96a8763bee3d5c4a0fc14831afd9d67"
|
||||
},
|
||||
{
|
||||
"bytes": 10609,
|
||||
"git_blob": "2c08be007564e5d4b223a7f93bcf4b36535fe739",
|
||||
"head_git_blob": "d8f8d3db7928f034d7126d479f4255637d0f8646",
|
||||
"path": "packages/plugins/tests/token-limit.test.mjs",
|
||||
"sha256": "cf2da1bd44a1591a48a2e5daa690286fd3f9419bf4206703234f3280838ed021"
|
||||
},
|
||||
{
|
||||
"bytes": 2827,
|
||||
"git_blob": "7e1b0c1996b536deb0013d4d58c8ee1d2697ad8e",
|
||||
"head_git_blob": "98aa6e8a2757e170dc2a27752e0b474a9fb3fab3",
|
||||
"path": "packages/plugins/usage/cliproxy-queue/README.md",
|
||||
"sha256": "06a8f869c90e0d5164a025a485a1e40cdef84dfe47926c5a3c38709494535c1b"
|
||||
}
|
||||
]
|
||||
Binary file not shown.
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,312 @@
|
||||
8be7f2b7c210ff8ddf24d86c2e088da5827f5d7160326291f4750e4bb608e112 AGENTS.md
|
||||
c4eb0d3a8ba06097c784ee6e9acf3bb24b4d01e93d7c5a596ace87b23ea30150 RELEASE
|
||||
db1ff3fb9f411012d49796039eb0a967918a756f1d7fe962c1d808a2385d26e1 agents/codex/work/queue-333/r1-repair/CONTROL-MAP.md
|
||||
e89c8ce76419b2858b698031ee138b7209f1132fd0d649138661f69d8cdacaee agents/codex/work/queue-333/r1-repair/GATE-ENTRY.md
|
||||
0ea528625b42b31822b12987c46c761d9bf881f38904bc78a5365464115e102f agents/codex/work/queue-333/r1-repair/RESPONSE.md
|
||||
7c95672a30c0d5c39189c7c7d610ada89cd539dcb9413617071fbb81200fd008 agents/codex/work/queue-333/r1-repair/REVIEW-R1.md
|
||||
7f74eba656d8380410cd500af951832377681b21027a92d7c2bbcfbd8a9cb181 agents/codex/work/queue-333/r1-repair/build-static-packet.py
|
||||
9a2673cc530a2ed046273ac351779e5fc5748ccd003581b7e8ef2eaa73b7597c agents/codex/work/queue-333/r1-repair/priority-guard.mjs
|
||||
4888024bd2945787bd107c677e5791d4836770c1b8c135f3cf6f52dafcf9eadc agents/codex/work/queue-333/r1-repair/run-light.sh
|
||||
0b1d09ce0b5d9cd7fddb5653574b3f582392367762d8185b994b689daff44754 agents/codex/work/queue-333/r1-repair/run-priority.mjs
|
||||
6a86f7c1e32cf8b8bd176608fe1c8ae2f5b2c91e4676cc0dbd9bd452a58cdb0e agents/codex/work/queue-333/r1-repair/run-strict19.sh
|
||||
c32f33ebc78f09a0549b0b0ba185771bf1cdb3149e9579204147f4b827a66a56 agents/codex/work/queue-333/r1-repair/whole-files.txt
|
||||
06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1 agents/codex/work/queue-333/trace-inputs.mjs
|
||||
95e2c9568498cbe628d62f1ef981dfb6819fc9acad0337086b67adc8717208fd docs/plans/2026-10-24_model-proxy-rows.md
|
||||
3038d65cd3e42c858445d92ac25675f7c5ae66babef1ef79799bd17ae59f0b17 docs/plans/2026-10-24_stack-model-proxy.md
|
||||
84e80f3bdcad8bd433951b503ad087705ee74341b374901b1eb8b3cbd6c04333 package-lock.json
|
||||
3baab27d3fe178da625a3bf48c87790d7fa7006098dd568131d5ee9944ac11cb package.json
|
||||
4f8057266af34f6c70ade88fc9bde45e2aff5a58ab3ee3b8a568a532385fc1cf packages/bus/package.json
|
||||
a2ba3a46f12e56139ecae9e55227d00847842aedec50c1d92aaae28844ca48e7 packages/bus/schema.sql
|
||||
232a1c77c2f17011c53b55fc6052f70985598210769d41d7c2c0b535328aad23 packages/bus/src/address.mjs
|
||||
c0144adade79c2cfc6b8247721393f0250b1d64f6c6c04d85738cb80939c42e5 packages/bus/src/broker.mjs
|
||||
ff927da3cf22fbacc9ace77b2e8b803bffc2953fb58cf7ab4e5f6f6493732996 packages/bus/src/business.mjs
|
||||
f3d483f61a24cbc9cce235e1e92889f09b8cecf513fcaf90c741f316f62262e2 packages/bus/src/client.mjs
|
||||
8b8609ae224bd7ed8e01be5a12c24c05291c7536723d7de9b8c9d1a46d630f22 packages/bus/src/console-cli.mjs
|
||||
86b4321dd436b97e389101873197dbab95b3d2202e5ef7da712c4978f4f9159f packages/bus/src/credential-verbs.mjs
|
||||
10485afcf94c29ac9f3d5ba30b12248a2379efd69185ff9fb90e9fed25fe0678 packages/bus/src/credentials.mjs
|
||||
27d7d5322c2f12641e350867d3ac6f838b33832951e69f057e3a7a28b8ac4d5b packages/bus/src/gitea-grant.mjs
|
||||
48337cdbc41d503f17962d3e3ad014183b1286165f97da6fd88b4faa50be3949 packages/bus/src/host-grant.mjs
|
||||
324c05b16253e0fcfc1a0299d1d8ab45850ea723fad1f67bcc07fc031f50d593 packages/bus/src/host-run.mjs
|
||||
271b9781d73cf31cc562a56180e3ebcd725b5fde148a83347a201fdef2fc28af packages/bus/src/human-cli.mjs
|
||||
bb13c146717cdc46d75d157177e400edac4d3e10f14fe511027a25fd44cec885 packages/bus/src/human.mjs
|
||||
56bfc8dcba476886d7de61a1e798aae8e3041c2434c62d44fc40a168d22bb3bd packages/bus/src/interpreter.mjs
|
||||
9919febc7679168e0a72c0ef51983120283e595fea290a5e8e948409bf5c911b packages/bus/src/landing.mjs
|
||||
83f6538a40d6b2a341e5755fa19992f091544746db47f1a25ae8d5794ba83547 packages/bus/src/limits.mjs
|
||||
b753f630301bf125e9e286b4156d0736930dd8fb9cd8eb2ebf316688f9191a07 packages/bus/src/migrations/3b-3c.sql
|
||||
179ffe356d4ff19a49b5ebad39b6c6bfd7771deb8e1b7c55b5e746f039d69e65 packages/bus/src/migrations/3b.sql
|
||||
0423832d05aa68f9191d7362827bd19310001165b895fb2de40b962fe68f9d56 packages/bus/src/migrations/3c-3d.sql
|
||||
d9aacc974d5047790e65c30a90068259bb9396dc92d4904eae3b9c5dbbb2f077 packages/bus/src/migrations/3d-3e.sql
|
||||
bf0b72c606b1a56a1610f09619b0c1118f1f300c636824ea13fd51a4ca6ac4b3 packages/bus/src/migrations/3e-3f.sql
|
||||
82f54b264919e34282bc214e34e9849f701cd3723b9b2f0a0d107c16f939dc05 packages/bus/src/migrations/3f-3g.sql
|
||||
76168e4f9f6b427286ddb8402fd833acadb01d6325a85f60e9ccf8d42fe2d1d0 packages/bus/src/migrations/3g-3h.sql
|
||||
e058e6cea8da7b6e649f3e03f2b81dc5444ee940a64274d0e367124c93545035 packages/bus/src/migrations/3h-3i.sql
|
||||
5ad122ca950e43e066f3d9ed215e73353e6b26de6687b961a8818d69c9465031 packages/bus/src/migrations/3i-3j.sql
|
||||
2e2bb1fe70076f5e24406a18a923b9e55c4192178a0a704a1b9716032676f9d4 packages/bus/src/migrations/3j-3k.sql
|
||||
eb2822c73e527697399691ae520092277ddbd4d2a9a42a0731b3c81cc3569e58 packages/bus/src/migrations/3k-3l.sql
|
||||
791879f06a3e97d3cfbe6112e2fb6502457af30b3e0198e3da1192038906d156 packages/bus/src/migrations/3l-3m.sql
|
||||
b40bc6a7bedc459d6827cbf0414619e48fc5dce2febdeff70a647345f2281c3a packages/bus/src/migrations/3m-3n.sql
|
||||
ef2711a80200686496ef42b6f154ffd44e3b5b9a983c38e20c19a5cd1a6bb4b8 packages/bus/src/model-keys.mjs
|
||||
29c88655e8b9aed8db604573c9213fd9f3c40ef35ff04f4eda8fbe8f1b8a32d7 packages/bus/src/peercred.mjs
|
||||
d1536a8f472fa5b3773adb10555529ed049ad63b647c0b44c00ce5f25ce09f85 packages/bus/src/peercred.py
|
||||
2b1e18be825e8264b16506d6294863acbba812956cfdf8e056f21faaa94f7137 packages/bus/src/principal.mjs
|
||||
ed13afdce6359df31d35a79496ebb4afdefef82030a8326a76b2a25b37e98d9d packages/bus/src/process.mjs
|
||||
cec059ea4bef5ef62f6181123bfe64bca21d8985d5357471da8c0a3199a877f9 packages/bus/src/proxy-page-vocabulary.mjs
|
||||
af36aae674f46a4e5eacfe176fde8b58cd0b171a6d70e07ee6d479e0f558cce7 packages/bus/src/proxy-page.mjs
|
||||
f673bc899f1eea07bb016e77203abfbbf19890079913a52e6c16bf737d25e44f packages/bus/src/proxy-usage.mjs
|
||||
311e722440e1ea6a255b0b2c3788a66299e1f27ed379e41463e4447b659df553 packages/bus/src/runtime.mjs
|
||||
8318bed9168ac3f58c09de40a139b68aacefd684e6c117406e181e2ca5ab4ec7 packages/bus/src/server.mjs
|
||||
dd7fce9706402efd1c5a5b81f7d0fa3793de203e7a6aef4e118e934aebdc7c84 packages/bus/src/store.mjs
|
||||
c04c434ec76252fbc93fb047e7a0c996225590e805f2c82a8d521c161cc9b80b packages/bus/src/tester-cli.mjs
|
||||
5e9e08ca8069e1de35232f26d48a77792388128dda659893909f2d34b5af2346 packages/bus/src/tester.mjs
|
||||
4ae57d053c4b217e1c1a22ada3ed1c5d4a3f0e61b8d2798e9db37997cd071a29 packages/bus/src/usage.mjs
|
||||
38228759eb2030232811669ef44a3c89874c80baf1f6af1da933decc1621e21a packages/bus/src/user-cli.mjs
|
||||
1f31aefa71984fba90c5390df5cc595d929681965f57485ad4972143d5c4b15f packages/bus/src/views.mjs
|
||||
68efa3c9d0a72095f503208ed5c2e660ef9bca68d3ea15f0fc2f1826a68e09cc packages/bus/src/web.mjs
|
||||
dbbfa80b4082fd44e2f08539b5455653fac062321b8f2106f638e2d8161fa3eb packages/bus/tests/daily-quota-runtime.test.mjs
|
||||
da07fe8a464e636040eaf676131b2482732f40fa9d0e89d4a413252d9bba4193 packages/bus/tests/limit-checks.test.mjs
|
||||
561d0950b788d08ad9a79ccd6572ad6976ba4b2e2b1c79d1e4d06827a84c131b packages/bus/tests/limit-stop.test.mjs
|
||||
a2e553025edbe6e930c9d03b48289c53b51b153ac9ae49bb21bf721b725f1913 packages/bus/tests/limits-runtime.test.mjs
|
||||
a8038fbad6fc666d5d033da4b35dffbf5f679eae6d1d6e042bea8d211c298360 packages/bus/tests/model-keys.test.mjs
|
||||
8a7889bb9aacde4faced9ab97faf6603eb7c5f7e1b78df9e5b28279c3b5ebab1 packages/bus/tests/p5-background.test.mjs
|
||||
1d57b286993b4fe7098433703462c1e5bea715c5e4e88c52f6676cc1757fd153 packages/bus/tests/p5-identity.test.mjs
|
||||
0c55ced6c8f30dbdc6572705f831a5c1a3375116cc169ca3005d36eeda35e737 packages/bus/tests/p5-key-compatibility.test.mjs
|
||||
6326f25430a4185e7031b5ae9893fc1ab20caa78f89b92e10266a93f165ab0f6 packages/bus/tests/p5-key-context.test.mjs
|
||||
241e779016ffd0b54c5646cb4fac7e21ea1167e77afbd652ff4e01f8d238f99c packages/bus/tests/p5-runtime.test.mjs
|
||||
0ba3a1937cd58a907581426a5dfdcd3f6d0ebcec63ef0eeeaa333c625fbdcfab packages/bus/tests/p5-telemetry-fixture.mjs
|
||||
895ffddbcca1b38fdaa17eefdeca9092a9b9a934d3a54a3bf7857f42fe99fba7 packages/bus/tests/plugins-verb.test.mjs
|
||||
84c8351029272b6ee05e7fd81b4cc4453553ceeb7a5127a1333dae63d1336ad5 packages/bus/tests/proxy-usage.test.mjs
|
||||
4b2149ea4219f49db19669ada9f88931f7691cdd73dd27dceec6e8fe1f76dd0c packages/bus/tests/usage-broker.test.mjs
|
||||
5abe93fca8442f06ff68760623e91262d863e1191fa35a3d0c87d7b0e6c0a4c6 packages/bus/tests/usage-runtime.test.mjs
|
||||
2613ba0561572a7d4f753066922fddc90cca812cb0ce2b3e0a9a4d249a15e340 packages/bus/tests/usage.test.mjs
|
||||
0e15a5be600573ff7fa0b41c425ee6e57dad788be3d42991185c3a84d6090fe9 packages/business/package.json
|
||||
af028c999a6ab4d42b321c3f047e683b226c7ad232a2ae9cfc623b7dd5a4dd5f packages/business/src/access.mjs
|
||||
aaa4578fd4133f64119de6c8786a14759240a8910677529fdeae57173058b7d9 packages/business/src/business.mjs
|
||||
c3422b1e144177f9dd3015ac036ee1d2cde02bd2b3be406364f3b3f45d8c9b73 packages/business/src/credentials.mjs
|
||||
cd4eb5960c17ce32f26d1a49196866ce04efc42c1d90b18b046af5fda8b9ff0a packages/business/src/errors.mjs
|
||||
e08b11b70b54f13e3b18996dd903f841e04fd6c64791e96063df8b164c663882 packages/business/src/hosts.mjs
|
||||
a386ce5bd1d41d86f7b90641a423a2b651b491c8989d5085412c7d202ac1cb30 packages/business/src/index.mjs
|
||||
09f2bde85a6d7a8f0b1d1c60ac589b845b0c95e991b2f807758878416b13c6bd packages/business/src/instance-settings.mjs
|
||||
e14d73f719664499d809909962a6ecc16d4ffb9d824fcdee699e0778809d9e96 packages/business/src/launch-settings.mjs
|
||||
2fbc6643133110236814ba403ac3efb5782b1e5f3c305b71aedd582adab6f9b6 packages/business/src/launch.mjs
|
||||
93a7fddac9a08b5f740a0a277b29b8a3459e6f5a4fd33a37212437cb456b9b62 packages/business/src/library-seats.mjs
|
||||
44fa089c9024934a2f9fb5ef99552eb18d616842210cbc0fc860ea32ce0b1524 packages/business/src/migrate-launch.mjs
|
||||
63ed59a21ed03514c2ea1b51db2e730831dc6a0cf38608156a92e6534f2495b4 packages/business/src/organization.mjs
|
||||
9d2c68dd21c6c9553af75f4b137c4f169e95761f32528767e0518d0313311f50 packages/business/src/plugin-settings.mjs
|
||||
9472996134c520c31971e66006d1c1683709f6df4f76fe3445bdc97a18637eff packages/business/src/project.mjs
|
||||
712183465fee099606223d84423afc54e3386a0c8e468c68d5ac39c1e676d109 packages/business/src/resolve.mjs
|
||||
b10af84d7422da4d0e8c0a4fea1064eebbc2fac6a838a1b3939b554e22dedfc9 packages/business/src/role.mjs
|
||||
e1f0e70a4bbba8ae2ad6185ab61770b15acda403e90fc708e13027a1e9ec663c packages/business/src/util.mjs
|
||||
f6b15ee8dad2d985c0ae66b1f106ca46cb56ec86ac8cd5dec8a05c887596a421 packages/business/src/vars.mjs
|
||||
de1f04628e400084a46e77fd7e03c7a039f0f80c9e07bb486c9c012f187aa3eb packages/business/src/vocabulary.mjs
|
||||
a6a9971b42ddf176d9415caee3efc2eb16791dead5f0f0557d28449a550aefa1 packages/business/tests/helpers.mjs
|
||||
f0dfe004905dce31317d85d89a05802db878c3472e765e85dc9f1e04166e1df6 packages/business/tests/plugin-settings.test.mjs
|
||||
bc6b3a31e8918d70aced7151b91ac4b39afec4081054024b162acb0e8f8fae07 packages/business/tests/token-limit-settings.test.mjs
|
||||
6c9c952d8637206697bc3273f2ee247185cad624b3db84fe4d2ead0b5c1013b3 packages/cli/package.json
|
||||
c4949a16173d11f9d32d10d3ddd58a181631848b259bef1998820a78f5694808 packages/cli/src/access.mjs
|
||||
15a8ee212fc37cea28e389f60ddb8916f9e1509cdcfb2e522acfe548702a16dc packages/cli/src/app.mjs
|
||||
147a17bbdcbc34efe20a88a4cabe796c101cb63dce621d28103f4de29def4cc2 packages/cli/src/boot-status.mjs
|
||||
1e663b175e18e39ff68c9ac3a65ff71fc777a6c37ebca035fce6a2783d0aaac3 packages/cli/src/cli.mjs
|
||||
d960c2a9df3f7c84deff22dad1f0ab120f95ee365984e390de98eba7292b65a1 packages/cli/src/config.mjs
|
||||
19755f7bb002d8455990c5dc7c458e64aeb95252ec7231a2ed2fd9c638fcb511 packages/cli/src/credentials.mjs
|
||||
c7bdd98a3ddeeb9bc4415d907b92555d723c566eba314075d91486da9b5e85dc packages/cli/src/errors.mjs
|
||||
481d9956698df7765ca8556d57164fb78f131708a09900d5a55b9048b5638f5f packages/cli/src/format.mjs
|
||||
3076a53b9891d4d0e084306567b88ded12c4de53a943c029646a424bf59d8e49 packages/cli/src/git-socket.mjs
|
||||
b586907ca8f351f60dc19ec2683df75d2d70ddb12955d09fb14560c9d3bed3dc packages/cli/src/grants.mjs
|
||||
a0936aee783ff47dd58fc907fefd86f63e571809a3ce5b0d6d931f71e756b15e packages/cli/src/host.mjs
|
||||
60419503898f5e7f3046df5e749098728fbdfea76eb5c53b5dc9b909329abe2e packages/cli/src/hosts.mjs
|
||||
8d6dab8da62b4458477572ca1956adad57bc0b0d308df6eae57477175c345d7a packages/cli/src/instances.mjs
|
||||
373d4c028dfa6d85c748d56f56359789fe2b81987f522ac23747fd37bb5478ed packages/cli/src/launcher.mjs
|
||||
2f291a71f490f2741edada7a3e3788500f8976a08eb8ab1411f6c5982f778260 packages/cli/src/limits.mjs
|
||||
9a043f122e1d49103bab64716d0eb80cfc09da3c91f7e2eb014b0d8ff0b02f3d packages/cli/src/model-proxy.mjs
|
||||
0bdc91dcaa096bd3dc9d08a1dea59893a21f6505c843e698ad9c8daa4b74364b packages/cli/src/model-stall.mjs
|
||||
b325b4f5133d40f8b1288e666ef36c5890f7f3a3de20f1dfc1ca27ec172a6372 packages/cli/src/notifier-process.mjs
|
||||
400f4af8c72915101e00f25c0817534a34e7fcf29f960f5cdd78ed9884707f3f packages/cli/src/notifier.mjs
|
||||
f8d9fc24ccd71494fb2914914949cb08948ae93fb3180b9531eb807c921a6f53 packages/cli/src/plugins.mjs
|
||||
6cfe7fd5086ddb59c5666060c6f8044c2852e0f3d5755b1fa206f7521173f300 packages/cli/src/project.mjs
|
||||
9d03335628ae62e85c5fbc08c2e739ed0bd43b10d486faf397129a56a1b343e0 packages/cli/src/screens.mjs
|
||||
1a30048032f5bb64419ae9716a1692978bc1a137220a094d1900298aca6ba1d7 packages/cli/src/session.mjs
|
||||
58888b7731f8009d4c3f8be2caf4445f13dd8f534e1633f6e2720b259fcc3f92 packages/cli/src/thread.mjs
|
||||
662642a8ce739fcb6c188ad07125a94e008c8a305eced127c8041d472c56e55b packages/cli/src/transport.mjs
|
||||
f9e0c69849633ae36a7a6aa22729a690dc40292178ac3db43accbb131fd7b4ca packages/cli/src/usage.mjs
|
||||
1e1aef2c74434e388d61b03407cd323336d20b7ef2106893d16a39638ee12a64 packages/control-board/package.json
|
||||
8966f1f98ea81b4525345fc4889db5e0e5263ca41b5132ac8dd9bd99a2c88522 packages/control-board/src/discord.mjs
|
||||
6d74b131af360268be748a1f8f7f2b3f5a9180365e7279426640883fc295a676 packages/control-board/src/scan.mjs
|
||||
2eb25c46e85ddadd3bdbdbe605db54a6e09845155384a209622554d78307e583 packages/control-board/src/serve.mjs
|
||||
2ed3790eb877414b8e985ca16031d8963adfb5c9555d415efb76288b76a5e1a6 packages/conversation/package.json
|
||||
a45beb82438bb42d97d1e322010e175e785767664e548b90c4125e98b7660003 packages/conversation/src/client.mjs
|
||||
eaf0772b60bb17fbf9548267c9cfeb0104f92f5cbafdfcb60c1633883eec6432 packages/conversation/src/framing.mjs
|
||||
da336ed2a2a149ff56ac12af2440a8353d4573c33e9069381be60f1a0ca70151 packages/conversation/src/parts.mjs
|
||||
20e781240846298fa65f9a8226b5e1ee1e81338b81229334666d845c17c99ac1 packages/conversation/src/pi.mjs
|
||||
75d0cc982c36b0a81ff23f0da9da1b56906c496250a043f91d3a3b18ffa8e51b packages/conversation/src/reader.mjs
|
||||
96f7b64c2e2c3493e270224542818fd14f042e3cf0ac14788b3f881010bc25b1 packages/conversation/src/records.mjs
|
||||
62b0f7e9f798f584fcc0e4ead0522e44fd113bd0803f2bad92ffa480cadb7527 packages/conversation/src/safe-fs.mjs
|
||||
c24d28a073659640b8b027eb12ad150ba895c3001091b892ecef2ec1da40d5cd packages/conversation/src/terminal.mjs
|
||||
f834ee740e7149e7d2ed976112d0719ce0660270e3b61cf93e1774d112c992a2 packages/conversation/src/transcript.mjs
|
||||
bdbfc8073d2073dd2ca4cb1460e3c376f087fff387d053d883932e5a67f85948 packages/discord/bin/git-credential.mjs
|
||||
a52c6bfc9bd26a3b021d3a96bddb0f5c45845d752ca4579ef04ef60667f110f3 packages/discord/package.json
|
||||
5ab69c4111dd9589a197172ffe6968bf414f41c552b7910e5478a27c446cfaec packages/discord/src/binding.mjs
|
||||
917b0e6c4f100e93f056b925e38d97eacdd8b2596e39fbd3f88c0b62b973d8ed packages/discord/src/errors.mjs
|
||||
c28e04a0055997ea0b34bea1ad2912adb248d5fd43713df1e6f5a661d87949b7 packages/discord/src/git.mjs
|
||||
12684e926574c3fe7f693a03b60d1393df483f5feb4b47c9dd7c5a7ac050aec5 packages/discord/src/journal.mjs
|
||||
aa7c1e328d6664b53e4d9cb5a1ab83c8ff71cc31deb9d3ce91a7dc6715c887aa packages/discord/src/notify.mjs
|
||||
8fa9968862dff77fa6d8be5210c22d13712fd622a8cbc722d167be5be80d0783 packages/discord/src/processing.mjs
|
||||
0b0b8f4dc25b8fbd4d948c962453c63084b0797b0ec5f0420e3f4f174837ccd5 packages/discord/src/rest.mjs
|
||||
ba09d286e707860afa53300f8802ac8e6193ab2d2e7abe9d2b07cbdef3822387 packages/discord/src/setspark.mjs
|
||||
975503616245bb6051f06ecbf47436ce7d030f21af23042df7f3341062df967f packages/discord/src/tools.mjs
|
||||
e5a7b64720872b12b34223549537ace05ebf0ca8a29b2f844d2b7c5cc9ea41f7 packages/discord/src/web.mjs
|
||||
34ef8212e27f052223443c66830839517f7a54ecb6ef7d85795b3e89c65b4d4c packages/harness/package.json
|
||||
e944a4c7a26d1fe55e13ac1eca31dd86c302dc7c868224b8b000b27255976153 packages/harness/src/bundle.mjs
|
||||
32b5090760c95eea0e1232ff36ec13a1d9b58335b2eade621196dec1ebdbe784 packages/harness/src/claude-gate.mjs
|
||||
a74ef2db4093c0c797ba9e7e28e4e4df0ceac9040385f00e60a273f39af9610b packages/harness/src/gate.mjs
|
||||
ce0107c3b21e07925b6543b6b925da8b8768823448d4fcf30b620883cfd2d39e packages/harness/src/mcp-server.mjs
|
||||
fcba4b8dfd9dde947a79f88376d880f383e2a04ee3c0a9ba2fa5af641fe61b35 packages/harness/src/pi-extension.mjs
|
||||
38fe84040a78c3f8a8dcde4339d88db3b5df9ef669d605ad1d92ff3e8b646b40 packages/harness/src/tools.mjs
|
||||
5c9b528fd69a2493f04933fc84f352b1101d276d69d9982806975def614fd740 packages/library/bin/askpass
|
||||
f6208a6b9e233baca38dd0ed9fd435cf2c7a3e34160c2c07cea1fea66893513b packages/library/package.json
|
||||
f710d9600a17f6e2989a289cfe84e58f161d86c7306605946ce05fa71b364eb2 packages/library/src/guard.mjs
|
||||
70c1fe75cb2149c9a074d55a6301d5b66157c2dc2e777b92bac338cce09d89c7 packages/library/src/index-build.mjs
|
||||
98c2c2877549c3e2c5963ec4e49d99ab3b6d6ad54fb3bfae86cf98542207157e packages/library/src/index.mjs
|
||||
98ef45ed61144aaea44d8aea1ac43082b6d340297e46846d01772da38728e530 packages/library/src/limits.mjs
|
||||
def32a176cb70c86248e45908edde22f9c4c5f88575a4af0a396a05f617358bc packages/library/src/links.mjs
|
||||
c83c626c7cdc2a00ba4217c34b889ca0517cd2022d1f8fc9e7d3a14a0293a802 packages/library/src/mapping.mjs
|
||||
26b824d6885e5c6d1b8bd71e754a9fa333c26307693f7e6a0c6a8e6300ecb4ae packages/library/src/mirror.mjs
|
||||
0c8764b03dae0150c56af74bcb113cf583dcbe1fa0c6f7386ef2d48d59a6bd31 packages/library/src/problems.mjs
|
||||
bafe113bee70f17bd249876d6bdd1c08fa051223c2111955e5d5f275bd76bba0 packages/library/src/query.mjs
|
||||
ea126533afb7e74b71419eb943febb6b242eb96fc6917d9df1019db3e7e6ce8d packages/library/src/reader.mjs
|
||||
bfc3de029d3c8f0dcc96c90fde30d6da58bbb5b72d8f13e3f536c0d735c73ca5 packages/library/src/render.mjs
|
||||
7b46f47b5e9d6b554b5d39bce2cd95c4610f5f35b8ab8fdc5a2864b3214be809 packages/library/src/reply-protocol.mjs
|
||||
97e12255f52ad638eeacd152eb26822f9a2aa72cd30e2fed1193f51cd6e56192 packages/library/src/scope.mjs
|
||||
6a3b4de2070e62b1cca1c0ab20f2883d3153fc61608d1bf7670cecea08765b4c packages/library/src/supporting.mjs
|
||||
016bfa5c80572c0baf90ced39cb3d3ec66d395f0be15c2727b9552a9dd849093 packages/library/src/survey.mjs
|
||||
a58f3aec5ed9b3530b363e2fdbd38bc9ded7635d261ab2fca3cb31c45dcd3dfa packages/library/src/sync.mjs
|
||||
a301b7c7e3f42f66cb69d88991220f4e236f25a6e5951c61e79ec4ef2b714198 packages/library/src/write.mjs
|
||||
889ac9589fadf7654d4dbb914f968cbafe4255ed215bd6a9ff3f331757c9017b packages/model-proxy/PIN
|
||||
8fbfb3d1562e9ea824a1bd399b17cb2048c92b125e7699ccf27abdcc6e31e40b packages/model-proxy/package.json
|
||||
f5f86cad661034f223a76352d877fa8d7883bfa921a7a01282347a9a03272441 packages/model-proxy/src/client.mjs
|
||||
a6fb88352018b8f21593a0bb9311f87162c80d8b1e05e62b4d43b1e69af21b23 packages/model-proxy/src/common.mjs
|
||||
00378d2ea95ac4945899696462f8ff4c70dc020cc58d93663d731d2f2f333783 packages/model-proxy/src/fetch.mjs
|
||||
1eac4b5741b360a077bb1c871c008b64f7c7119afc64be4d6e4a0dcdb3a313bb packages/model-proxy/src/settings.mjs
|
||||
e66453cf6662677cf28cbad1ae8f7509917d333e5b80404ab02c53f5cf75e9e1 packages/model-proxy/src/validation.mjs
|
||||
77327681d6eb51f25d7aeffcc532b7e8269c1dc59139cb03adb4a3a1409f63e9 packages/model-proxy/tests/client-probe.test.mjs
|
||||
790c6a50ec030a8b27a28fac7fd129bd9eabe79774adf11d6620c00df9b6ae86 packages/model-proxy/tests/client.test.mjs
|
||||
95e39a519f7ac8b9592876e6157191169f9b14d002163867a6ff6ab808e42c14 packages/model-proxy/tests/management-key-encoding.test.mjs
|
||||
f24e1d121a340cbcaa3f6cd6390eeb7d4b05f778dd498d76ba099cba5a719dea packages/model-proxy/tests/page-client.test.mjs
|
||||
1ad66d56800a31cfbd387939e640653bc72150f4e73822d9e3c777b3bffbf1e1 packages/model-proxy/tests/usage-client.test.mjs
|
||||
5e7e1ec169392ee3065f8f47d19732ebbe8bdd90f9193581425b956e66da6b73 packages/plugins/channel/cli/index.mjs
|
||||
789132601745a94027f9e9184e7fef1f70cff0cba450afed5cca647f683591f4 packages/plugins/channel/webui/index.mjs
|
||||
a317ac544359d321bb91b67cd87fc6ef431b72df9ac9f7f2a9ff291ed1a9109a packages/plugins/harness/claude-code/index.mjs
|
||||
aabaf5c4602e28f025c18b2e2ddd6fa0d1648870101a5de0c4424d97b24472dd packages/plugins/harness/pi/compactions.mjs
|
||||
39c225f157b8f66b416625bda689153505743ffcfdc32964bb1f3d2c6fcb73af packages/plugins/harness/pi/index.mjs
|
||||
3dc8244502eb42b9d5b94d66bda7cb10f75fde0f83683e9795feb768bdd7072f packages/plugins/limit-check/daily-quota/index.mjs
|
||||
a40c456dbbbfa010ca23b7c008132958e463f0b9d04088314db2a6a2a4e01895 packages/plugins/limit-check/token-limit/index.mjs
|
||||
90a9ac59a9ea2287e9a3d4b2f4286d025e727f2a6ce149464f8d0420fd9a8ef1 packages/plugins/package.json
|
||||
8be381a7e5dc7dd5ad18e89bb17f17d4b7074bbac490331fc61c65ac2b824057 packages/plugins/search-source/harness-builtin/index.mjs
|
||||
92618d0cd2f1b79c7d0230ec0ecd80ff628744524847d6b5f33ddbae9d7a3a09 packages/plugins/search-source/searxng-bundled/index.mjs
|
||||
fe4603b69596c3758ef8d7f794e403273e24e0fb950a92f15f8e651e193955ec packages/plugins/search-source/searxng-url/index.mjs
|
||||
5fcecf8336ee247e8ac2f626b21e4c79b1edc49082eadfd536cd23016c6bb756 packages/plugins/src/channel.mjs
|
||||
eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78 packages/plugins/src/kinds.mjs
|
||||
49346a27e6b5487ba28770c5d983355f9fbe1e2e7921b0bcc50f2b4ed674eaf2 packages/plugins/src/loader.mjs
|
||||
127fc77d461ef1d8f62d0686608ad954d96a8763bee3d5c4a0fc14831afd9d67 packages/plugins/src/model-quota.mjs
|
||||
3d4fab56fea4c45c6a317ef41121aa5b6da0502a6ef614b7931f91cafdfc1f71 packages/plugins/tests/daily-quota.test.mjs
|
||||
5d5e5dccdae3f94b8540d187a8899ec36f9c9933cae3933249c2d8c400c75aa2 packages/plugins/tests/helpers.mjs
|
||||
f3081e1dbdac20ade2246c743bcbb3934be686f79f378af21c365cd1451893ba packages/plugins/tests/kinds.test.mjs
|
||||
8588ad7eee0c9ce5de3b53e3b88562812a155a3d791a2bd3413bb1754655d78b packages/plugins/tests/loader.test.mjs
|
||||
cf2da1bd44a1591a48a2e5daa690286fd3f9419bf4206703234f3280838ed021 packages/plugins/tests/token-limit.test.mjs
|
||||
d09ae19db3eb69477783163559bd6a8e5b59a6f5af0eafd62d0e2e3bd325065e packages/plugins/usage-source/transcript/index.mjs
|
||||
06a8f869c90e0d5164a025a485a1e40cdef84dfe47926c5a3c38709494535c1b packages/plugins/usage/cliproxy-queue/README.md
|
||||
6096a577cd5d7e8bf84fd6b98ab284e2f47d5facebd027548e07e6aeec442f96 packages/plugins/usage/cliproxy-queue/index.mjs
|
||||
83aa9ed92f6ea3e1f68a6325ee61250a3167cefb360fd7154b89ed026b1aa8fa packages/processing-control/package.json
|
||||
781973277c09133de15fc39be35b372a79066479097d46923c8ab7782f011dcd packages/processing-control/src/containers.mjs
|
||||
ddc7318297abc4ec4dd03d425820b7323db609e554cfc5341cfdfa6934271e73 packages/processing-control/src/coordinator.mjs
|
||||
3bc600649267f011e21ed8266fb16927b0ad3a0e2c49e4b54062d34c544d0c17 packages/processing-control/src/effects.mjs
|
||||
7145420aa354180689a5c84423928fc60c8123476dcfed3364c9cf4542f8c7ea packages/processing-control/src/runtimes.mjs
|
||||
ed834770fed863cb0c15b75062de1fd63dea940f3b42020b769a7e62b319c8ed packages/processing-control/src/state.mjs
|
||||
13664e88d0f233bcf18f05e75946e70a1f2a7ba8d099248b73936230cefadd8d packages/project/package.json
|
||||
925bb03ac99e5845e4bfa20b4561a331f034f88e187db82213df6602a7ceee4b packages/project/schemas/decision.schema.json
|
||||
f069c012e9660d5d0491a21f98e936b725f6818e1c3136dfec61b3c800bd58de packages/project/schemas/project.schema.json
|
||||
79a1e7b567af7162bb88ca69861075fc579a858e8aec4e49824ccdc370b690c3 packages/project/schemas/requirement.schema.json
|
||||
af6865a4cace92ef27910098507ffedfc8dfe768cea088b1fee21d0876cc556e packages/project/src/git.mjs
|
||||
3ab38cc40ce9ed1a714a59a1f2c336c3792a59431a6a9cc655ba6a2f47513899 packages/project/src/index.mjs
|
||||
bd9debcf3f9bb92560e74f220a0b108dfe24154bc6d1fb03c5ec414356d451f9 packages/project/src/paths.mjs
|
||||
42113cd20eb8f04dd252f9963a6f1a84806af9cae7beb6808c4d584a2548220c packages/project/src/read.mjs
|
||||
e49ab5e825f0706da2f3c8dfcf33c1331a38d77ca2d35b03359ee68ea74652c5 packages/project/src/validate.mjs
|
||||
24b7e3224dba45753e2d6139fcf05d2ed8c29d999752b02a637cfb8489fd9e0a packages/project/templates/north-star.md
|
||||
26ee149f870ff56ad6d1c3d7c3b4b2301879c59f02d5840078c07e7964cc2175 packages/seat/package.json
|
||||
5aca02491fe8df51487968ce62c776d493d0fe693cc41478b84bef7b49c8948d packages/seat/src/checkout.mjs
|
||||
c5de99284b8fa61763b8dd30a58809bbc086529eeb10587586d52b0df2754774 packages/seat/src/compactions.mjs
|
||||
6f7c938a32b349ee49ce95b89ad499e599f6016e5e9d7efd79a9ea4177b4d175 packages/seat/src/landing.mjs
|
||||
382cbf7e0ff336911e288ce858bdbfbec693bc2b69879720d1f0b4c7d8455198 packages/seat/src/proc.mjs
|
||||
0868f393f6fb117d430428ec390e435359737eae0792b4a4d1f54797c7a6c1bf packages/seat/src/sandbox.mjs
|
||||
eec970961a667c9e614d1474d33c31a019b2cf1b0bf931a51458d874bca13a15 packages/seat/src/seat.mjs
|
||||
c37a6ef6f6d2b4e61443e77d800656bf31e38913bf7dbdc4ca955f4a83b13a41 packages/seat/src/session.mjs
|
||||
621f5c223811444336f0f5d6ad10bc7afce075491653c0527d6c26ca568b79c3 packages/seat/src/working.mjs
|
||||
2018701876f26c0566307335eae992efb3551b75af200b7c249b615757bf311a packages/tasks/fields.json
|
||||
269161444d253da7886d83f7b2f7bd79792b6c6b798c6e72f05f69bb99ad5295 packages/tasks/package.json
|
||||
80b58323994d70e8bb496d81225aeb3d2cdfda464654b68b3b082e9af1fac5c1 packages/tasks/requirements.json
|
||||
ff0f30ef6b2f4b758082913c34062d4749a71c157e994a06de692bb70dc8014b packages/tasks/src/adapter.mjs
|
||||
b5580224e931198c7024326135db5bd4f660dfa42834f19e4cd3c08550845bc9 packages/tasks/src/digest.mjs
|
||||
c9a883e9a1649277edce97adca40bca2874df7b5312c70e4ac6f6d4a1c860841 packages/tasks/src/fields.mjs
|
||||
38e7b85650247759f06c09fce205b2970b8368bc81491f51dc6b3c90ba2a846d packages/tasks/src/requirements.mjs
|
||||
c538cb5ac1c9bc96c50b8d6ca01136361369ec463606684a21d81e3b5c2e46a5 packages/tasks/src/startup.mjs
|
||||
39887268258c3b651246b3596a866005fc193cd8ee5f151a02492967069f2d06 packages/tasks/src/sync.mjs
|
||||
1c10dfcd37b0435e199aed2535b71909728ef358dc145ca9eec4f5beb37bfb87 packages/tasks/src/verbs.mjs
|
||||
0d76911dac358d195be4293ae03ae53476ea4d1b0fff4fbdb1a2de33f46ef952 packages/tasks/src/vikunja.mjs
|
||||
0bb346f598380c2bcdb39db92a006959442d3ce5dc645503ef76405aae53311c packages/webui/package.json
|
||||
c521be48ddbc473c61431424838cb9c6d67a0086082141000882013bde62379f packages/webui/src/access.mjs
|
||||
4ebf6c2b5d71c23d85cbde83f69aa671058dc2195c9ae4bdda624f6940729d1b packages/webui/src/bus.mjs
|
||||
3a5321a5f492a98d342e4ddcc1e9da3522cfff89a4f9bc3f51d2ab1426d3de1b packages/webui/src/chat-http.mjs
|
||||
fe2072a7198771a82f58dca5fc05aa4d697dd3db25a206fb2a24c8514010b069 packages/webui/src/chat.mjs
|
||||
5988c015b7f03b56654311039874f8c42a1d93012b330ee389a42fb88af70279 packages/webui/src/cli.mjs
|
||||
79cfb474308d148293b702c0132927acb31ac4f1400fde9a9ee78c99a7a558af packages/webui/src/console-bus.mjs
|
||||
93d4d0c36d0b74eaace24bce4c3e7179b7418377eb4df6d0f6a9ca89d5eb8e39 packages/webui/src/decision-http.mjs
|
||||
c3825a02c3b4f4e5537db4a945439d707e177e74c3e8b1fc2cb777515e610b64 packages/webui/src/processing-http.mjs
|
||||
a09028cd5ca57367f597d0681e84926ca871fd4626769e9947927d949c2b6ab7 packages/webui/src/proxy-http.mjs
|
||||
3c7a35e25b4c1cfda19ac9466d4b2fbc86c880761a1d04ad3ece8bc485f60f93 packages/webui/src/public/bus.js
|
||||
46defeb3b4be0e1a22e4b89445872ad6b15cdee182076e9e6222219ae29997f4 packages/webui/src/reads.mjs
|
||||
7b7bee91604b7bd973027b177de83205db9aed366e694072fc6343b46465b5ba packages/webui/src/serve.mjs
|
||||
37b01ab0479d5f2a7ab9aac790931c6d88c790465392d9c0b65a105513f3e36b packages/webui/src/sso-config.mjs
|
||||
9a3442739e95407deb0afe3e2a2aa77741d40f3eb899db985f45af49c38b34a0 packages/webui/src/sso.mjs
|
||||
1c1fe0c795adac97f28502564a75f26d5666d9be5ae51169f7dd5bb7741fad16 packages/webui/src/tester-socket.mjs
|
||||
b35d3f3471d6d83ef2d19d6102eaecce2ddec9330f337d7194f1d7be03cbd216 packages/webui/tests/fixture.mjs
|
||||
39f50991578b98594183390a00efbca84fda90ef61617eea4215e2c75f90b82c packages/webui/tests/usage-render.test.mjs
|
||||
f96d06974bc83051c0d5c9000e38161ea0cc231997410bcc6c42ed7f55718dfd packages/webui/tests/usage.test.mjs
|
||||
5f63ff52aaccf06a0f2415ffdd9d1903c202679cf953bef5266a6841b5e39ab7 roles/assistant.json
|
||||
7d2d50a1278c62daa4f6c4a5ac7809817409f2f1d0d75787802300739d3fba15 roles/assistant.md
|
||||
314074c8081953923f962f2df045d4c14629010ea99d1f23449ed45294b46bcc roles/chief-executive-officer.json
|
||||
a6bc3aad543cfb3a03f93efda60859221c56f78d0f1094da33afd458399b4ffa roles/chief-executive-officer.md
|
||||
539d531a0f5744aebb933ca685b52022554e3e93ae54cc8b67e4de0eb27d3460 roles/chief-financial-officer.json
|
||||
09347759baf8fdbf0a8105106e8d27b500f3d0b76dcaa91dc2cdc20b3b000b00 roles/chief-financial-officer.md
|
||||
8ee8e7213d4c073e2d9ba7732fd84b3b3130d9bbb930d07595b7f692bb9fc5dc roles/chief-information-officer.json
|
||||
0a7041dd3ae5f05ba6f37baa2aeeca35a430ed3e387a3e2407daae2c431efda2 roles/chief-information-officer.md
|
||||
a550428603979f4342e57ad9ccddd4d2e44a5203a64f19027ce09a24f1dbfc0e roles/chief-information-security-officer.json
|
||||
1da83baca46abb75c6b2e74df7a3fb9424e1556ce37ff5f8c7802e85100d6b16 roles/chief-information-security-officer.md
|
||||
3cdd799159d3e676529efee01f467a4ed7d67920253cddba2e098566368a1e36 roles/chief-marketing-officer.json
|
||||
4d414c02485b6a83f9d8fc2498a53d275019fd45e9ad948fdf61777a3a983bfa roles/chief-marketing-officer.md
|
||||
c781c4108824db7f17cc4b514e3b0d446120dc1ad7c05e5bf5a72edcac70d054 roles/chief-of-staff.json
|
||||
db16c358820e199910eabe06f885a53a4bde2502aeafa5444c12d9b29c74880c roles/chief-of-staff.md
|
||||
13713c4e64ade3b1b1eedabed75f5f76fe65e73f6df336b771d1e34881d111f3 roles/coder.json
|
||||
d29d469aaae2a97705dd0d5b057b6eef20c5f22d37791aaee9d886c8bb46700f roles/coder.md
|
||||
962f1e8ca9d56d7ad7dd4f82a57b97b834bacdc72c3fe774f9a9afccf7dd72e9 roles/companion.json
|
||||
cad0360c16db9b2659370e6363937a27d61e9f6c4fae711a2dfc5b89aadead81 roles/companion.md
|
||||
42e751413a649e03c5e1eb87acdf59e0a0fcd54f519bca297463f88ee07e3043 roles/conductor-policy.json
|
||||
031807451adfe5e4643da2ff59fab0a041fce519f4cb84d749ec6f10edff8f36 roles/continuity.json
|
||||
75522c66ccd242971b4b00786112ef37b41c972af5b0d98c011697169fba7db2 roles/continuity.md
|
||||
60b6482a29a578234b4e5bf0d4c9a123bd3a65a65dc6e488f474546cf4456bb2 roles/cto.json
|
||||
b5603cbdfc1a79d4b986c97aa2a94e2c57164f9abfd5117b348086025dd50993 roles/cto.md
|
||||
1dfc6629dc70dd8020483456db140751010e81a44fbd49308580f0c6356c2471 roles/fact-checker.json
|
||||
2d01f771831d52a1d9ddde8c1183601051782efd39899605949761fdd5e07291 roles/fact-checker.md
|
||||
2c69c26460574948584eae487e944b7240cfa37a0a0f3ddeaabd682815ebf6ed roles/ideas.json
|
||||
bb403867a2ba33ea271d2d576165c6131e43446f2d5deb4eb86389398cb0592d roles/ideas.md
|
||||
14dbbbaa98670ebab8612555e3f813793ff12caf6a3aaef3883c2007ebc9bfe8 roles/merge-gate.json
|
||||
b8bbccbf7e10e090f3514664384cba44c86fbb514c79d182d31a209045fdcc1d roles/merge-gate.md
|
||||
1af1cb70512163eb5c39ae942496a4cc309b0b1d47b9cb48253ac788862f0e9f roles/pm.json
|
||||
d1016f8c34ee04601ab751c7514a20dfbeec0359d46dba8f94c44538dcc16133 roles/pm.md
|
||||
3a55947b867241dd42b78588276f6f901d374b519f3964ba0acc4b782513224c roles/proofreader.json
|
||||
054f6f888064eca4c6b7b1c0180bd2ad968b10429f045db7aaa92453cbddd1ab roles/proofreader.md
|
||||
38d36d8cca7f4f7141af5469f0a17dd2a44a5ec26ef113ad9a01c9b013968501 roles/research.json
|
||||
2a66291a7a8d21b9f587c6226d408667a775b2846bc9950606e73b210f4ac0d1 roles/research.md
|
||||
3b5f0c39b72eb1ef1d546899ea5b02da6ce0c22a5d30d67058530b1bdc67964f roles/researcher.json
|
||||
4d2b2ab1208aced3a82d7de1ace879574fae2930ac1bc684f76e1d16e58cec8f roles/reviewer.json
|
||||
f7418c27a5b84f258041b87e87ccf9f441fcb9c638a322e50aafcfdb0ce7f364 roles/reviewer.md
|
||||
d84bd99dda657fc44b6272cc35a89c490315117c7102d8936042ac1cf58978cb roles/security-reviewer.json
|
||||
eb5ad42d4fcd98a2c89afb8b2286edc5eb666f993e21fbbda838e5c472f34dd8 roles/security-reviewer.md
|
||||
@@ -0,0 +1,17 @@
|
||||
3eb9b8d10445aa328be3b854385e4792dda2c5712b19d443d485d1b00a18d0f8 INDEX.json
|
||||
9b64bfe45f20f59ae62812529c5f4ef4a41f29ea9124cf42dd6e9c32f5089711 baseline-controls.patch
|
||||
add6f177692f774a0a4370c95d28d3e72a3aa4e76adab886ed6bdcc01a965e2b baseline-input-bytes.tar.gz
|
||||
9f18698d9b327c8664461decf939e7fcbb6a756e81f93e88dc1d2d51511a7ea8 baseline-inputs.json
|
||||
a287f6218039b825bb84c5902d68f0659cbedc9c89d5c2cff6e63fd0a64dfeed baseline-inputs.sha256
|
||||
f3808e3a13fc9244f2301a8f6237fd07d5ed62f496765ef6c281f245713b7e68 baseline-to-fixed.patch
|
||||
42f770fc3e2384362efd1e416091355c064b6cca22dd40f3b5ef8f7b67e43a52 changed-source-tests.json
|
||||
ce03510187334794f10c57b3ce022cbb31fb0324a50e9a225a1c8bb9a06540c4 fixed-input-bytes.tar.gz
|
||||
505c022b46d0871d979c1dc9455a5d0a34ba5442fdeb5bc6195509e56a06b3b2 fixed-inputs.json
|
||||
8f47fbe78ca155f2bc45f5c76e0cc2204af655b5485fc4bb55db5b21f2f7095f fixed-inputs.sha256
|
||||
fcbb8633c9cf0bdee9aeb1bfa8026c868c880cdbeea5369fa35928a9e87daacb preserved-base-test-prefixes.json
|
||||
e7edd87316c9617caf2d30f7f8fc2ef38a6e918a781173bd40b251a81f878f6d r1-raw-evidence-bytes.tar.gz
|
||||
e2d81fd97a93d13805fe009428dcab77cafd2e99f6f9330b8ae08bc56af06306 r1-raw-evidence.json
|
||||
a78bc385801b64be270fb9d6e84672c443738a5fce8eb68f7d2a01359a57a770 source-tests.patch
|
||||
3a1878a64719ad3c733c4e6a7b3fee091fb97be5591e126a6d2cb971262fc8b1 static-dependencies.json
|
||||
521a779bb862349c137bd3cce0e319e7565c80657c437cc794bf3f9848689319 static-overlay-check.json
|
||||
c32f33ebc78f09a0549b0b0ba185771bf1cdb3149e9579204147f4b827a66a56 whole-files.txt
|
||||
@@ -0,0 +1,4 @@
|
||||
[
|
||||
"packages/bus/tests/limit-checks.test.mjs",
|
||||
"packages/plugins/tests/token-limit.test.mjs"
|
||||
]
|
||||
Binary file not shown.
@@ -0,0 +1,72 @@
|
||||
[
|
||||
{
|
||||
"bytes": 3307,
|
||||
"git_blob": "00f2b35bb3b5187909e724f042062feb057a6d7a",
|
||||
"head_git_blob": null,
|
||||
"path": "agents/codex/work/queue-333/r1-repair/receipts/01-identity-red.txt",
|
||||
"sha256": "ec0fb03d34a3fa31bfa8305676fb932cb3ca3c52fc3ed663b7ae56d946585b77"
|
||||
},
|
||||
{
|
||||
"bytes": 4537,
|
||||
"git_blob": "f10567852cfd3ff9adb288b73c0e0b6d37eb391d",
|
||||
"head_git_blob": null,
|
||||
"path": "agents/codex/work/queue-333/r1-repair/receipts/02-fresh-identity-red.txt",
|
||||
"sha256": "6693e5e29d26c789c3469664c70d1c77246456774641985bc07737c960f9042f"
|
||||
},
|
||||
{
|
||||
"bytes": 5219,
|
||||
"git_blob": "296f6ece0dbb17f656a3fbe07be71197fd0dd3e1",
|
||||
"head_git_blob": null,
|
||||
"path": "agents/codex/work/queue-333/r1-repair/receipts/03-identity-green.txt",
|
||||
"sha256": "06c7727d4058447e299a4110ae24d71c390e5ef4851231ddb2c725737738c645"
|
||||
},
|
||||
{
|
||||
"bytes": 6536,
|
||||
"git_blob": "0f41601f8893466afd3853c4cfe5a0eead00341f",
|
||||
"head_git_blob": null,
|
||||
"path": "agents/codex/work/queue-333/r1-repair/receipts/04-legacy-account-red.txt",
|
||||
"sha256": "76d8a88b81caef26568191b8b9b76447e881b8073907b3bdabb986b929a2dd51"
|
||||
},
|
||||
{
|
||||
"bytes": 6757,
|
||||
"git_blob": "ee3b3cb6b042306c62c7d89861b78a13e28c13be",
|
||||
"head_git_blob": null,
|
||||
"path": "agents/codex/work/queue-333/r1-repair/receipts/05-legacy-fence-behavior-red.txt",
|
||||
"sha256": "a8dabd0f59035d90de5bcc4680d9c9c5dee867e7e0edf521331c41544e54079a"
|
||||
},
|
||||
{
|
||||
"bytes": 839,
|
||||
"git_blob": "2fbd8bad453f3ab8893afb2951fc2a2b78a524fc",
|
||||
"head_git_blob": null,
|
||||
"path": "agents/codex/work/queue-333/r1-repair/receipts/06-legacy-account-green.txt",
|
||||
"sha256": "be88ca17efc4fc18f5d011afc5ab6f519f26fe0da496631558204c0db81cc655"
|
||||
},
|
||||
{
|
||||
"bytes": 1046,
|
||||
"git_blob": "4d24f1b251ffdba83a19bbddd99f9258b187acb8",
|
||||
"head_git_blob": null,
|
||||
"path": "agents/codex/work/queue-333/r1-repair/receipts/07-legacy-strict19.txt",
|
||||
"sha256": "198c1d8b28df8c9f301fd99f559ff222515de4fbff346ba36c717c366339f0df"
|
||||
},
|
||||
{
|
||||
"bytes": 308,
|
||||
"git_blob": "b178ce53cd6ee0d645d4b8997a4b6fd87843e1d0",
|
||||
"head_git_blob": null,
|
||||
"path": "agents/codex/work/queue-333/r1-repair/receipts/07-priority-native.jsonl",
|
||||
"sha256": "cf338f68c02eb89ca1722aa32a529ece28c7e8c341585d47cae53a2adfa296b3"
|
||||
},
|
||||
{
|
||||
"bytes": 14879,
|
||||
"git_blob": "65fb63c1351da0bc799eb7ea410007ab7d7c7197",
|
||||
"head_git_blob": null,
|
||||
"path": "agents/codex/work/queue-333/r1-repair/REVIEW-R1.md",
|
||||
"sha256": "7c95672a30c0d5c39189c7c7d610ada89cd539dcb9413617071fbb81200fd008"
|
||||
},
|
||||
{
|
||||
"bytes": 57857,
|
||||
"git_blob": "3c032a8c18da6645abf0e8fc80b157b3bdc40efd",
|
||||
"head_git_blob": null,
|
||||
"path": "agents/codex/work/queue-333/r1-repair/baselines/runtime-before-background-fix.mjs",
|
||||
"sha256": "b493137828a70fbb7eeece7d4fe5628ebc8f98a9997882bb3be010b2ae7eed4f"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,558 @@
|
||||
diff --git a/packages/bus/src/limits.mjs b/packages/bus/src/limits.mjs
|
||||
index cb47c5df6c97fad2a18cf6a482b6976376ea7fa7..c4bb3a75ecd47b94f83dcc4df28f11e252d5f460 100644
|
||||
--- a/packages/bus/src/limits.mjs
|
||||
+++ b/packages/bus/src/limits.mjs
|
||||
@@ -12,7 +12,7 @@
|
||||
//
|
||||
// refresh, mayLaunch and mustStop are async: they re-read the file and reload first. report is
|
||||
// sync, so the organization verbs stay sync; it uses the modules the last refresh loaded.
|
||||
-import { createLoader } from '../../plugins/src/loader.mjs';
|
||||
+import { createLoader, isDailyModelQuota } from '../../plugins/src/loader.mjs';
|
||||
import { turnRecords } from './usage.mjs';
|
||||
|
||||
const KIND = 'limit-check';
|
||||
@@ -122,8 +122,9 @@ export function createLimits({ store, read, log, makeLoader = createLoader, keyF
|
||||
log({ event: 'limit-check-failed', business, check: st.missing, export: name, code: 'not-loaded' });
|
||||
return halt({ check: st.missing, code: 'not-loaded' });
|
||||
}
|
||||
+ if (!st.checks.length) return { [key]: go };
|
||||
const leaves = limitLeaves(st.limits);
|
||||
- if (Object.keys(st.limits?.tokens?.keys ?? {}).some(k => /^[a-f0-9]{12}$/.test(k))) {
|
||||
+ if (Object.entries(st.limits?.tokens?.keys ?? {}).some(([k, entry]) => isDailyModelQuota(k, entry))) {
|
||||
let modelKeyId;
|
||||
try {
|
||||
if (name === 'mustStop' && (typeof context?.run !== 'string' || !context.run)) throw new Failure('proxy-key-refused');
|
||||
diff --git a/packages/bus/src/model-keys.mjs b/packages/bus/src/model-keys.mjs
|
||||
index 560c8474838ca69a88539ecbc44961c2f157a84b..a998576434fa604912732b0131b9e31ca62f08b4 100644
|
||||
--- a/packages/bus/src/model-keys.mjs
|
||||
+++ b/packages/bus/src/model-keys.mjs
|
||||
@@ -36,6 +36,17 @@ export class ModelKeys {
|
||||
if (this.#record(instance)?.state === 'revoking') fail('proxy-key-revoking');
|
||||
if (!this.#ready) fail(this.#failure);
|
||||
}
|
||||
+ // P5's destructive queue read needs this instance's current identity, not
|
||||
+ // an issued agent credential. A sentinel refusal stays closed until explicit
|
||||
+ // reconcile; telemetry never retries around it or performs reconciliation.
|
||||
+ verifyIdentity() {
|
||||
+ return this.#exclusive(async () => {
|
||||
+ if (!this.#ready) fail(this.#failure);
|
||||
+ let keys;
|
||||
+ try { keys = await this.#client.getKeys(); } catch { fail('proxy-down'); }
|
||||
+ this.#sentinel(keys);
|
||||
+ });
|
||||
+ }
|
||||
async #replace(before, after) {
|
||||
this.#sentinel(before); this.#sentinel(after);
|
||||
await this.#client.putKeys(after);
|
||||
diff --git a/packages/bus/src/proxy-usage.mjs b/packages/bus/src/proxy-usage.mjs
|
||||
index 71d9a72fa348cf24003e02d36ebe0c1280597f30..754c8c022185014c39183dae0456ac6235ff87a9 100644
|
||||
--- a/packages/bus/src/proxy-usage.mjs
|
||||
+++ b/packages/bus/src/proxy-usage.mjs
|
||||
@@ -28,7 +28,7 @@ export function createProxyUsage({ store, read, client, records, log, now = Date
|
||||
due = now() + Math.min(...enabled.map(b => b.pollSeconds)) * 1000;
|
||||
try {
|
||||
await loader.load({ usage: 'cliproxy-queue' });
|
||||
- const module = loader.modules('usage')[0], management = client();
|
||||
+ const module = loader.modules('usage')[0], management = await client();
|
||||
if (!module || !management) throw Error('unavailable');
|
||||
const events = await module.read({ client: management });
|
||||
const owners = new Map();
|
||||
diff --git a/packages/bus/src/runtime.mjs b/packages/bus/src/runtime.mjs
|
||||
index c21103a447c2e77fa1b8e487fef1a7c4a0dba6b2..8bb0b0585df10f38d3bf563f3bb6b4dc15ef33ab 100644
|
||||
--- a/packages/bus/src/runtime.mjs
|
||||
+++ b/packages/bus/src/runtime.mjs
|
||||
@@ -384,7 +384,11 @@ export async function startBroker({
|
||||
const keyForRun = (business, run) => modelRuns.get(business + ':' + run)?.keyId ?? null;
|
||||
const usage = await createUsage({ store, dataRoot, businesses, log: usageLog, keyForRun,
|
||||
proxyView: business => proxyUsage?.view(business) ?? null });
|
||||
- proxyUsage = createProxyUsage({ store, log: usageLog, client: () => modelProxyClient,
|
||||
+ proxyUsage = createProxyUsage({ store, log: usageLog, client: async () => {
|
||||
+ if (!modelKeys) return null;
|
||||
+ await modelKeys.verifyIdentity();
|
||||
+ return modelProxyClient;
|
||||
+ },
|
||||
records: () => credentials.status(),
|
||||
read: () => Object.fromEntries(Object.keys(businesses).map(id => [id, settings ? settings.current(id) : businesses[id]])) });
|
||||
// Row 125 (#1619, REQ-LIMIT-3, REQ-LIMIT-4): the limit checks read the organization file at
|
||||
@@ -862,9 +866,10 @@ export async function startBroker({
|
||||
}
|
||||
// One bounded queue read at a time. The service applies the configured
|
||||
// 1..59 second poll deadline; this tick only checks whether a read is due.
|
||||
- usageTimer = setInterval(() => { proxyUsage.tick().catch(() => usageLog({ action: 'proxy.usage', code: 'proxy-usage-read-failed' })); }, 1000);
|
||||
+ const usageTick = () => { proxyUsage.tick().catch(() => usageLog({ action: 'proxy.usage', code: 'proxy-usage-read-failed' })); };
|
||||
+ usageTimer = setInterval(usageTick, 1000);
|
||||
usageTimer.unref();
|
||||
- await proxyUsage.tick();
|
||||
+ usageTick(); // Optional telemetry never blocks the native ready answer.
|
||||
return {
|
||||
broker,
|
||||
credentials,
|
||||
diff --git a/packages/bus/tests/limit-checks.test.mjs b/packages/bus/tests/limit-checks.test.mjs
|
||||
index b9b7660723e4e2fe115cc786b8af2121b23e2403..a0264cc77cb2f9802d42adf4df5dbb01165a5bcc 100644
|
||||
--- a/packages/bus/tests/limit-checks.test.mjs
|
||||
+++ b/packages/bus/tests/limit-checks.test.mjs
|
||||
@@ -327,7 +327,7 @@ test('REQ-LIMIT-3 core reaches limit checks only through the plug-in loader', ()
|
||||
|
||||
test('P5 missing, ambiguous or invalid model key lookup fails closed without leaking a lookup error', async t => {
|
||||
const root=mkdtempSync(join(tmpdir(),'p5-limit-')),store=new Store(root),log=[];t.after(()=>{store.close();rmSync(root,{recursive:true,force:true});});
|
||||
- const key='012345abcdef',doc={plugins:{'limit-check':['token-limit']},launch:{limits:{tokens:{keys:{[key]:{limit:5,since:SINCE}}}}}};
|
||||
+ const key='012345abcdef',doc={plugins:{'limit-check':['daily-quota']},launch:{limits:{tokens:{keys:{[key]:{limit:5,since:SINCE,reset:'00:00',timeZone:'UTC'}}}}}};
|
||||
for(const lookup of [()=>null,()=>['012345abcdef','abcdef012345'],()=> 'msk-private-lookup',()=>{throw Error('PRIVATE-LOOKUP-CANARY');}]) {
|
||||
const l=createLimits({store,read:()=>doc,log:e=>log.push(e),keyForSubject:lookup});
|
||||
assert.deepEqual(await l.mayLaunch('demo',SUBJECT),{allow:false,check:null,code:'proxy-key-refused'});
|
||||
@@ -337,7 +337,7 @@ test('P5 missing, ambiguous or invalid model key lookup fails closed without lea
|
||||
});
|
||||
test('P5 trusted lookup uses the retiring run key rather than the agent current key',async t=>{
|
||||
const root=mkdtempSync(join(tmpdir(),'p5-old-key-')),store=new Store(root);t.after(()=>{store.close();rmSync(root,{recursive:true,force:true});});
|
||||
- const old='012345abcdef',current='abcdef012345',doc={plugins:{'limit-check':['token-limit']},launch:{limits:{tokens:{keys:{[old]:{limit:0,since:SINCE}}}}}};
|
||||
+ const old='012345abcdef',current='abcdef012345',doc={plugins:{'limit-check':['daily-quota']},launch:{limits:{tokens:{keys:{[old]:{limit:0,since:SINCE,reset:'00:00',timeZone:'UTC'}}}}}};
|
||||
const l=createLimits({store,read:()=>doc,log:()=>{},keyForSubject:(_,s)=>s.run==='old-run'?old:current});
|
||||
assert.equal((await l.mayLaunch('demo',SUBJECT)).allow,true);
|
||||
assert.equal((await l.mustStop('demo',SUBJECT,{run:'old-run'})).stop,true);
|
||||
diff --git a/packages/bus/tests/p5-background.test.mjs b/packages/bus/tests/p5-background.test.mjs
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..bb51ad3527280f0db0449c27eb42474dd8b9e894
|
||||
--- /dev/null
|
||||
+++ b/packages/bus/tests/p5-background.test.mjs
|
||||
@@ -0,0 +1,51 @@
|
||||
+// Prepared after Mos1971 STOP. These controls have NOT been executed locally.
|
||||
+// Only fake loopback HTTP, explicit event barriers and virtual existing timers.
|
||||
+import test from 'node:test';
|
||||
+import assert from 'node:assert/strict';
|
||||
+import { createHash } from 'node:crypto';
|
||||
+import { mkdirSync, writeFileSync } from 'node:fs';
|
||||
+import { join } from 'node:path';
|
||||
+import { startTimeOf } from '../../seat/src/proc.mjs';
|
||||
+import { telemetryFixture } from './p5-telemetry-fixture.mjs';
|
||||
+async function nativeTurn(f) {
|
||||
+ const model=await f.bus.modelPreflight({business:'demo',role:'coder'});
|
||||
+ const keyId=createHash('sha256').update(model.key).digest('hex').slice(0,12),dir=join(f.root,'native-transcript');mkdirSync(dir);
|
||||
+ const {cap}=f.bus.bindLaunch({business:'demo',role:'coder',run:'held-poll-native',harness:'pi',modelKeyId:keyId,transcript:dir,
|
||||
+ pid:process.pid,startTime:startTimeOf(process.pid)});
|
||||
+ f.bus.broker.request(cap,{verb:'role.claim'});
|
||||
+ assert.deepEqual(await f.bus.mayLaunch({business:'demo',instance:'coder',provider:'fixture',model:'fake'}),{allow:true});
|
||||
+ const human=f.human(),{id}=f.bus.broker.request(human,{verb:'message.send',args:{to:'coder',body:'native work while optional queue is held'}});
|
||||
+ f.bus.broker.request(cap,{verb:'message.receive'});
|
||||
+ await f.bus.broker.request(cap,{verb:'usage.begin',args:{turn:id}});
|
||||
+ writeFileSync(join(dir,'native.jsonl'),JSON.stringify({type:'message',id:'native',message:{role:'assistant',usage:{input:2,output:1,cacheRead:0,cacheWrite:0}}})+'\n');
|
||||
+ await f.bus.broker.request(cap,{verb:'usage.end',args:{turn:id}});
|
||||
+ const view=f.bus.broker.request(human,{verb:'usage'});
|
||||
+ assert.equal(view.total.input,2);assert.equal(view.byKey[0].modelKeyId,keyId);
|
||||
+ assert.deepEqual(f.bus.broker.request(cap,{verb:'message.receive'}),[]);
|
||||
+}
|
||||
+for(const fail of [false,true])test(`P5 R1 held first optional poll does not delay native startup or work; ${fail?'failure':'release'} settles safely`,async t=>{
|
||||
+ t.mock.timers.enable({apis:['Date','setInterval'],now:Date.now()});
|
||||
+ const f=await telemetryFixture(t,{hold:true});const started=f.start();
|
||||
+ await f.waitQueue(1);await new Promise(setImmediate);
|
||||
+ // Causal first guard: the queue is still held, so a ready runtime cannot
|
||||
+ // have depended on its response. No racing timeout or longer budget.
|
||||
+ assert.notEqual(f.bus,null,'startBroker must resolve while the first queue response is held');
|
||||
+ await started;assert.equal(f.state.held.length,1);
|
||||
+ assert.equal(f.bus.broker.request(f.human(),{verb:'plugins'}).plugins.usage,'cliproxy-queue');
|
||||
+ await nativeTurn(f);assert.equal(f.queueCalls(),1);
|
||||
+ t.mock.timers.tick(1000);await new Promise(setImmediate);assert.equal(f.queueCalls(),1,'scheduled ticks share the held first read');
|
||||
+ const from=f.logs.length;f.release(fail);
|
||||
+ await f.waitLog(fail?'proxy-usage-read-failed':'proxy.usage.reconcile',from);
|
||||
+ assert.equal(f.bus.broker.request(f.human(),{verb:'usage'}).proxy.state,fail?'unavailable':'available');
|
||||
+ await f.close();assert.equal(f.queueCalls(),1);
|
||||
+});
|
||||
+test('P5 R1 close bounds an outstanding first poll by the unchanged five-second client deadline',async t=>{
|
||||
+ t.mock.timers.enable({apis:['Date','setInterval','setTimeout'],now:Date.now()});
|
||||
+ const f=await telemetryFixture(t,{hold:true});const started=f.start();await f.waitQueue(1);await new Promise(setImmediate);
|
||||
+ assert.notEqual(f.bus,null,'native readiness precedes the held optional poll');await started;
|
||||
+ let closed=false;const closing=f.close().then(()=>{closed=true;});
|
||||
+ t.mock.timers.tick(4999);await new Promise(setImmediate);assert.equal(closed,false);
|
||||
+ t.mock.timers.tick(1);await closing;
|
||||
+ assert.equal(closed,true);assert.equal(f.queueCalls(),1);
|
||||
+ assert.ok(f.logs.some(line=>line.includes('proxy-usage-read-failed')));
|
||||
+});
|
||||
diff --git a/packages/bus/tests/p5-identity.test.mjs b/packages/bus/tests/p5-identity.test.mjs
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..4ee111f7c9ec75dbae24c184c3310b71973fc7c2
|
||||
--- /dev/null
|
||||
+++ b/packages/bus/tests/p5-identity.test.mjs
|
||||
@@ -0,0 +1,38 @@
|
||||
+import test from 'node:test';
|
||||
+import assert from 'node:assert/strict';
|
||||
+import { telemetryFixture } from './p5-telemetry-fixture.mjs';
|
||||
+for(const foreign of [true,false])test(`P5 R1 boot identity ${foreign?'refusal prevents queue consumption':'matching sentinel permits telemetry without an agent key'}`,async t=>{
|
||||
+ t.mock.timers.enable({apis:['Date','setInterval'],now:Date.now()});
|
||||
+ const f=await telemetryFixture(t,{foreign});await f.start();await f.settleInitial();
|
||||
+ const human=f.human();assert.equal(f.bus.broker.request(human,{verb:'plugins'}).plugins.usage,'cliproxy-queue');
|
||||
+ if(foreign){
|
||||
+ await assert.rejects(f.bus.modelPreflight({business:'demo',role:'coder'}),{code:'proxy-open'});
|
||||
+ assert.equal(f.queueCalls(),0);assert.equal(f.state.queued.length,1);
|
||||
+ await f.pollSettledAfterTick(t);assert.equal(f.queueCalls(),0);assert.equal(f.state.queued.length,1);
|
||||
+ assert.equal(f.bus.broker.request(human,{verb:'usage'}).proxy.state,'unavailable');
|
||||
+ }else{
|
||||
+ assert.equal(f.queueCalls(),1);assert.equal(f.state.queued.length,0);
|
||||
+ assert.equal(f.bus.broker.request(human,{verb:'usage'}).proxy.state,'available');
|
||||
+ assert.equal(f.bus.credentials.status().some(r=>r.service==='model'&&r.keyId),false);
|
||||
+ }
|
||||
+});
|
||||
+test('P5 R1 later sentinel refusal fences every subsequent queue poll while preserving human control',async t=>{
|
||||
+ t.mock.timers.enable({apis:['Date','setInterval'],now:Date.now()});
|
||||
+ const f=await telemetryFixture(t);await f.start();await f.settleInitial();assert.equal(f.queueCalls(),1);
|
||||
+ f.state.keys=[f.other];
|
||||
+ await assert.rejects(f.bus.modelPreflight({business:'demo',role:'coder'}),{code:'proxy-open'});
|
||||
+ await f.pollSettledAfterTick(t);assert.equal(f.queueCalls(),1);
|
||||
+ await f.pollSettledAfterTick(t);assert.equal(f.queueCalls(),1);
|
||||
+ const human=f.human();assert.equal(f.bus.broker.request(human,{verb:'plugins'}).plugins.usage,'cliproxy-queue');
|
||||
+ assert.equal(f.bus.broker.request(human,{verb:'usage'}).proxy.state,'unavailable');
|
||||
+});
|
||||
+
|
||||
+test('P5 R1 every drain verifies fresh sentinel before consuming a changed listener',async t=>{
|
||||
+ t.mock.timers.enable({apis:['Date','setInterval'],now:Date.now()});
|
||||
+ const f=await telemetryFixture(t);await f.start();await f.settleInitial();assert.equal(f.queueCalls(),1);
|
||||
+ f.state.keys=[f.other];await f.pollSettledAfterTick(t);assert.equal(f.queueCalls(),1);
|
||||
+ await assert.rejects(f.bus.modelPreflight({business:'demo',role:'coder'}),{code:'proxy-open'});
|
||||
+ const lists=f.state.calls.filter(p=>p==='/v8/management/config/access/api-keys').length;
|
||||
+ f.state.keys=[f.own];await f.pollSettledAfterTick(t);assert.equal(f.queueCalls(),1);
|
||||
+ assert.equal(f.state.calls.filter(p=>p==='/v8/management/config/access/api-keys').length,lists,'no retry around sticky identity refusal');
|
||||
+});
|
||||
diff --git a/packages/bus/tests/p5-key-compatibility.test.mjs b/packages/bus/tests/p5-key-compatibility.test.mjs
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..331032ecb48644587057a9ec4799e69d5fa3cdc8
|
||||
--- /dev/null
|
||||
+++ b/packages/bus/tests/p5-key-compatibility.test.mjs
|
||||
@@ -0,0 +1,68 @@
|
||||
+import test from 'node:test';
|
||||
+import assert from 'node:assert/strict';
|
||||
+import { mkdtempSync, rmSync, readFileSync } from 'node:fs';
|
||||
+import { tmpdir } from 'node:os';
|
||||
+import { join } from 'node:path';
|
||||
+import { Store } from '../src/store.mjs';
|
||||
+import { createLimits, modelUsageKey } from '../src/limits.mjs';
|
||||
+import * as token from '../../plugins/limit-check/token-limit/index.mjs';
|
||||
+import * as daily from '../../plugins/limit-check/daily-quota/index.mjs';
|
||||
+import { launchSettings } from '../../business/src/launch-settings.mjs';
|
||||
+import { businessDoc, rolesCopy, writeJson, systemFor } from '../../business/tests/helpers.mjs';
|
||||
+const key='abcdefabcdef',other='012345abcdef',since='2026-01-01T00:00:00.000Z';
|
||||
+const quota={limit:10,since,reset:'00:00',timeZone:'UTC'};
|
||||
+const native={at:'2026-10-26T12:00:00.000Z',run:'legacy-run',turn:'turn',account:key,modelKeyId:other,status:'known',input:10,output:0,cacheWrite:0,cacheRead:0};
|
||||
+test('P5 R1 plain twelve-hex account leaves retain matching and original account report even with another model ID',()=>{
|
||||
+ const a={limits:{tokens:{keys:{[key]:{limit:10,since}}}},subject:{account:key,modelKeyId:other},records:[native]};
|
||||
+ assert.equal(token.mayLaunch(a).allow,false);assert.equal(token.mustStop(a).stop,true);
|
||||
+ assert.equal(token.report(a)[0].count,10);assert.deepEqual(token.report(a)[0].path,['tokens','keys',key]);
|
||||
+ assert.equal(token.mayLaunch({...a,records:[{...native,input:9}]}).allow,true);
|
||||
+ assert.deepEqual(daily.report({...a,now:native.at}),[]);
|
||||
+});
|
||||
+for(const proxy of [false,true])test(`P5 R1 legacy account core lookup stays independent of ${proxy?'unrelated proxy metadata':'missing proxy metadata'}`,async t=>{
|
||||
+ const root=mkdtempSync(join(tmpdir(),'p5-legacy-')),store=new Store(root);t.after(()=>{store.close();rmSync(root,{recursive:true,force:true});});
|
||||
+ let lookups=0;
|
||||
+ const b={launch:{account:{name:key,credential:'FAKE_TOKEN_NAME'},limits:{tokens:{keys:{[key]:{limit:10,since}}}}},plugins:{'limit-check':['token-limit']}};
|
||||
+ const limits=createLimits({store,read:()=>b,log:()=>{},keyForSubject:(...args)=>{lookups++;return proxy?modelUsageKey([{service:'model',instance:'demo/coder',keyId:other,retiring:[]}],new Map(),'demo',args[1]):null;}});
|
||||
+ assert.deepEqual(await limits.mayLaunch('demo',{instance:'coder',account:key}),{allow:true});
|
||||
+ store.run(`INSERT INTO usage_records(at,business,run,instance,account,turn,source,phase,status,cursor,input,output,cache_write,cache_read)
|
||||
+ VALUES (?,'demo','legacy-run','coder',?,'turn','transcript','end','known',?,10,0,0,0)`,native.at,key,JSON.stringify({modelKeyId:other}));
|
||||
+ const hit={path:['tokens','keys',key],limit:10,count:10,unknownTurns:0};
|
||||
+ assert.deepEqual(await limits.mayLaunch('demo',{instance:'coder',account:key}),{allow:false,check:'token-limit',hit});
|
||||
+ assert.deepEqual(await limits.mustStop('demo',{instance:'coder',account:key}),{stop:true,check:'token-limit',hit});
|
||||
+ assert.equal(limits.report('demo')[0].count,10);assert.equal(lookups,0);
|
||||
+});
|
||||
+for(const leaf of [{limit:0,since},quota])test(`P5 R1 empty checks bypass model metadata for ${leaf.reset?'daily model':'legacy hex account'} leaves`,async t=>{
|
||||
+ const root=mkdtempSync(join(tmpdir(),'p5-no-checks-')),store=new Store(root);t.after(()=>{store.close();rmSync(root,{recursive:true,force:true});});
|
||||
+ let lookups=0;const limits=createLimits({store,read:()=>({plugins:{'limit-check':[]},launch:{limits:{tokens:{keys:{[key]:leaf}}}}}),log:()=>{},keyForSubject:()=>{lookups++;throw Error('MUST-NOT-LOOK-UP');}});
|
||||
+ assert.deepEqual(await limits.mayLaunch('demo',{instance:'coder',account:key}),{allow:true});
|
||||
+ assert.deepEqual(await limits.mustStop('demo',{instance:'coder',account:key}),{stop:false});assert.equal(lookups,0);
|
||||
+});
|
||||
+test('P5 R1 legacy hex account chief resets stay allowed; daily model old/new/removal/reset transitions stay human-only',t=>{
|
||||
+ const root=mkdtempSync(join(tmpdir(),'p5-fence-'));t.after(()=>rmSync(root,{recursive:true,force:true}));
|
||||
+ const rolesDir=rolesCopy(root),doc=businessDoc(root,'demo'),file=join(root,'businesses/demo.json');
|
||||
+ doc.launch.account={name:key,credential:'FAKE_TOKEN_NAME'};doc.launch.limits={tokens:{keys:{[key]:{limit:10,since}}}};writeJson(file,doc);
|
||||
+ let now='2026-10-26T12:00:00.000Z';const settings=launchSettings({dir:root,rolesDir,system:systemFor(root),now:()=>now});let v=settings.read('demo');
|
||||
+ v=settings.set('demo',{revision:v.revision,reset:[['tokens','keys',key]]},'chief');
|
||||
+ assert.equal(JSON.parse(readFileSync(file,'utf8')).launch.limits.tokens.keys[key].since,now);
|
||||
+ const dailyLeaf={limit:10,reset:'00:00',timeZone:'UTC'};
|
||||
+ assert.throws(()=>settings.set('demo',{revision:v.revision,limits:{tokens:{keys:{[key]:dailyLeaf}}}},'chief'),{code:'organization-model-quota-human-only'});
|
||||
+ v=settings.set('demo',{revision:v.revision,limits:{tokens:{keys:{[key]:dailyLeaf}}}},'jason');now='2026-10-26T13:00:00.000Z';
|
||||
+ for(const args of [{reset:[['tokens','keys',key]]},{limits:{}},{limits:{tokens:{keys:{[key]:{limit:10}}}}}])
|
||||
+ assert.throws(()=>settings.set('demo',{revision:v.revision,...args},'chief'),{code:'organization-model-quota-human-only'});
|
||||
+ v=settings.set('demo',{revision:v.revision,limits:{tokens:{keys:{[key]:{limit:10}}}}},'jason');
|
||||
+ v=settings.set('demo',{revision:v.revision,reset:[['tokens','keys',key]]},'chief');
|
||||
+ assert.equal(JSON.parse(readFileSync(file,'utf8')).launch.limits.tokens.keys[key].since,now);
|
||||
+});
|
||||
+
|
||||
+test('P5 R1 daily model matching/report is separate from legacy account and schema refuses partial or invalid daily shapes',async()=>{
|
||||
+ const {checkTokenLimits}=await import('../../business/src/launch.mjs');
|
||||
+ assert.deepEqual(checkTokenLimits({keys:{[key]:quota}}).keys[key],quota);
|
||||
+ const args={limits:{tokens:{keys:{[key]:quota}}},records:[native],subject:{account:key,modelKeyId:other},now:native.at};
|
||||
+ assert.deepEqual(token.report(args),[]);
|
||||
+ assert.equal(daily.mayLaunch(args).allow,true);assert.equal(daily.report(args)[0].count,0);
|
||||
+ const owned={...args,subject:{account:'other-account',modelKeyId:key},records:[{...native,account:'other-account',modelKeyId:key}]};
|
||||
+ assert.equal(daily.mayLaunch(owned).allow,false);assert.equal(daily.mustStop(owned).stop,true);assert.equal(daily.report(owned)[0].count,10);
|
||||
+ for(const leaf of [{...quota,reset:'25:00'},{...quota,timeZone:'Mars/Phobos'},{limit:10,since,reset:'00:00'},{limit:10,since,timeZone:'UTC'}])
|
||||
+ assert.throws(()=>checkTokenLimits({keys:{[key]:leaf}}));
|
||||
+});
|
||||
diff --git a/packages/bus/tests/p5-key-context.test.mjs b/packages/bus/tests/p5-key-context.test.mjs
|
||||
index 8b2ebe0947591589f83d5c89b49bbd8fcf261e10..46b7a87c8e9cbfe4515e35be768f619dffc4a2b6 100644
|
||||
--- a/packages/bus/tests/p5-key-context.test.mjs
|
||||
+++ b/packages/bus/tests/p5-key-context.test.mjs
|
||||
@@ -22,7 +22,7 @@ test('P5 broker preserves original plugin subject and derives internal run conte
|
||||
});
|
||||
test('P5 configured key quotas never use a supplied safe-looking ID when trusted metadata lookup is missing',async t=>{
|
||||
const root=mkdtempSync(join(tmpdir(),'p5-no-bypass-')),store=new Store(root);t.after(()=>{store.close();rmSync(root,{recursive:true,force:true});});
|
||||
- const doc={plugins:{'limit-check':['token-limit']},launch:{limits:{tokens:{keys:{[key]:{limit:10,since:'2026-01-01T00:00:00.000Z'}}}}}};
|
||||
+ const doc={plugins:{'limit-check':['daily-quota']},launch:{limits:{tokens:{keys:{[key]:{limit:10,since:'2026-01-01T00:00:00.000Z',reset:'00:00',timeZone:'UTC'}}}}}};
|
||||
const limits=createLimits({store,read:()=>doc,log:()=>{},keyForSubject:()=>null});
|
||||
assert.deepEqual(await limits.mustStop('demo',{instance:'coder',modelKeyId:key},{run:'forged-run'}),{stop:true,check:null,code:'proxy-key-refused'});
|
||||
});
|
||||
@@ -38,7 +38,7 @@ test('P5 internal context resolves exactly current or retained generation; wrong
|
||||
|
||||
test('P5 model-key mustStop without native run context fails closed even when the current key resolves',async t=>{
|
||||
const root=mkdtempSync(join(tmpdir(),'p5-missing-context-')),store=new Store(root);t.after(()=>{store.close();rmSync(root,{recursive:true,force:true});});
|
||||
- const doc={plugins:{'limit-check':['token-limit']},launch:{limits:{tokens:{keys:{[key]:{limit:10,since:'2026-01-01T00:00:00.000Z'}}}}}};
|
||||
+ const doc={plugins:{'limit-check':['daily-quota']},launch:{limits:{tokens:{keys:{[key]:{limit:10,since:'2026-01-01T00:00:00.000Z',reset:'00:00',timeZone:'UTC'}}}}}};
|
||||
const limits=createLimits({store,read:()=>doc,log:()=>{},keyForSubject:()=>key});
|
||||
assert.deepEqual(await limits.mustStop('demo',{instance:'coder'}),{stop:true,check:null,code:'proxy-key-refused'});
|
||||
});
|
||||
diff --git a/packages/bus/tests/p5-telemetry-fixture.mjs b/packages/bus/tests/p5-telemetry-fixture.mjs
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..99390f7d565a7d7db5344b574bc5a8623d5fa073
|
||||
--- /dev/null
|
||||
+++ b/packages/bus/tests/p5-telemetry-fixture.mjs
|
||||
@@ -0,0 +1,66 @@
|
||||
+// Fresh, made-up instance and local management listener only; no worker/provider.
|
||||
+import http from 'node:http';
|
||||
+import { createHash, randomBytes } from 'node:crypto';
|
||||
+import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'node:fs';
|
||||
+import { tmpdir } from 'node:os';
|
||||
+import { join } from 'node:path';
|
||||
+import { startBroker } from '../src/runtime.mjs';
|
||||
+import { Registry } from '../../seat/src/session.mjs';
|
||||
+import { businessDoc, rolesCopy, systemFor, writeJson } from '../../business/tests/helpers.mjs';
|
||||
+export async function telemetryFixture(t, { foreign = false, hold = false } = {}) {
|
||||
+ const root = mkdtempSync(join(tmpdir(), 'p5-telemetry-')), config = join(root,'config'), data = join(root,'data');
|
||||
+ mkdirSync(config,{mode:0o700}); mkdirSync(data,{mode:0o700});
|
||||
+ const rolesDir = rolesCopy(config), doc = businessDoc(config,'demo');
|
||||
+ doc.plugins = { usage:'cliproxy-queue', harness:['pi'], 'usage-source':['transcript'], 'limit-check':['token-limit'] };
|
||||
+ doc.usage = { cliproxyQueue:{pollSeconds:1} };
|
||||
+ writeJson(join(config,'businesses/demo.json'),doc);
|
||||
+ mkdirSync(join(config,'secrets'),{recursive:true,mode:0o700});
|
||||
+ writeFileSync(join(config,'secrets/proxy-management.key'),'p5-r1-made-up-management',{mode:0o600});
|
||||
+ new Registry(data);
|
||||
+ const tag = createHash('sha256').update(config).digest('hex').slice(0,12);
|
||||
+ const own = `msk-${tag}-sentinel-${randomBytes(32).toString('base64url')}`;
|
||||
+ const other = `msk-ffffffffffff-sentinel-${randomBytes(32).toString('base64url')}`;
|
||||
+ const state = { keys:[foreign?other:own], calls:[], queued:[{api_key:'msk-r1-unknown-fake',source:'p5-r1-upstream-canary',failed:false,tokens:{input_tokens:1,output_tokens:2}}], held:[], hold };
|
||||
+ const logs=[], waiters=[];
|
||||
+ const stderr = process.stderr.write;
|
||||
+ t.mock.method(process.stderr,'write',function(chunk,...args) {
|
||||
+ const text=String(chunk);logs.push(text);
|
||||
+ for(const waiter of [...waiters]) if(text.includes(waiter.fragment) && logs.length>waiter.from) { waiters.splice(waiters.indexOf(waiter),1);waiter.resolve(); }
|
||||
+ return stderr.call(this,chunk,...args);
|
||||
+ });
|
||||
+ const waitLog=(fragment,from=0)=> {
|
||||
+ if(logs.slice(from).some(line=>line.includes(fragment)))return Promise.resolve();
|
||||
+ return new Promise(resolve=>waiters.push({fragment,from,resolve}));
|
||||
+ };
|
||||
+ let queueWaiters=[];
|
||||
+ const waitQueue=(count)=> state.calls.filter(p=>p.includes('/usage/queue')).length>=count?Promise.resolve():new Promise(resolve=>queueWaiters.push({count,resolve}));
|
||||
+ const answerQueue=res=>{res.end(JSON.stringify(state.queued));state.queued=[];};
|
||||
+ const server=http.createServer(async(req,res)=>{
|
||||
+ state.calls.push(req.url);
|
||||
+ if(req.headers.authorization!=='Bearer p5-r1-made-up-management' && req.url.startsWith('/v8/management/')) {res.writeHead(401);res.end('{}');return;}
|
||||
+ if(req.url==='/v8/management/config/access/api-keys') {
|
||||
+ if(req.method==='PUT'){let body='';for await(const c of req)body+=c;state.keys=JSON.parse(body);res.end('{"status":"ok"}');}
|
||||
+ else res.end(JSON.stringify(state.keys));return;
|
||||
+ }
|
||||
+ if(req.url==='/v8/management/observability/usage/queue?count=100') {
|
||||
+ if(state.hold)state.held.push(res);else answerQueue(res);
|
||||
+ const count=state.calls.filter(p=>p.includes('/usage/queue')).length;
|
||||
+ for(const waiter of queueWaiters.filter(w=>count>=w.count))waiter.resolve();
|
||||
+ queueWaiters=queueWaiters.filter(w=>count<w.count);return;
|
||||
+ }
|
||||
+ res.writeHead(state.keys.includes(req.headers.authorization?.slice(7))?200:401);res.end('{}');
|
||||
+ });
|
||||
+ await new Promise(resolve=>server.listen(0,'127.0.0.1',resolve));
|
||||
+ let bus=null,startPromise=null,closePromise=null;
|
||||
+ const start=()=>startPromise??=(startBroker({dataRoot:data,businesses:{demo:{id:'demo',human:'jason',plugins:doc.plugins,arbiters:{technical:'coder',delivery:'coder'},roles:{coder:{definition:'coder',authority:{withinRole:[],crossRole:[]}}}}},
|
||||
+ organization:{dir:config,rolesDir,system:systemFor(config)},proxy:{port:server.address().port,binary:'/fixture-unused'}}).then(value=>(bus=value)));
|
||||
+ const release=(fail=false)=>{state.hold=false;for(const res of state.held.splice(0)){if(res.destroyed)continue;if(fail){res.writeHead(503);res.end('{}');}else answerQueue(res);}};
|
||||
+ const close=()=>bus?(closePromise??=bus.close()):Promise.resolve();
|
||||
+ t.after(async()=>{release();await startPromise?.catch(()=>{});await close();server.closeAllConnections();await new Promise(r=>server.close(r));rmSync(root,{recursive:true,force:true});});
|
||||
+ return {root,data,config,state,logs,own,other,start,waitLog,waitQueue,release,close,
|
||||
+ settleInitial:()=>Promise.race([waitLog('proxy-usage-read-failed'),waitLog('proxy.usage.reconcile')]),
|
||||
+ get bus(){return bus;},queueCalls:()=>state.calls.filter(p=>p.includes('/usage/queue')).length,
|
||||
+ human:()=>bus.broker.bindHuman({business:'demo',human:'jason',via:'cli',outsideAgent:true}),
|
||||
+ async pollSettledAfterTick(t){const from=logs.length,next=state.calls.filter(p=>p.includes('/usage/queue')).length+1;t.mock.timers.tick(1000);await Promise.race([waitQueue(next),waitLog('proxy-usage-read-failed',from)]);await new Promise(setImmediate);},
|
||||
+ };
|
||||
+}
|
||||
diff --git a/packages/business/src/launch.mjs b/packages/business/src/launch.mjs
|
||||
index 4ee37c5c6514bdf541b20e7001873fb5d8e878f3..7871fdda595d23c3645b417dbf96783faac9047e 100644
|
||||
--- a/packages/business/src/launch.mjs
|
||||
+++ b/packages/business/src/launch.mjs
|
||||
@@ -1,5 +1,6 @@
|
||||
// REQ-LIMIT-1: editable concurrency policy, never a compiled-in capacity ceiling.
|
||||
import { requireObject, requireId, requireString, rejectUnknownKeys } from "./util.mjs";
|
||||
+import { isDailyModelQuota } from "../../plugins/src/model-quota.mjs";
|
||||
import { refuse } from "./errors.mjs";
|
||||
|
||||
const name = (value, at) => requireString(value, at, { max: 200 });
|
||||
@@ -67,12 +68,16 @@ export function checkTokenLimits(value, where = "launch.limits.tokens") {
|
||||
if (Object.hasOwn(value, "models")) {
|
||||
out.models = tokenMap(value.models, `${where}.models`, name, (models, at) => tokenMap(models, at, name, tokenLimit));
|
||||
}
|
||||
- // P5: model key IDs are 12 hex characters (including digit-leading IDs).
|
||||
- // A model key may use the daily quota shape; existing account limits retain theirs.
|
||||
- if (Object.hasOwn(value, "keys")) out.keys = tokenMap(value.keys, `${where}.keys`,
|
||||
- (key, at) => /^[a-f0-9]{12}$/.test(key) ? key : requireId(key, at),
|
||||
- (entry, at) => Object.hasOwn(entry ?? {}, "reset") && /^[a-f0-9]{12}$/.test(at.split('.').at(-1))
|
||||
- ? dailyQuota(entry, at) : tokenLimit(entry, at));
|
||||
+ // P5 adds daily model leaves, including digit-leading IDs; plain keys keep
|
||||
+ // their existing account-name schema and cumulative account semantics.
|
||||
+ if (Object.hasOwn(value, "keys")) {
|
||||
+ requireObject(value.keys, `${where}.keys`);
|
||||
+ out.keys = Object.fromEntries(Object.entries(value.keys).map(([key, entry]) => {
|
||||
+ const at = `${where}.keys.${key}`;
|
||||
+ if (isDailyModelQuota(key, entry)) return [key, dailyQuota(entry, at)];
|
||||
+ return [requireId(key, `${where}.keys`), tokenLimit(entry, at)];
|
||||
+ }));
|
||||
+ }
|
||||
// One quota per account; the business read checks each key names launch.account.
|
||||
if (Object.hasOwn(value, "daily")) out.daily = tokenMap(value.daily, `${where}.daily`, requireId, dailyQuota);
|
||||
return out;
|
||||
diff --git a/packages/business/src/organization.mjs b/packages/business/src/organization.mjs
|
||||
index 6d358631d81464dcac98ec0db2388f08e9eceb39..2acb92e417f32f9080396b41d1a2f565272a01d4 100644
|
||||
--- a/packages/business/src/organization.mjs
|
||||
+++ b/packages/business/src/organization.mjs
|
||||
@@ -8,6 +8,7 @@ import { join, dirname } from "node:path";
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { businessFilePath, validateBusinessDocument } from "./business.mjs";
|
||||
import { requireId, sha256, canonicalJson } from "./util.mjs";
|
||||
+import { isDailyModelQuota } from "../../plugins/src/model-quota.mjs";
|
||||
import { checkReplyLimits } from "../../library/src/limits.mjs";
|
||||
|
||||
export class OrganizationError extends Error {
|
||||
@@ -84,7 +85,7 @@ function changes(old, next, path = "") {
|
||||
// P5/Q222: every writer protects per-model-key quotas, including removal/reset.
|
||||
function modelQuotaFence(old, document, actor) {
|
||||
const keys = doc => Object.fromEntries(Object.entries(doc?.launch?.limits?.tokens?.keys ?? {})
|
||||
- .filter(([key]) => /^[a-f0-9]{12}$/.test(key)));
|
||||
+ .filter(([key, entry]) => isDailyModelQuota(key, entry)));
|
||||
if (canonicalJson(keys(old)) === canonicalJson(keys(document))) return;
|
||||
const agents = Object.entries(old.roles ?? {}).flatMap(([instance, entry]) => [instance, `${entry?.definition}.${instance}`]);
|
||||
if (actor === old.human && actor !== "tester" && !agents.includes(actor)) return;
|
||||
diff --git a/packages/plugins/limit-check/daily-quota/index.mjs b/packages/plugins/limit-check/daily-quota/index.mjs
|
||||
index 38b445803d13a05803ec91e11556346e868a2437..096aa2ead37a18cfa17b2e2d43e19fb5604350f6 100644
|
||||
--- a/packages/plugins/limit-check/daily-quota/index.mjs
|
||||
+++ b/packages/plugins/limit-check/daily-quota/index.mjs
|
||||
@@ -4,6 +4,7 @@
|
||||
// timeZone}. A count is every kind summed over the account's known records since the later of the
|
||||
// day's reset and the leaf's `since`; an unknown turn adds nothing and is counted on its own.
|
||||
// It copies token-limit's tally helpers rather than importing a sibling check, so each loads alone.
|
||||
+import { isDailyModelQuota } from '../../src/model-quota.mjs';
|
||||
export const interfaceVersion = 2;
|
||||
|
||||
const KINDS = ['input', 'output', 'cacheWrite', 'cacheRead'];
|
||||
@@ -63,7 +64,7 @@ function windowStart(entry, now) {
|
||||
function leaves(limits) {
|
||||
const daily = limits?.tokens?.daily ?? {};
|
||||
const entries = [...Object.entries(daily).map(([account, entry]) => ({ path: ['tokens', 'daily', account], entry, match: x => x.account === account })),
|
||||
- ...Object.entries(limits?.tokens?.keys ?? {}).filter(([key, entry]) => /^[a-f0-9]{12}$/.test(key) && Object.hasOwn(entry, 'reset'))
|
||||
+ ...Object.entries(limits?.tokens?.keys ?? {}).filter(([key, entry]) => isDailyModelQuota(key, entry))
|
||||
.map(([key, entry]) => ({ path: ['tokens', 'keys', key], entry, match: x => x.modelKeyId === key }))];
|
||||
return entries.map(({ path, entry, match }) => {
|
||||
if (!Number.isSafeInteger(entry?.limit) || entry.limit < 0 || typeof entry.reset !== 'string' || !RESET.test(entry.reset) ||
|
||||
diff --git a/packages/plugins/limit-check/token-limit/index.mjs b/packages/plugins/limit-check/token-limit/index.mjs
|
||||
index 8f26fcb9c7cbcae4c6cf953a6827af53590771be..b20cea356ca7081a6cf571949a0f6aa31dfec89d 100644
|
||||
--- a/packages/plugins/limit-check/token-limit/index.mjs
|
||||
+++ b/packages/plugins/limit-check/token-limit/index.mjs
|
||||
@@ -3,6 +3,7 @@
|
||||
// launch limits and its per-turn usage records, and nothing here reads a file
|
||||
// or a store. A count is every kind summed over the known records since the
|
||||
// limit's `since`; an unknown turn adds nothing and is counted on its own.
|
||||
+import { isDailyModelQuota } from '../../src/model-quota.mjs';
|
||||
export const interfaceVersion = 2;
|
||||
|
||||
const KINDS = ['input', 'output', 'cacheWrite', 'cacheRead'];
|
||||
@@ -31,8 +32,8 @@ function leaves(limits) {
|
||||
// A key is the record's account. Accounts are null until row 126 names them,
|
||||
// so a key limit matches nothing until then.
|
||||
for (const [k, entry] of Object.entries(tokens.keys ?? {}))
|
||||
- if (!Object.hasOwn(entry, 'reset')) out.push({ path: ['tokens', 'keys', k], entry,
|
||||
- match: x => /^[a-f0-9]{12}$/.test(k) ? x.modelKeyId === k : x.account === k, key: true });
|
||||
+ if (!isDailyModelQuota(k, entry)) out.push({ path: ['tokens', 'keys', k], entry,
|
||||
+ match: x => x.account === k, key: true });
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -73,7 +74,7 @@ export function mustStop(args) {
|
||||
// while no record names an account (lead decision 150, Q1).
|
||||
export function report({ limits, records }) {
|
||||
if (!Array.isArray(records)) refuse('bad-records');
|
||||
- const named = records.some(r => r.account != null || r.modelKeyId != null);
|
||||
+ const named = records.some(r => r.account != null);
|
||||
return leaves(limits).map(leaf => {
|
||||
const { path, entry: { limit, since } } = leaf;
|
||||
if (leaf.key && !named) return { path, limit, since, notEnforced: 'no records name a key' };
|
||||
diff --git a/packages/plugins/src/loader.mjs b/packages/plugins/src/loader.mjs
|
||||
index 04731ee91b04329a3956fd751f4d7fb215f845c3..5634a90664ea98022074cd9fff9bbfbd279692e8 100644
|
||||
--- a/packages/plugins/src/loader.mjs
|
||||
+++ b/packages/plugins/src/loader.mjs
|
||||
@@ -162,3 +162,6 @@ export function createLoader({ log, barrier = () => {} }) {
|
||||
|
||||
return { load, loaded, modules, snapshot };
|
||||
}
|
||||
+
|
||||
+// Shared pure plug-in setting classification; no check implementation is loaded.
|
||||
+export { isDailyModelQuota } from "./model-quota.mjs";
|
||||
diff --git a/packages/plugins/src/model-quota.mjs b/packages/plugins/src/model-quota.mjs
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..1350eb56b5947e759ec8d32f0c429813c352f2a9
|
||||
--- /dev/null
|
||||
+++ b/packages/plugins/src/model-quota.mjs
|
||||
@@ -0,0 +1,17 @@
|
||||
+// The new P5 namespace is the validated DAILY leaf, never a twelve-hex name
|
||||
+// alone. Plain {limit,since} keys remain legacy account limits.
|
||||
+const ID = /^[a-f0-9]{12}$/;
|
||||
+const RESET = /^([01]\d|2[0-3]):[0-5]\d$/;
|
||||
+const ZONE = /^[A-Za-z][A-Za-z0-9_+-]*(\/[A-Za-z0-9_+-]+)*$/;
|
||||
+const SINCE = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
|
||||
+export function isDailyModelQuota(key, value) {
|
||||
+ if (typeof key !== 'string' || !ID.test(key) || !value || typeof value !== 'object' || Array.isArray(value)
|
||||
+ || Object.keys(value).some(k => !['limit','since','reset','timeZone'].includes(k))
|
||||
+ || !Number.isSafeInteger(value.limit) || value.limit < 0
|
||||
+ || typeof value.since !== 'string' || !SINCE.test(value.since) || Number.isNaN(Date.parse(value.since))
|
||||
+ || new Date(value.since).toISOString() !== value.since
|
||||
+ || typeof value.reset !== 'string' || !RESET.test(value.reset)
|
||||
+ || typeof value.timeZone !== 'string' || !ZONE.test(value.timeZone)) return false;
|
||||
+ try { new Intl.DateTimeFormat('en-US', { timeZone:value.timeZone }); return true; }
|
||||
+ catch { return false; }
|
||||
+}
|
||||
diff --git a/packages/plugins/tests/token-limit.test.mjs b/packages/plugins/tests/token-limit.test.mjs
|
||||
index d8f8d3db7928f034d7126d479f4255637d0f8646..2c08be007564e5d4b223a7f93bcf4b36535fe739 100644
|
||||
--- a/packages/plugins/tests/token-limit.test.mjs
|
||||
+++ b/packages/plugins/tests/token-limit.test.mjs
|
||||
@@ -150,11 +150,11 @@ test("REQ-LIMIT-3 token-limit ignores tokens.daily, which the daily-quota check
|
||||
assert.deepEqual(check.report(a), []);
|
||||
});
|
||||
|
||||
-test('P5 a model key ID limit counts stack records by key ID without an account', () => {
|
||||
- const keyId = '012345abcdef';
|
||||
+test('P5 plain twelve-hex keys keep legacy account matching rather than cumulative model matching', () => {
|
||||
+ const keyId = 'abcdef012345';
|
||||
const args = { business: 'demo', limits: { tokens: { keys: { [keyId]: { limit: 5, since: '2026-10-18T00:00:00.000Z' } } } },
|
||||
- subject: { instance: 'coder', modelKeyId: keyId, account: null }, records: [{ at: '2026-10-18T01:00:00.000Z',
|
||||
- run: 'run', turn: 'turn', modelKeyId: keyId, account: null, status: 'known', input: 5, output: 0, cacheWrite: 0, cacheRead: 0 }] };
|
||||
+ subject: { instance: 'coder', modelKeyId: '012345abcdef', account: keyId }, records: [{ at: '2026-10-18T01:00:00.000Z',
|
||||
+ run: 'run', turn: 'turn', modelKeyId: '012345abcdef', account: keyId, status: 'known', input: 5, output: 0, cacheWrite: 0, cacheRead: 0 }] };
|
||||
assert.equal(check.mayLaunch(args).allow, false);
|
||||
assert.equal(check.report(args)[0].count, 5);
|
||||
});
|
||||
diff --git a/packages/plugins/usage/cliproxy-queue/README.md b/packages/plugins/usage/cliproxy-queue/README.md
|
||||
index 98aa6e8a2757e170dc2a27752e0b474a9fb3fab3..7e1b0c1996b536deb0013d4d58c8ee1d2697ad8e 100644
|
||||
--- a/packages/plugins/usage/cliproxy-queue/README.md
|
||||
+++ b/packages/plugins/usage/cliproxy-queue/README.md
|
||||
@@ -35,8 +35,9 @@ usage cursor, preserved at turn begin and end. The Console exposes `byKey`.
|
||||
A business can set a daily per-key quota at
|
||||
`launch.limits.tokens.keys.<12-hex-key-id>` with `{limit, since, reset, timeZone}`;
|
||||
the human writer stamps `since`. Enable `limit-check: ["daily-quota"]` to apply
|
||||
-that quota. Cumulative model-key limits retain `{limit,since}` and use
|
||||
-`token-limit`. Omitting a limit means no quota. Existing named account keys and
|
||||
+that quota. Plain `{limit,since}` keys leaves remain cumulative legacy account limits, even
|
||||
+when the name is twelve hex characters. They use `token-limit` and never resolve
|
||||
+model metadata. Omitting a limit means no quota. Existing named account keys and
|
||||
`tokens.daily.<account>` retain their existing behavior. Model-key limits and
|
||||
resets are human-only through every organization writer. Missing, ambiguous or
|
||||
foreign run-key metadata fails closed with `proxy-key-refused`; a retiring run
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"changed_package_files": 18,
|
||||
"source_patch_equals_controls_then_remainder": true,
|
||||
"status": "byte-application-verified-no-product-execution",
|
||||
"temporary_trees_removed": true
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
packages/model-proxy/tests/usage-client.test.mjs
|
||||
packages/model-proxy/tests/client.test.mjs
|
||||
packages/model-proxy/tests/client-probe.test.mjs
|
||||
packages/model-proxy/tests/page-client.test.mjs
|
||||
packages/model-proxy/tests/management-key-encoding.test.mjs
|
||||
packages/plugins/tests/kinds.test.mjs
|
||||
packages/plugins/tests/loader.test.mjs
|
||||
packages/plugins/tests/token-limit.test.mjs
|
||||
packages/plugins/tests/daily-quota.test.mjs
|
||||
packages/business/tests/plugin-settings.test.mjs
|
||||
packages/business/tests/token-limit-settings.test.mjs
|
||||
packages/bus/tests/usage.test.mjs
|
||||
packages/bus/tests/proxy-usage.test.mjs
|
||||
packages/bus/tests/p5-runtime.test.mjs
|
||||
packages/bus/tests/p5-key-context.test.mjs
|
||||
packages/bus/tests/limit-checks.test.mjs
|
||||
packages/bus/tests/usage-runtime.test.mjs
|
||||
packages/bus/tests/usage-broker.test.mjs
|
||||
packages/bus/tests/daily-quota-runtime.test.mjs
|
||||
packages/bus/tests/limits-runtime.test.mjs
|
||||
packages/bus/tests/limit-stop.test.mjs
|
||||
packages/bus/tests/plugins-verb.test.mjs
|
||||
packages/webui/tests/usage.test.mjs
|
||||
packages/webui/tests/usage-render.test.mjs
|
||||
packages/bus/tests/p5-identity.test.mjs
|
||||
packages/bus/tests/p5-key-compatibility.test.mjs
|
||||
packages/bus/tests/p5-background.test.mjs
|
||||
packages/bus/tests/model-keys.test.mjs
|
||||
@@ -0,0 +1,20 @@
|
||||
// Own-process priority only. A drift is evidence failure, never a behavior RED.
|
||||
import { setPriority, getPriority } from 'node:os';
|
||||
import { appendFileSync } from 'node:fs';
|
||||
const file=process.env.P5_PRIORITY_TRACE;
|
||||
const capture=phase=>{let priority=null;try{priority=getPriority(0);}catch{};const row={phase,pid:process.pid,ppid:process.ppid,priority};appendFileSync(file,JSON.stringify(row)+'\n');if(priority!==19)process.exitCode=78;return row;};
|
||||
try{setPriority(0,19);}catch{appendFileSync(file,JSON.stringify({phase:'setup-failed',pid:process.pid})+'\n');process.exit(78);}
|
||||
const enter=capture('before-modules');if(enter.priority!==19)process.exit(78);
|
||||
const direct=process.ppid===Number(process.env.P5_PRIORITY_PARENT) && typeof process.send==='function';
|
||||
if(direct){
|
||||
await new Promise(resolve=>{process.once('message',msg=>{if(msg?.p5Priority!=='before-ack'||msg.priority!==19)process.exit(78);resolve();});process.send({p5Priority:'before',...enter});});
|
||||
if(capture('before-modules-acked').priority!==19)process.exit(78);
|
||||
process.channel.unref();
|
||||
}
|
||||
let sampled=false;
|
||||
process.on('beforeExit',()=>{
|
||||
if(sampled)return;sampled=true;
|
||||
const after=capture('after-modules');
|
||||
if(direct&&process.connected){process.channel.ref();process.once('message',msg=>{if(msg?.p5Priority!=='after-ack'||msg.priority!==19)process.exitCode=78;process.disconnect();});process.send({p5Priority:'after',...after});}
|
||||
});
|
||||
process.on('exit',()=>capture('exit'));
|
||||
@@ -0,0 +1,64 @@
|
||||
serial nice19/private HOME/XDG_CONFIG_HOME/TMPDIR/MOSAIC_CONFIG; current whole files; original budgets
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["70a0d738f730"]}
|
||||
model-proxy: {"action":"proxy.reconcile","code":"proxy-open"}
|
||||
model-proxy: {"action":"proxy.boot-refused","code":"proxy-open"}
|
||||
model-proxy: {"call":"GET /v8/management/observability/usage/queue","status":200,"keyIds":[]}
|
||||
usage: {"action":"proxy.usage.reconcile","keyId":"2d76a74ee538","code":"proxy-usage-unknown-key"}
|
||||
✖ P5 R1 boot identity refusal prevents queue consumption (125.800633ms)
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["ef88c818311e"]}
|
||||
model-proxy: {"action":"proxy.reconcile","addedKeyIds":[],"removedKeyIds":[]}
|
||||
model-proxy: {"call":"GET /v8/management/observability/usage/queue","status":200,"keyIds":[]}
|
||||
usage: {"action":"proxy.usage.reconcile","keyId":"2d76a74ee538","code":"proxy-usage-unknown-key"}
|
||||
✔ P5 R1 boot identity matching sentinel permits telemetry without an agent key (97.002793ms)
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["e2be6c3cd8a1"]}
|
||||
model-proxy: {"action":"proxy.reconcile","addedKeyIds":[],"removedKeyIds":[]}
|
||||
model-proxy: {"call":"GET /v8/management/observability/usage/queue","status":200,"keyIds":[]}
|
||||
usage: {"action":"proxy.usage.reconcile","keyId":"2d76a74ee538","code":"proxy-usage-unknown-key"}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["56754da18bfc"]}
|
||||
model-proxy: {"call":"GET /v8/management/observability/usage/queue","status":200,"keyIds":[]}
|
||||
✖ P5 R1 later sentinel refusal fences every subsequent queue poll while preserving human control (91.983417ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 449.925938
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/p5-identity.test.mjs:4:35
|
||||
✖ P5 R1 boot identity refusal prevents queue consumption (125.800633ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
1 !== 0
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-identity.test.mjs:10:12)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 1,
|
||||
expected: 0,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/p5-identity.test.mjs:19:1
|
||||
✖ P5 R1 later sentinel refusal fences every subsequent queue poll while preserving human control (91.983417ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
2 !== 1
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-identity.test.mjs:24:42)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 2,
|
||||
expected: 1,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
serial nice19/private HOME/XDG_CONFIG_HOME/TMPDIR/MOSAIC_CONFIG; current whole files; original budgets
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["f5a3100515d0"]}
|
||||
model-proxy: {"action":"proxy.reconcile","code":"proxy-open"}
|
||||
model-proxy: {"action":"proxy.boot-refused","code":"proxy-open"}
|
||||
model-proxy: {"call":"GET /v8/management/observability/usage/queue","status":200,"keyIds":[]}
|
||||
usage: {"action":"proxy.usage.reconcile","keyId":"2d76a74ee538","code":"proxy-usage-unknown-key"}
|
||||
✖ P5 R1 boot identity refusal prevents queue consumption (128.483916ms)
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["7a3cb88227a1"]}
|
||||
model-proxy: {"action":"proxy.reconcile","addedKeyIds":[],"removedKeyIds":[]}
|
||||
model-proxy: {"call":"GET /v8/management/observability/usage/queue","status":200,"keyIds":[]}
|
||||
usage: {"action":"proxy.usage.reconcile","keyId":"2d76a74ee538","code":"proxy-usage-unknown-key"}
|
||||
✔ P5 R1 boot identity matching sentinel permits telemetry without an agent key (92.549175ms)
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["d65bc75c34be"]}
|
||||
model-proxy: {"action":"proxy.reconcile","addedKeyIds":[],"removedKeyIds":[]}
|
||||
model-proxy: {"call":"GET /v8/management/observability/usage/queue","status":200,"keyIds":[]}
|
||||
usage: {"action":"proxy.usage.reconcile","keyId":"2d76a74ee538","code":"proxy-usage-unknown-key"}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["4ebc52a66f1f"]}
|
||||
model-proxy: {"call":"GET /v8/management/observability/usage/queue","status":200,"keyIds":[]}
|
||||
✖ P5 R1 later sentinel refusal fences every subsequent queue poll while preserving human control (89.288341ms)
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["381e8696a4aa"]}
|
||||
model-proxy: {"action":"proxy.reconcile","addedKeyIds":[],"removedKeyIds":[]}
|
||||
model-proxy: {"call":"GET /v8/management/observability/usage/queue","status":200,"keyIds":[]}
|
||||
usage: {"action":"proxy.usage.reconcile","keyId":"2d76a74ee538","code":"proxy-usage-unknown-key"}
|
||||
model-proxy: {"call":"GET /v8/management/observability/usage/queue","status":200,"keyIds":[]}
|
||||
✖ P5 R1 every drain verifies fresh sentinel before consuming a changed listener (86.240495ms)
|
||||
ℹ tests 4
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 3
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 510.10727
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/p5-identity.test.mjs:4:35
|
||||
✖ P5 R1 boot identity refusal prevents queue consumption (128.483916ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
1 !== 0
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-identity.test.mjs:10:12)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 1,
|
||||
expected: 0,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/p5-identity.test.mjs:19:1
|
||||
✖ P5 R1 later sentinel refusal fences every subsequent queue poll while preserving human control (89.288341ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
2 !== 1
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-identity.test.mjs:24:42)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 2,
|
||||
expected: 1,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/p5-identity.test.mjs:30:1
|
||||
✖ P5 R1 every drain verifies fresh sentinel before consuming a changed listener (86.240495ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
2 !== 1
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-identity.test.mjs:33:65)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 2,
|
||||
expected: 1,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
serial nice19/private HOME/XDG_CONFIG_HOME/TMPDIR/MOSAIC_CONFIG; current whole files; original budgets
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["86c48fc677b6"]}
|
||||
model-proxy: {"action":"proxy.reconcile","code":"proxy-open"}
|
||||
model-proxy: {"action":"proxy.boot-refused","code":"proxy-open"}
|
||||
usage: {"action":"proxy.usage","code":"proxy-usage-read-failed"}
|
||||
usage: {"action":"proxy.usage","code":"proxy-usage-read-failed"}
|
||||
✔ P5 R1 boot identity refusal prevents queue consumption (130.508163ms)
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["bd046882d09b"]}
|
||||
model-proxy: {"action":"proxy.reconcile","addedKeyIds":[],"removedKeyIds":[]}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["bd046882d09b"]}
|
||||
model-proxy: {"call":"GET /v8/management/observability/usage/queue","status":200,"keyIds":[]}
|
||||
usage: {"action":"proxy.usage.reconcile","keyId":"2d76a74ee538","code":"proxy-usage-unknown-key"}
|
||||
✔ P5 R1 boot identity matching sentinel permits telemetry without an agent key (88.658667ms)
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["4b34617e0395"]}
|
||||
model-proxy: {"action":"proxy.reconcile","addedKeyIds":[],"removedKeyIds":[]}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["4b34617e0395"]}
|
||||
model-proxy: {"call":"GET /v8/management/observability/usage/queue","status":200,"keyIds":[]}
|
||||
usage: {"action":"proxy.usage.reconcile","keyId":"2d76a74ee538","code":"proxy-usage-unknown-key"}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["7dffb1f98321"]}
|
||||
usage: {"action":"proxy.usage","code":"proxy-usage-read-failed"}
|
||||
usage: {"action":"proxy.usage","code":"proxy-usage-read-failed"}
|
||||
✔ P5 R1 later sentinel refusal fences every subsequent queue poll while preserving human control (90.624642ms)
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["214865151ff7"]}
|
||||
model-proxy: {"action":"proxy.reconcile","addedKeyIds":[],"removedKeyIds":[]}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["214865151ff7"]}
|
||||
model-proxy: {"call":"GET /v8/management/observability/usage/queue","status":200,"keyIds":[]}
|
||||
usage: {"action":"proxy.usage.reconcile","keyId":"2d76a74ee538","code":"proxy-usage-unknown-key"}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["05c20c828aab"]}
|
||||
usage: {"action":"proxy.usage","code":"proxy-usage-read-failed"}
|
||||
usage: {"action":"proxy.usage","code":"proxy-usage-read-failed"}
|
||||
✔ P5 R1 every drain verifies fresh sentinel before consuming a changed listener (89.507433ms)
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["3c2be7b3eafc"]}
|
||||
model-proxy: {"action":"proxy.reconcile","addedKeyIds":[],"removedKeyIds":[]}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["3c2be7b3eafc"]}
|
||||
model-proxy: {"call":"PUT /v8/management/config/access/api-keys","status":200,"keyIds":["3c2be7b3eafc","59588bcfb072"]}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["3c2be7b3eafc","59588bcfb072"]}
|
||||
model-proxy: {"action":"proxy.key.issued","keyIds":["59588bcfb072"],"instance":"demo/coder"}
|
||||
model-proxy: {"call":"GET /v1/models","status":200,"keyIds":["59588bcfb072"]}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mustStop","subject":{"instance":"coder","provider":null,"model":null,"account":null,"modelKeyId":"59588bcfb072"},"path":["tokens","keys","59588bcfb072"],"limit":2,"count":2,"unknownTurns":0}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mayLaunch","subject":{"instance":"coder","provider":"fixture","model":"fake","account":null,"modelKeyId":"59588bcfb072"},"path":["tokens","keys","59588bcfb072"],"limit":2,"count":2,"unknownTurns":0}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
✔ P5 real runtime binds stack usage to issued key, daily stops at stack count and human-only telemetry settings pass broker contract (307.634061ms)
|
||||
✔ P5 usage plugin off by default, default poll is 15 seconds and configured polls skip early ticks (59.231552ms)
|
||||
✔ P5 safe telemetry stores failures per key and proxy-labelled accounts; no client/upstream value enters store/log/view or quota records (51.73727ms)
|
||||
✔ P5 unknown msk key goes only to value-free reconcile log and other businesses stay isolated (41.741296ms)
|
||||
✔ P5 queue failure is safe, does not enforce and does not retry before poll deadline (41.631253ms)
|
||||
✔ P5 retiring key keeps attribution and telemetry rows remain append-only across reader restart (45.675917ms)
|
||||
✔ P5 malformed queue batch is atomic: no valid prefix, body or credential can reach store/log/view (40.836614ms)
|
||||
✔ P5 concurrent ticks issue one bounded queue read and a closed collector never polls again (41.649306ms)
|
||||
ℹ tests 12
|
||||
ℹ suites 0
|
||||
ℹ pass 12
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1339.356951
|
||||
@@ -0,0 +1,151 @@
|
||||
serial nice19/private HOME/XDG_CONFIG_HOME/TMPDIR/MOSAIC_CONFIG; current whole files; original budgets
|
||||
✖ P5 R1 plain twelve-hex account leaves retain matching and original account report even with another model ID (1.287351ms)
|
||||
✖ P5 R1 legacy account core lookup stays independent of missing proxy metadata (44.846563ms)
|
||||
✖ P5 R1 legacy account core lookup stays independent of unrelated proxy metadata (75.574178ms)
|
||||
✖ P5 R1 empty checks bypass model metadata for legacy hex account leaves (40.99232ms)
|
||||
✖ P5 R1 empty checks bypass model metadata for daily model leaves (39.708938ms)
|
||||
✖ P5 R1 legacy hex account chief resets stay allowed; daily model old/new/removal/reset transitions stay human-only (6.300602ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 6
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 286.933279
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/p5-key-compatibility.test.mjs:15:1
|
||||
✖ P5 R1 plain twelve-hex account leaves retain matching and original account report even with another model ID (1.287351ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
true !== false
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-key-compatibility.test.mjs:17:9)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.start (node:internal/test_runner/test:1262:17)
|
||||
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: true,
|
||||
expected: false,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/p5-key-compatibility.test.mjs:22:33
|
||||
✖ P5 R1 legacy account core lookup stays independent of missing proxy metadata (44.846563ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
+ allow: false,
|
||||
+ check: null,
|
||||
+ code: 'proxy-key-refused'
|
||||
- allow: true
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-key-compatibility.test.mjs:27:9)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { allow: false, check: null, code: 'proxy-key-refused' },
|
||||
expected: { allow: true },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/p5-key-compatibility.test.mjs:22:33
|
||||
✖ P5 R1 legacy account core lookup stays independent of unrelated proxy metadata (75.574178ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
+ allow: true
|
||||
- allow: false,
|
||||
- check: 'token-limit',
|
||||
- hit: {
|
||||
- count: 10,
|
||||
- limit: 10,
|
||||
- path: [
|
||||
- 'tokens',
|
||||
- 'keys',
|
||||
- 'abcdefabcdef'
|
||||
- ],
|
||||
- unknownTurns: 0
|
||||
- }
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-key-compatibility.test.mjs:31:9)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { allow: true },
|
||||
expected: { allow: false, check: 'token-limit', hit: { path: [Array], limit: 10, count: 10, unknownTurns: 0 } },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/p5-key-compatibility.test.mjs:35:43
|
||||
✖ P5 R1 empty checks bypass model metadata for legacy hex account leaves (40.99232ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
+ allow: false,
|
||||
+ check: null,
|
||||
+ code: 'proxy-key-refused'
|
||||
- allow: true
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-key-compatibility.test.mjs:38:9)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { allow: false, check: null, code: 'proxy-key-refused' },
|
||||
expected: { allow: true },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/p5-key-compatibility.test.mjs:35:43
|
||||
✖ P5 R1 empty checks bypass model metadata for daily model leaves (39.708938ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
+ allow: false,
|
||||
+ check: null,
|
||||
+ code: 'proxy-key-refused'
|
||||
- allow: true
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-key-compatibility.test.mjs:38:9)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { allow: false, check: null, code: 'proxy-key-refused' },
|
||||
expected: { allow: true },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/p5-key-compatibility.test.mjs:41:1
|
||||
✖ P5 R1 legacy hex account chief resets stay allowed; daily model old/new/removal/reset transitions stay human-only (6.300602ms)
|
||||
TypeError: Cannot convert undefined or null to object
|
||||
at Object.entries (<anonymous>)
|
||||
at mergeVars (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/src/vars.mjs:208:39)
|
||||
at resolveInstance (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/src/resolve.mjs:58:32)
|
||||
at file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/src/launch-settings.mjs:149:20
|
||||
at Array.map (<anonymous>)
|
||||
at Object.view [as read] (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/src/launch-settings.mjs:148:70)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-key-compatibility.test.mjs:45:115)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
@@ -0,0 +1,153 @@
|
||||
serial nice19/private HOME/XDG_CONFIG_HOME/TMPDIR/MOSAIC_CONFIG; current whole files; original budgets
|
||||
✖ P5 R1 plain twelve-hex account leaves retain matching and original account report even with another model ID (1.240436ms)
|
||||
✖ P5 R1 legacy account core lookup stays independent of missing proxy metadata (39.542498ms)
|
||||
✖ P5 R1 legacy account core lookup stays independent of unrelated proxy metadata (41.657463ms)
|
||||
✖ P5 R1 empty checks bypass model metadata for legacy hex account leaves (42.329077ms)
|
||||
✖ P5 R1 empty checks bypass model metadata for daily model leaves (38.400191ms)
|
||||
✖ P5 R1 legacy hex account chief resets stay allowed; daily model old/new/removal/reset transitions stay human-only (28.304788ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 6
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 266.994555
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/p5-key-compatibility.test.mjs:15:1
|
||||
✖ P5 R1 plain twelve-hex account leaves retain matching and original account report even with another model ID (1.240436ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
true !== false
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-key-compatibility.test.mjs:17:9)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.start (node:internal/test_runner/test:1262:17)
|
||||
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: true,
|
||||
expected: false,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/p5-key-compatibility.test.mjs:22:33
|
||||
✖ P5 R1 legacy account core lookup stays independent of missing proxy metadata (39.542498ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
+ allow: false,
|
||||
+ check: null,
|
||||
+ code: 'proxy-key-refused'
|
||||
- allow: true
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-key-compatibility.test.mjs:27:9)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { allow: false, check: null, code: 'proxy-key-refused' },
|
||||
expected: { allow: true },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/p5-key-compatibility.test.mjs:22:33
|
||||
✖ P5 R1 legacy account core lookup stays independent of unrelated proxy metadata (41.657463ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
+ allow: true
|
||||
- allow: false,
|
||||
- check: 'token-limit',
|
||||
- hit: {
|
||||
- count: 10,
|
||||
- limit: 10,
|
||||
- path: [
|
||||
- 'tokens',
|
||||
- 'keys',
|
||||
- 'abcdefabcdef'
|
||||
- ],
|
||||
- unknownTurns: 0
|
||||
- }
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-key-compatibility.test.mjs:31:9)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { allow: true },
|
||||
expected: { allow: false, check: 'token-limit', hit: { path: [Array], limit: 10, count: 10, unknownTurns: 0 } },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/p5-key-compatibility.test.mjs:35:43
|
||||
✖ P5 R1 empty checks bypass model metadata for legacy hex account leaves (42.329077ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
+ allow: false,
|
||||
+ check: null,
|
||||
+ code: 'proxy-key-refused'
|
||||
- allow: true
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-key-compatibility.test.mjs:38:9)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { allow: false, check: null, code: 'proxy-key-refused' },
|
||||
expected: { allow: true },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/p5-key-compatibility.test.mjs:35:43
|
||||
✖ P5 R1 empty checks bypass model metadata for daily model leaves (38.400191ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
+ allow: false,
|
||||
+ check: null,
|
||||
+ code: 'proxy-key-refused'
|
||||
- allow: true
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-key-compatibility.test.mjs:38:9)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { allow: false, check: null, code: 'proxy-key-refused' },
|
||||
expected: { allow: true },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/p5-key-compatibility.test.mjs:41:1
|
||||
✖ P5 R1 legacy hex account chief resets stay allowed; daily model old/new/removal/reset transitions stay human-only (28.304788ms)
|
||||
Error: organization-model-quota-human-only
|
||||
at fail (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/src/organization.mjs:21:9)
|
||||
at modelQuotaFence (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/src/organization.mjs:91:3)
|
||||
at file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/src/organization.mjs:263:9
|
||||
at withLock (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/src/organization.mjs:189:14)
|
||||
at Object.write (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/src/organization.mjs:251:14)
|
||||
at Object.set (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/src/launch-settings.mjs:247:28)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-key-compatibility.test.mjs:46:13)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18) {
|
||||
code: 'organization-model-quota-human-only'
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
serial nice19/private HOME/XDG_CONFIG_HOME/TMPDIR/MOSAIC_CONFIG; current whole files; original budgets
|
||||
✔ P5 R1 plain twelve-hex account leaves retain matching and original account report even with another model ID (2.200722ms)
|
||||
✔ P5 R1 legacy account core lookup stays independent of missing proxy metadata (66.048932ms)
|
||||
✔ P5 R1 legacy account core lookup stays independent of unrelated proxy metadata (44.314633ms)
|
||||
✔ P5 R1 empty checks bypass model metadata for legacy hex account leaves (42.37751ms)
|
||||
✔ P5 R1 empty checks bypass model metadata for daily model leaves (43.039529ms)
|
||||
✔ P5 R1 legacy hex account chief resets stay allowed; daily model old/new/removal/reset transitions stay human-only (249.560024ms)
|
||||
ℹ tests 6
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 523.899686
|
||||
@@ -0,0 +1,22 @@
|
||||
✔ P5 R1 plain twelve-hex account leaves retain matching and original account report even with another model ID (1.786896ms)
|
||||
✔ P5 R1 legacy account core lookup stays independent of missing proxy metadata (52.50413ms)
|
||||
✔ P5 R1 legacy account core lookup stays independent of unrelated proxy metadata (45.531998ms)
|
||||
✔ P5 R1 empty checks bypass model metadata for legacy hex account leaves (39.386516ms)
|
||||
✔ P5 R1 empty checks bypass model metadata for daily model leaves (41.470824ms)
|
||||
✔ P5 R1 legacy hex account chief resets stay allowed; daily model old/new/removal/reset transitions stay human-only (246.297869ms)
|
||||
✖ packages/bus/tests/p5-key-compatibility.test.mjs (498.329508ms)
|
||||
ℹ tests 7
|
||||
ℹ suites 0
|
||||
ℹ pass 6
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 503.700106
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/p5-key-compatibility.test.mjs:1:1
|
||||
✖ packages/bus/tests/p5-key-compatibility.test.mjs (498.329508ms)
|
||||
'test failed'
|
||||
UNVERIFIED/STOP: priority drift or incomplete capture; child=1, signal=null
|
||||
@@ -0,0 +1,5 @@
|
||||
{"phase":"wrapper-before","pid":2643577,"priority":19}
|
||||
{"phase":"before-modules","pid":2643590,"ppid":2643584,"priority":19}
|
||||
{"phase":"after-modules","pid":2643590,"ppid":2643584,"priority":16}
|
||||
{"phase":"exit","pid":2643590,"ppid":2643584,"priority":16}
|
||||
{"phase":"wrapper-after","pid":2643577,"priority":16}
|
||||
@@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
p5root=$(mktemp -d /tmp/p5-r1-light-XXXXXX)
|
||||
trap 'rm -rf "$p5root"' EXIT
|
||||
mkdir "$p5root/home" "$p5root/config" "$p5root/tmp"
|
||||
export HOME="$p5root/home" XDG_CONFIG_HOME="$p5root/config" TMPDIR="$p5root/tmp" MOSAIC_CONFIG="$p5root/config/absent.json"
|
||||
printf '%s\n' 'serial nice19/private HOME/XDG_CONFIG_HOME/TMPDIR/MOSAIC_CONFIG; current whole files; original budgets'
|
||||
nice -n 19 node --test --test-concurrency=1 "$@"
|
||||
@@ -0,0 +1,26 @@
|
||||
import { setPriority, getPriority } from 'node:os';
|
||||
import { spawn } from 'node:child_process';
|
||||
import { appendFileSync, readFileSync } from 'node:fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
const file=process.env.P5_PRIORITY_TRACE;
|
||||
const capture=(phase,pid=0)=>{let priority=null;try{priority=getPriority(pid);}catch{};const row={phase,pid:pid||process.pid,priority};appendFileSync(file,JSON.stringify(row)+'\n');return priority;};
|
||||
try{setPriority(0,19);}catch{process.stderr.write('UNVERIFIED/STOP: own wrapper priority setup failed\n');process.exit(78);}
|
||||
if(capture('wrapper-before')!==19)process.exit(78);
|
||||
const child=spawn(process.execPath,['--import',fileURLToPath(new URL('./priority-guard.mjs',import.meta.url)),'--test','--test-concurrency=1',...process.argv.slice(2)],{
|
||||
env:{...process.env,P5_PRIORITY_PARENT:String(process.pid)},stdio:['ignore','inherit','inherit','ipc'],
|
||||
});
|
||||
child.on('message',msg=>{
|
||||
if(!['before','after'].includes(msg?.p5Priority))return;
|
||||
const priority=capture(`direct-child-${msg.p5Priority}`,child.pid);
|
||||
child.send({p5Priority:`${msg.p5Priority}-ack`,priority});
|
||||
});
|
||||
child.on('error',()=>{process.stderr.write('UNVERIFIED/STOP: native child setup failed\n');process.exitCode=78;});
|
||||
child.on('close',(code,signal)=>{
|
||||
capture('wrapper-after');
|
||||
const rows=readFileSync(file,'utf8').trim().split('\n').map(JSON.parse);
|
||||
const drift=rows.some(r=>r.priority!==19);
|
||||
const before=rows.filter(r=>r.phase==='before-modules');
|
||||
const complete=before.length>0&&before.every(r=>rows.some(x=>x.pid===r.pid&&x.phase==='exit'));
|
||||
if(drift||!complete||signal){process.stderr.write(`UNVERIFIED/STOP: priority drift or incomplete capture; child=${code}, signal=${signal}\n`);process.exitCode=78;}
|
||||
else{process.stderr.write(`native strict19 verified: ${before.length} Node processes; direct-child before/after readbacks=19; behavior exit=${code}\n`);process.exitCode=code??78;}
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
p5root=$(mktemp -d /tmp/p5-r1-strict-XXXXXX)
|
||||
trap 'rm -rf "$p5root"' EXIT
|
||||
mkdir "$p5root/home" "$p5root/config" "$p5root/tmp"
|
||||
export HOME="$p5root/home" XDG_CONFIG_HOME="$p5root/config" TMPDIR="$p5root/tmp" MOSAIC_CONFIG="$p5root/config/absent.json"
|
||||
: "${P5_PRIORITY_TRACE:?caller must name a new priority evidence file}"
|
||||
: > "$P5_PRIORITY_TRACE"
|
||||
node agents/codex/work/queue-333/r1-repair/run-priority.mjs "$@"
|
||||
@@ -0,0 +1,28 @@
|
||||
packages/model-proxy/tests/usage-client.test.mjs
|
||||
packages/model-proxy/tests/client.test.mjs
|
||||
packages/model-proxy/tests/client-probe.test.mjs
|
||||
packages/model-proxy/tests/page-client.test.mjs
|
||||
packages/model-proxy/tests/management-key-encoding.test.mjs
|
||||
packages/plugins/tests/kinds.test.mjs
|
||||
packages/plugins/tests/loader.test.mjs
|
||||
packages/plugins/tests/token-limit.test.mjs
|
||||
packages/plugins/tests/daily-quota.test.mjs
|
||||
packages/business/tests/plugin-settings.test.mjs
|
||||
packages/business/tests/token-limit-settings.test.mjs
|
||||
packages/bus/tests/usage.test.mjs
|
||||
packages/bus/tests/proxy-usage.test.mjs
|
||||
packages/bus/tests/p5-runtime.test.mjs
|
||||
packages/bus/tests/p5-key-context.test.mjs
|
||||
packages/bus/tests/limit-checks.test.mjs
|
||||
packages/bus/tests/usage-runtime.test.mjs
|
||||
packages/bus/tests/usage-broker.test.mjs
|
||||
packages/bus/tests/daily-quota-runtime.test.mjs
|
||||
packages/bus/tests/limits-runtime.test.mjs
|
||||
packages/bus/tests/limit-stop.test.mjs
|
||||
packages/bus/tests/plugins-verb.test.mjs
|
||||
packages/webui/tests/usage.test.mjs
|
||||
packages/webui/tests/usage-render.test.mjs
|
||||
packages/bus/tests/p5-identity.test.mjs
|
||||
packages/bus/tests/p5-key-compatibility.test.mjs
|
||||
packages/bus/tests/p5-background.test.mjs
|
||||
packages/bus/tests/model-keys.test.mjs
|
||||
@@ -0,0 +1,25 @@
|
||||
agents/codex/work/queue-333/receipts/01-token-red.txt: OK
|
||||
agents/codex/work/queue-333/receipts/02-contract-red.txt: OK
|
||||
agents/codex/work/queue-333/receipts/03-core-green.txt: OK
|
||||
agents/codex/work/queue-333/receipts/04-integration-red.txt: OK
|
||||
agents/codex/work/queue-333/receipts/05-collector-green.txt: OK
|
||||
agents/codex/work/queue-333/receipts/06-collector-green.txt: OK
|
||||
agents/codex/work/queue-333/receipts/07-wiring-green.txt: OK
|
||||
agents/codex/work/queue-333/receipts/08-edges-red.txt: OK
|
||||
agents/codex/work/queue-333/receipts/09-lookup-red.txt: OK
|
||||
agents/codex/work/queue-333/receipts/10-lookup-behavior-red.txt: OK
|
||||
agents/codex/work/queue-333/receipts/11-edges-green.txt: OK
|
||||
agents/codex/work/queue-333/receipts/12-runtime.txt: OK
|
||||
agents/codex/work/queue-333/receipts/13-runtime.txt: OK
|
||||
agents/codex/work/queue-333/receipts/14-runtime.txt: OK
|
||||
agents/codex/work/queue-333/receipts/15-safety-green.txt: OK
|
||||
agents/codex/work/queue-333/receipts/16-upstream-value-mutant.txt: OK
|
||||
agents/codex/work/queue-333/receipts/17-mutant-restored-green.txt: OK
|
||||
agents/codex/work/queue-333/receipts/18-current-wholefiles.txt: OK
|
||||
agents/codex/work/queue-333/receipts/19-current-wholefiles-green.txt: OK
|
||||
agents/codex/work/queue-333/receipts/20-context-bypass-red.txt: OK
|
||||
agents/codex/work/queue-333/receipts/21-context-green.txt: OK
|
||||
agents/codex/work/queue-333/receipts/22-final-current-wholefiles-green.txt: OK
|
||||
agents/codex/work/queue-333/receipts/23-missing-context-red.txt: OK
|
||||
agents/codex/work/queue-333/receipts/24-final-current-wholefiles-green.txt: OK
|
||||
agents/codex/work/queue-333/receipts/source-inputs.raw.jsonl: OK
|
||||
@@ -0,0 +1,25 @@
|
||||
83116bee02980cd12f66b9db2db0dfe4add8c1d2a19b7de3a3b05c18b0cec8cd agents/codex/work/queue-333/receipts/01-token-red.txt
|
||||
0f21d268ed7777bcfc0290160f30016932f0f3580d9174daf84158833e693e0f agents/codex/work/queue-333/receipts/02-contract-red.txt
|
||||
9aa1d4feb1924ac45c8fa9af14714aa8c89ef6ba7d711884f415c6473ffe20af agents/codex/work/queue-333/receipts/03-core-green.txt
|
||||
11ed664ff680750630dd861bc60cc2cc47cba77575cb63e64001e3271162c33a agents/codex/work/queue-333/receipts/04-integration-red.txt
|
||||
818e3654c49d95ac81200676c46ebecc8155b101352e4e34ed8907a6b4bd93db agents/codex/work/queue-333/receipts/05-collector-green.txt
|
||||
304d137843363f96eb9b0bfef8a570b5d2c3ee53fc66da4ebb5e18a571f71fce agents/codex/work/queue-333/receipts/06-collector-green.txt
|
||||
6bb1254ff078de90dac8503c326422180c5c40df7be6aea569ce6f41cf136a49 agents/codex/work/queue-333/receipts/07-wiring-green.txt
|
||||
0fe51fde4f88bf85d049b26ebfd3048fbc15db3e6785d14f45b987256744def8 agents/codex/work/queue-333/receipts/08-edges-red.txt
|
||||
e47bc241fe8bfcc8a84e64a274d51383f143b16b95fe5ffaf3fa5ec5030b5d2c agents/codex/work/queue-333/receipts/09-lookup-red.txt
|
||||
688dff5c657bfb58c8a4125cbfb4decdb62633d0e1be9b2579dea2d2619db009 agents/codex/work/queue-333/receipts/10-lookup-behavior-red.txt
|
||||
58ac0ed96465af6571b899402e47dc3cd76f420873975e0ca8df091184c9f322 agents/codex/work/queue-333/receipts/11-edges-green.txt
|
||||
f3be41efca8f65dbf5a69b2ad5541d090db7f1f084b7d95eca5192cf07fcf0b2 agents/codex/work/queue-333/receipts/12-runtime.txt
|
||||
9aefb96aa52e8baf033eebf14226c74db255b6047f9fd0a46d5bc20b2b75d04e agents/codex/work/queue-333/receipts/13-runtime.txt
|
||||
9331e56310edd0a8d31807d9f0b7c1092188eb75be44e0c001f001a751b55654 agents/codex/work/queue-333/receipts/14-runtime.txt
|
||||
d138c2fa4c79ed4bed64fec95c08ec706e092766d5d74c421a26206d7d844ded agents/codex/work/queue-333/receipts/15-safety-green.txt
|
||||
10a1ad5d5eecfcdef684f35e861fa2903c2598008ce18b05fb56d2d5460f6fa0 agents/codex/work/queue-333/receipts/16-upstream-value-mutant.txt
|
||||
25f57b7482a0110a8be18e233e2b216b2d99ea826359d60bf1c72c075da036de agents/codex/work/queue-333/receipts/17-mutant-restored-green.txt
|
||||
aefa2196d51cf0e957bdf03b769757d27a174bd163627c72aa8c8eb2c47a21da agents/codex/work/queue-333/receipts/18-current-wholefiles.txt
|
||||
31357c2a88cc3a70ed9fa4b79a43715b34493d9abbb816029f6a8ffac72f4db5 agents/codex/work/queue-333/receipts/19-current-wholefiles-green.txt
|
||||
4fbae7204515aac046c7b782df18c5fba937fdfc536527740ffeffffe0f59226 agents/codex/work/queue-333/receipts/20-context-bypass-red.txt
|
||||
764db5e9b464d6b070720977c0a62edbd4e9329ca918cedc1ee69419da96d47d agents/codex/work/queue-333/receipts/21-context-green.txt
|
||||
5d45ed8ea8e79e91c4b41a59239824ef05cfa924a55b3cc6fb163120027ed441 agents/codex/work/queue-333/receipts/22-final-current-wholefiles-green.txt
|
||||
f6928aae72409ec0e8b13da469c5a957ebc8f6ae1911dfeec8c681359fc4b429 agents/codex/work/queue-333/receipts/23-missing-context-red.txt
|
||||
3358af061c35d42b00d5ee1e001939534c5e7563d4f5418ea85431605d0b9f6d agents/codex/work/queue-333/receipts/24-final-current-wholefiles-green.txt
|
||||
9c16aa4b8e6d81aa5b9867fec5e0890b22e90db5c307da55badfcfa9f240aef1 agents/codex/work/queue-333/receipts/source-inputs.raw.jsonl
|
||||
@@ -0,0 +1,43 @@
|
||||
✔ REQ-LIMIT-3 token-limit exports interface version 2 with mayLaunch, mustStop and report (3.955474ms)
|
||||
✔ REQ-LIMIT-3 each subject kind refuses at its limit and allows under it (1.336324ms)
|
||||
✔ REQ-LIMIT-3 a limit covers only its own subject's records and launches (0.329981ms)
|
||||
✔ REQ-LIMIT-4 only known records count; an unknown turn adds nothing and is counted apart (0.256881ms)
|
||||
✔ REQ-LIMIT-3 a reset moves since: records before it no longer count (0.171382ms)
|
||||
✔ REQ-LIMIT-3 limit 0 refuses with no records; the first limit hit in file order is named (0.142272ms)
|
||||
✔ REQ-LIMIT-3 a key limit is not enforced while every record's account is null (decision 150 Q1) (0.184471ms)
|
||||
✔ REQ-LIMIT-3 counts past the safe integer range come back as digit strings (0.143936ms)
|
||||
✔ REQ-LIMIT-4 bad records or times throw a code, and the check reads nothing but its arguments (0.65868ms)
|
||||
✔ REQ-LIMIT-3 no token limits: every launch is allowed and the report is empty (0.216805ms)
|
||||
✔ REQ-LIMIT-3 token-limit ignores tokens.daily, which the daily-quota check enforces (row 126) (0.16854ms)
|
||||
✖ P5 a model key ID limit counts stack records by key ID without an account (0.661965ms)
|
||||
ℹ tests 12
|
||||
ℹ suites 0
|
||||
ℹ pass 11
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 51.890649
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/plugins/tests/token-limit.test.mjs:153:1
|
||||
✖ P5 a model key ID limit counts stack records by key ID without an account (0.661965ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
true !== false
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/plugins/tests/token-limit.test.mjs:158:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: true,
|
||||
expected: false,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
✔ REQ-LIMIT-3 schema: each subject kind, limit 0 and no ceiling are accepted; bad limits, times, keys and undeclared instances refuse (18.6933ms)
|
||||
✔ REQ-LIMIT-3 the writer stamps since: a new limit gets now, a changed one keeps its time, a different time is refused (266.957706ms)
|
||||
✔ REQ-LIMIT-3 only tokens.* at schema depth holds token limits: agent limits named `limit` save as sent, and a token limit named `limit` is stamped and reset (259.927876ms)
|
||||
✔ REQ-LIMIT-3 a reset moves since to now, is logged with its actor, and refuses a path that is not a limit (136.121744ms)
|
||||
✔ REQ-LIMIT-2 schema: launch.account names a credential set; a daily quota needs a reset and an IANA zone and names the account (27.149735ms)
|
||||
✔ REQ-LIMIT-2 the writer stamps a daily quota's since, keeps its reset and zone, and a reset moves since (147.184856ms)
|
||||
✖ P5 per-model-key quotas are unset by default, accept digit-leading IDs and only the human changes or resets them (2.663205ms)
|
||||
✖ P5 queue read uses actual bounded fixed management GET and immediately drops client and upstream values (7.314165ms)
|
||||
✖ P5 bad envelope refuses safely with no retry (1.407651ms)
|
||||
✖ P5 over count refuses safely with no retry (0.970003ms)
|
||||
✖ P5 missing key refuses safely with no retry (0.457173ms)
|
||||
✖ P5 bad counts refuses safely with no retry (0.970914ms)
|
||||
✖ P5 redirect refuses safely with no retry (0.566467ms)
|
||||
✖ P5 refusal refuses safely with no retry (0.492518ms)
|
||||
✔ REQ-LIMIT-2 daily-quota exports interface version 2 with mayLaunch, mustStop and report (4.119781ms)
|
||||
✔ REQ-LIMIT-2 the count sums every kind of the account's known records since the later of the day start and since (11.801692ms)
|
||||
✔ REQ-LIMIT-2 a launch with no account (pi) is covered by no daily quota (0.304042ms)
|
||||
✔ REQ-LIMIT-4 an unknown turn adds nothing and is counted apart (0.440258ms)
|
||||
✔ REQ-LIMIT-2 the day turns at the reset in its zone, not in UTC, and before it the day is yesterday's (0.636362ms)
|
||||
✔ REQ-LIMIT-2 the spring DST change makes the day after a 00:00 reset 23 hours long (0.3629ms)
|
||||
✔ REQ-LIMIT-2 the fall DST change makes the day after a 00:00 reset 25 hours long (0.307097ms)
|
||||
✔ REQ-LIMIT-2 a reset the clocks skip starts the day at the first instant after the gap (1.317847ms)
|
||||
✔ REQ-LIMIT-2 a reset the clocks repeat starts one day, at the first one (0.410965ms)
|
||||
✔ REQ-LIMIT-2 a launch is refused at the quota, a turn that reaches it stops, and the next day allows again (1.040865ms)
|
||||
✔ REQ-LIMIT-2 counts past the safe integer range come back as digit strings (0.338405ms)
|
||||
✔ REQ-LIMIT-4 bad leaves, records or times throw a code, and the check reads nothing but its arguments (2.143241ms)
|
||||
✔ REQ-LIMIT-2 no daily quotas: every launch is allowed and the report is empty (0.174843ms)
|
||||
✖ P5 daily quota for a model key ID matches stack key records and resets the next day (0.717346ms)
|
||||
ℹ tests 28
|
||||
ℹ suites 0
|
||||
ℹ pass 19
|
||||
ℹ fail 9
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1055.443581
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/business/tests/token-limit-settings.test.mjs:154:1
|
||||
✖ P5 per-model-key quotas are unset by default, accept digit-leading IDs and only the human changes or resets them (2.663205ms)
|
||||
Error [BusinessError]: unsupported /tmp/mosaic-row333-4L4S3o/tmp/mosaic-business-CbuiLR/businesses/acme.json launch.limits.tokens.keys.012345abcdef key: "reset"
|
||||
at refuse (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/src/errors.mjs:12:9)
|
||||
at rejectUnknownKeys (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/src/util.mjs:17:33)
|
||||
at tokenLimit (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/src/launch.mjs:31:3)
|
||||
at file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/src/launch.mjs:57:80
|
||||
at Array.map (<anonymous>)
|
||||
at tokenMap (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/src/launch.mjs:57:51)
|
||||
at checkTokenLimits (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/src/launch.mjs:71:48)
|
||||
at checkLimits (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/src/launch.mjs:112:52)
|
||||
at checkLaunch (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/src/business.mjs:196:16)
|
||||
at validateBusinessDocument (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/src/business.mjs:310:57) {
|
||||
exitCode: 2
|
||||
}
|
||||
|
||||
test at packages/model-proxy/tests/usage-client.test.mjs:21:1
|
||||
✖ P5 queue read uses actual bounded fixed management GET and immediately drops client and upstream values (7.314165ms)
|
||||
TypeError: f.client.readUsageQueue is not a function
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/model-proxy/tests/usage-client.test.mjs:23:33)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
|
||||
test at packages/model-proxy/tests/usage-client.test.mjs:38:4
|
||||
✖ P5 bad envelope refuses safely with no retry (1.407651ms)
|
||||
TypeError: f.client.readUsageQueue is not a function
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/model-proxy/tests/usage-client.test.mjs:40:33)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
|
||||
test at packages/model-proxy/tests/usage-client.test.mjs:38:4
|
||||
✖ P5 over count refuses safely with no retry (0.970003ms)
|
||||
TypeError: f.client.readUsageQueue is not a function
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/model-proxy/tests/usage-client.test.mjs:40:33)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
|
||||
test at packages/model-proxy/tests/usage-client.test.mjs:38:4
|
||||
✖ P5 missing key refuses safely with no retry (0.457173ms)
|
||||
TypeError: f.client.readUsageQueue is not a function
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/model-proxy/tests/usage-client.test.mjs:40:33)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
|
||||
test at packages/model-proxy/tests/usage-client.test.mjs:38:4
|
||||
✖ P5 bad counts refuses safely with no retry (0.970914ms)
|
||||
TypeError: f.client.readUsageQueue is not a function
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/model-proxy/tests/usage-client.test.mjs:40:33)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
|
||||
test at packages/model-proxy/tests/usage-client.test.mjs:38:4
|
||||
✖ P5 redirect refuses safely with no retry (0.566467ms)
|
||||
TypeError: f.client.readUsageQueue is not a function
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/model-proxy/tests/usage-client.test.mjs:40:33)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
|
||||
test at packages/model-proxy/tests/usage-client.test.mjs:38:4
|
||||
✖ P5 refusal refuses safely with no retry (0.492518ms)
|
||||
TypeError: f.client.readUsageQueue is not a function
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/model-proxy/tests/usage-client.test.mjs:40:33)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
|
||||
test at packages/plugins/tests/daily-quota.test.mjs:173:1
|
||||
✖ P5 daily quota for a model key ID matches stack key records and resets the next day (0.717346ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
true !== false
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/plugins/tests/daily-quota.test.mjs:178:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: true,
|
||||
expected: false,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
✔ REQ-LIMIT-3 schema: each subject kind, limit 0 and no ceiling are accepted; bad limits, times, keys and undeclared instances refuse (12.739299ms)
|
||||
✔ REQ-LIMIT-3 the writer stamps since: a new limit gets now, a changed one keeps its time, a different time is refused (233.858718ms)
|
||||
✔ REQ-LIMIT-3 only tokens.* at schema depth holds token limits: agent limits named `limit` save as sent, and a token limit named `limit` is stamped and reset (274.692946ms)
|
||||
✔ REQ-LIMIT-3 a reset moves since to now, is logged with its actor, and refuses a path that is not a limit (129.01269ms)
|
||||
✔ REQ-LIMIT-2 schema: launch.account names a credential set; a daily quota needs a reset and an IANA zone and names the account (24.597721ms)
|
||||
✔ REQ-LIMIT-2 the writer stamps a daily quota's since, keeps its reset and zone, and a reset moves since (146.514468ms)
|
||||
✔ P5 per-model-key quotas are unset by default, accept digit-leading IDs and only the human changes or resets them (202.85529ms)
|
||||
✔ P5 queue read uses actual bounded fixed management GET and immediately drops client and upstream values (14.363195ms)
|
||||
✔ P5 bad envelope refuses safely with no retry (3.275949ms)
|
||||
✔ P5 over count refuses safely with no retry (1.650709ms)
|
||||
✔ P5 missing key refuses safely with no retry (1.355454ms)
|
||||
✔ P5 bad counts refuses safely with no retry (2.028358ms)
|
||||
✔ P5 redirect refuses safely with no retry (1.385706ms)
|
||||
✔ P5 refusal refuses safely with no retry (1.027413ms)
|
||||
✔ REQ-LIMIT-2 daily-quota exports interface version 2 with mayLaunch, mustStop and report (4.002643ms)
|
||||
✔ REQ-LIMIT-2 the count sums every kind of the account's known records since the later of the day start and since (11.703557ms)
|
||||
✔ REQ-LIMIT-2 a launch with no account (pi) is covered by no daily quota (0.285389ms)
|
||||
✔ REQ-LIMIT-4 an unknown turn adds nothing and is counted apart (0.427944ms)
|
||||
✔ REQ-LIMIT-2 the day turns at the reset in its zone, not in UTC, and before it the day is yesterday's (0.664291ms)
|
||||
✔ REQ-LIMIT-2 the spring DST change makes the day after a 00:00 reset 23 hours long (0.359593ms)
|
||||
✔ REQ-LIMIT-2 the fall DST change makes the day after a 00:00 reset 25 hours long (0.292084ms)
|
||||
✔ REQ-LIMIT-2 a reset the clocks skip starts the day at the first instant after the gap (1.428363ms)
|
||||
✔ REQ-LIMIT-2 a reset the clocks repeat starts one day, at the first one (0.427054ms)
|
||||
✔ REQ-LIMIT-2 a launch is refused at the quota, a turn that reaches it stops, and the next day allows again (1.066274ms)
|
||||
✔ REQ-LIMIT-2 counts past the safe integer range come back as digit strings (0.329306ms)
|
||||
✔ REQ-LIMIT-4 bad leaves, records or times throw a code, and the check reads nothing but its arguments (2.160938ms)
|
||||
✔ REQ-LIMIT-2 no daily quotas: every launch is allowed and the report is empty (0.172297ms)
|
||||
✔ P5 daily quota for a model key ID matches stack key records and resets the next day (0.746089ms)
|
||||
✔ REQ-LIMIT-3 token-limit exports interface version 2 with mayLaunch, mustStop and report (1.156529ms)
|
||||
✔ REQ-LIMIT-3 each subject kind refuses at its limit and allows under it (1.303907ms)
|
||||
✔ REQ-LIMIT-3 a limit covers only its own subject's records and launches (0.353216ms)
|
||||
✔ REQ-LIMIT-4 only known records count; an unknown turn adds nothing and is counted apart (0.2777ms)
|
||||
✔ REQ-LIMIT-3 a reset moves since: records before it no longer count (0.150391ms)
|
||||
✔ REQ-LIMIT-3 limit 0 refuses with no records; the first limit hit in file order is named (0.1377ms)
|
||||
✔ REQ-LIMIT-3 a key limit is not enforced while every record's account is null (decision 150 Q1) (0.170332ms)
|
||||
✔ REQ-LIMIT-3 counts past the safe integer range come back as digit strings (0.135122ms)
|
||||
✔ REQ-LIMIT-4 bad records or times throw a code, and the check reads nothing but its arguments (0.635473ms)
|
||||
✔ REQ-LIMIT-3 no token limits: every launch is allowed and the report is empty (0.62587ms)
|
||||
✔ REQ-LIMIT-3 token-limit ignores tokens.daily, which the daily-quota check enforces (row 126) (0.130727ms)
|
||||
✔ P5 a model key ID limit counts stack records by key ID without an account (0.11813ms)
|
||||
ℹ tests 40
|
||||
ℹ suites 0
|
||||
ℹ pass 40
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1270.553008
|
||||
@@ -0,0 +1,80 @@
|
||||
node:internal/modules/esm/resolve:272
|
||||
throw new ERR_MODULE_NOT_FOUND(
|
||||
^
|
||||
|
||||
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/src/proxy-usage.mjs' imported from /home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/proxy-usage.test.mjs
|
||||
at finalizeResolution (node:internal/modules/esm/resolve:272:11)
|
||||
at moduleResolve (node:internal/modules/esm/resolve:879:10)
|
||||
at defaultResolve (node:internal/modules/esm/resolve:1006:11)
|
||||
at #cachedDefaultResolve (node:internal/modules/esm/loader:708:20)
|
||||
at #resolveAndMaybeBlockOnLoaderThread (node:internal/modules/esm/loader:728:38)
|
||||
at ModuleLoader.resolveSync (node:internal/modules/esm/loader:766:56)
|
||||
at #resolve (node:internal/modules/esm/loader:690:17)
|
||||
at ModuleLoader.getOrCreateModuleJob (node:internal/modules/esm/loader:610:35)
|
||||
at ModuleJob.syncLink (node:internal/modules/esm/module_job:277:33)
|
||||
at ModuleJob.link (node:internal/modules/esm/module_job:389:17) {
|
||||
code: 'ERR_MODULE_NOT_FOUND',
|
||||
url: 'file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/src/proxy-usage.mjs'
|
||||
}
|
||||
|
||||
Node.js v26.8.1
|
||||
✖ packages/bus/tests/proxy-usage.test.mjs (51.269919ms)
|
||||
✔ REQ-LIMIT-4 loader source records new turn kinds, excludes history and retries exactly once (51.514952ms)
|
||||
✔ REQ-LIMIT-4 cut: unknown is durable and logged next to every total (50.36014ms)
|
||||
✔ REQ-LIMIT-4 disabled: unknown is durable and logged next to every total (46.155638ms)
|
||||
✔ REQ-LIMIT-4 missing-begin: unknown is durable and logged next to every total (40.267126ms)
|
||||
✔ REQ-LIMIT-4 no-new-usage: unknown is durable and logged next to every total (45.725198ms)
|
||||
✔ REQ-LIMIT-4 rewrite: unknown is durable and logged next to every total (45.864606ms)
|
||||
✔ REQ-LIMIT-4 unfinished turn remains visibly unknown after accounting restarts (40.628929ms)
|
||||
✔ usage records are append-only (40.809636ms)
|
||||
✔ REQ-LIMIT-4 parse failure logs its safe code, never transcript content (46.321713ms)
|
||||
✔ REQ-LIMIT-4 resumed run baselines history and exact totals do not overflow (56.488827ms)
|
||||
✔ REQ-PLUG-1 core has no transcript import and disabled sources do not read any transcript (45.994492ms)
|
||||
✔ REQ-LIMIT-4 a resumed thread bills only new assistant messages to its next run (46.867774ms)
|
||||
✔ REQ-LIMIT-4 every enabled source is called; failure is unknown and a partial total stays labelled (55.909721ms)
|
||||
✔ REQ-LIMIT-4 a turn whose reported sum exceeds safe precision is unknown, not rounded (72.188479ms)
|
||||
✔ row 65 a run bound without a transcript directory records no-transcript (47.882475ms)
|
||||
✖ P5 immutable stack key attribution survives rotation and restart without key values (46.501339ms)
|
||||
✔ REQ-PLUG-1 schema: plugins is optional, names known kinds and checked module names (10.169709ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the setter writes plugins through the organization writer and logs old and new names (136.187046ms)
|
||||
✔ vikunja:19/309 a patch changes only the kinds it names; null removes one kind, explicitly and in the trail (158.840283ms)
|
||||
✔ vikunja:19/309 an unknown kind (set or removed), a bad module, an empty patch and null on the wrong shape are refused, nothing written (1.730784ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the writer checks the bytes it writes: a Date in plugins is refused there too (19.213042ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 a refused setter write throws a code, changes nothing and logs nothing (1.512701ms)
|
||||
✔ vikunja:19/305 with an exists check, the setter refuses a module no tree file answers to, before anything is written (56.368217ms)
|
||||
✖ P5 optional usage kind and pollSeconds configure through plugins.set; default stays absent and retention bound is strict (1.972898ms)
|
||||
ℹ tests 25
|
||||
ℹ suites 0
|
||||
ℹ pass 22
|
||||
ℹ fail 3
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1344.122542
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/proxy-usage.test.mjs:1:1
|
||||
✖ packages/bus/tests/proxy-usage.test.mjs (51.269919ms)
|
||||
'test failed'
|
||||
|
||||
test at packages/bus/tests/usage.test.mjs:157:1
|
||||
✖ P5 immutable stack key attribution survives rotation and restart without key values (46.501339ms)
|
||||
TypeError: Cannot read properties of undefined (reading '0')
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/usage.test.mjs:162:39)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
|
||||
test at packages/business/tests/plugin-settings.test.mjs:148:1
|
||||
✖ P5 optional usage kind and pollSeconds configure through plugins.set; default stays absent and retention bound is strict (1.972898ms)
|
||||
Error: invalid-request
|
||||
at Object.set (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/src/plugin-settings.mjs:22:13)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/tests/plugin-settings.test.mjs:150:15)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
code: 'invalid-request'
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/src/limits.mjs:126
|
||||
const key = keyForSubject(business, subject);
|
||||
^
|
||||
|
||||
SyntaxError: Identifier 'key' has already been declared
|
||||
at compileSourceTextModule (node:internal/modules/esm/utils:355:16)
|
||||
at ModuleLoader.moduleStrategy (node:internal/modules/esm/translators:93:18)
|
||||
at #translate (node:internal/modules/esm/loader:441:20)
|
||||
at afterLoad (node:internal/modules/esm/loader:509:29)
|
||||
at ModuleLoader.loadAndTranslate (node:internal/modules/esm/loader:514:12)
|
||||
at #getOrCreateModuleJobAfterResolve (node:internal/modules/esm/loader:567:36)
|
||||
at afterResolve (node:internal/modules/esm/loader:614:52)
|
||||
at ModuleLoader.getOrCreateModuleJob (node:internal/modules/esm/loader:620:12)
|
||||
at ModuleJob.syncLink (node:internal/modules/esm/module_job:277:33)
|
||||
at ModuleJob.link (node:internal/modules/esm/module_job:389:17)
|
||||
|
||||
Node.js v26.8.1
|
||||
✖ packages/bus/tests/proxy-usage.test.mjs (51.892872ms)
|
||||
✔ REQ-LIMIT-4 loader source records new turn kinds, excludes history and retries exactly once (50.378772ms)
|
||||
✔ REQ-LIMIT-4 cut: unknown is durable and logged next to every total (45.234905ms)
|
||||
✔ REQ-LIMIT-4 disabled: unknown is durable and logged next to every total (44.712639ms)
|
||||
✔ REQ-LIMIT-4 missing-begin: unknown is durable and logged next to every total (38.834227ms)
|
||||
✔ REQ-LIMIT-4 no-new-usage: unknown is durable and logged next to every total (45.613047ms)
|
||||
✔ REQ-LIMIT-4 rewrite: unknown is durable and logged next to every total (61.823662ms)
|
||||
✔ REQ-LIMIT-4 unfinished turn remains visibly unknown after accounting restarts (39.178221ms)
|
||||
✔ usage records are append-only (48.911454ms)
|
||||
✔ REQ-LIMIT-4 parse failure logs its safe code, never transcript content (44.798699ms)
|
||||
✔ REQ-LIMIT-4 resumed run baselines history and exact totals do not overflow (74.440531ms)
|
||||
✔ REQ-PLUG-1 core has no transcript import and disabled sources do not read any transcript (44.272941ms)
|
||||
✔ REQ-LIMIT-4 a resumed thread bills only new assistant messages to its next run (45.321015ms)
|
||||
✔ REQ-LIMIT-4 every enabled source is called; failure is unknown and a partial total stays labelled (50.132554ms)
|
||||
✔ REQ-LIMIT-4 a turn whose reported sum exceeds safe precision is unknown, not rounded (45.271975ms)
|
||||
✔ row 65 a run bound without a transcript directory records no-transcript (45.784161ms)
|
||||
✔ P5 immutable stack key attribution survives rotation and restart without key values (46.660026ms)
|
||||
✔ REQ-PLUG-1 schema: plugins is optional, names known kinds and checked module names (9.948537ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the setter writes plugins through the organization writer and logs old and new names (133.831911ms)
|
||||
✔ vikunja:19/309 a patch changes only the kinds it names; null removes one kind, explicitly and in the trail (204.184755ms)
|
||||
✔ vikunja:19/309 an unknown kind (set or removed), a bad module, an empty patch and null on the wrong shape are refused, nothing written (1.716312ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the writer checks the bytes it writes: a Date in plugins is refused there too (21.420971ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 a refused setter write throws a code, changes nothing and logs nothing (1.601618ms)
|
||||
✔ vikunja:19/305 with an exists check, the setter refuses a module no tree file answers to, before anything is written (51.983097ms)
|
||||
✔ P5 optional usage kind and pollSeconds configure through plugins.set; default stays absent and retention bound is strict (99.930829ms)
|
||||
ℹ tests 25
|
||||
ℹ suites 0
|
||||
ℹ pass 24
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1470.74285
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/proxy-usage.test.mjs:1:1
|
||||
✖ packages/bus/tests/proxy-usage.test.mjs (51.892872ms)
|
||||
'test failed'
|
||||
@@ -0,0 +1,37 @@
|
||||
✔ P5 usage plugin off by default, default poll is 15 seconds and configured polls skip early ticks (65.214926ms)
|
||||
✔ P5 safe telemetry stores failures per key and proxy-labelled accounts; no client/upstream value enters store/log/view or quota records (52.537861ms)
|
||||
✔ P5 unknown msk key goes only to value-free reconcile log and other businesses stay isolated (41.558814ms)
|
||||
✔ P5 queue failure is safe, does not enforce and does not retry before poll deadline (41.087812ms)
|
||||
✔ P5 retiring key keeps attribution and telemetry rows remain append-only across reader restart (47.727536ms)
|
||||
✔ REQ-LIMIT-4 loader source records new turn kinds, excludes history and retries exactly once (50.881627ms)
|
||||
✔ REQ-LIMIT-4 cut: unknown is durable and logged next to every total (45.298282ms)
|
||||
✔ REQ-LIMIT-4 disabled: unknown is durable and logged next to every total (44.997351ms)
|
||||
✔ REQ-LIMIT-4 missing-begin: unknown is durable and logged next to every total (39.610461ms)
|
||||
✔ REQ-LIMIT-4 no-new-usage: unknown is durable and logged next to every total (45.405893ms)
|
||||
✔ REQ-LIMIT-4 rewrite: unknown is durable and logged next to every total (45.836002ms)
|
||||
✔ REQ-LIMIT-4 unfinished turn remains visibly unknown after accounting restarts (40.248661ms)
|
||||
✔ usage records are append-only (40.155769ms)
|
||||
✔ REQ-LIMIT-4 parse failure logs its safe code, never transcript content (45.604899ms)
|
||||
✔ REQ-LIMIT-4 resumed run baselines history and exact totals do not overflow (55.889033ms)
|
||||
✔ REQ-PLUG-1 core has no transcript import and disabled sources do not read any transcript (44.53629ms)
|
||||
✔ REQ-LIMIT-4 a resumed thread bills only new assistant messages to its next run (45.80935ms)
|
||||
✔ REQ-LIMIT-4 every enabled source is called; failure is unknown and a partial total stays labelled (54.81715ms)
|
||||
✔ REQ-LIMIT-4 a turn whose reported sum exceeds safe precision is unknown, not rounded (46.31434ms)
|
||||
✔ row 65 a run bound without a transcript directory records no-transcript (46.570895ms)
|
||||
✔ P5 immutable stack key attribution survives rotation and restart without key values (47.523777ms)
|
||||
✔ REQ-PLUG-1 schema: plugins is optional, names known kinds and checked module names (9.987571ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the setter writes plugins through the organization writer and logs old and new names (141.127286ms)
|
||||
✔ vikunja:19/309 a patch changes only the kinds it names; null removes one kind, explicitly and in the trail (184.625638ms)
|
||||
✔ vikunja:19/309 an unknown kind (set or removed), a bad module, an empty patch and null on the wrong shape are refused, nothing written (1.650477ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the writer checks the bytes it writes: a Date in plugins is refused there too (22.208259ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 a refused setter write throws a code, changes nothing and logs nothing (1.619398ms)
|
||||
✔ vikunja:19/305 with an exists check, the setter refuses a module no tree file answers to, before anything is written (53.382155ms)
|
||||
✔ P5 optional usage kind and pollSeconds configure through plugins.set; default stays absent and retention bound is strict (100.346538ms)
|
||||
ℹ tests 29
|
||||
ℹ suites 0
|
||||
ℹ pass 29
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1701.08968
|
||||
@@ -0,0 +1,61 @@
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mayLaunch","subject":{"instance":"coder","provider":"anthropic","model":"opus","account":"jason-max"},"path":["tokens","daily","jason-max"],"limit":0,"count":0,"unknownTurns":0}
|
||||
usage: {"event":"usage-unknown","business":"demo","run":"run1","instance":"coder","turn":"0f9af1a6-ff5d-4a03-8deb-ee3d9ff7a587","source":"@none","code":"baseline-unknown"}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mustStop","subject":{"instance":"coder","provider":"anthropic","model":"opus","account":"jason-max","run":"run1"},"path":["tokens","daily","jason-max"],"limit":0,"count":0,"unknownTurns":1}
|
||||
usage: {"event":"usage-unknown","business":"demo","run":"run1","instance":"coder","turn":"139909cd-89c9-47ab-8924-fef1d9125ebc","source":"@none","code":"baseline-unknown"}
|
||||
✔ REQ-LIMIT-2 runtime: limits counts the daily quota, and mayLaunch refuses only the account at it (160.313054ms)
|
||||
✔ REQ-LIMIT-4 runtime: a run bound with the account writes it on its usage records and stops at the quota (141.082402ms)
|
||||
✔ REQ-LIMIT-4 runtime: a run bound without an account records null and the daily quota never stops it (118.409041ms)
|
||||
✔ REQ-LIMIT-4 bindLaunch keeps the account off session.launched, refuses one that is not an identifier, and takes null as none (60.812376ms)
|
||||
✔ P5 usage plugin off by default, default poll is 15 seconds and configured polls skip early ticks (67.249055ms)
|
||||
✔ P5 safe telemetry stores failures per key and proxy-labelled accounts; no client/upstream value enters store/log/view or quota records (48.031566ms)
|
||||
✔ P5 unknown msk key goes only to value-free reconcile log and other businesses stay isolated (46.042815ms)
|
||||
✔ P5 queue failure is safe, does not enforce and does not retry before poll deadline (41.173899ms)
|
||||
✔ P5 retiring key keeps attribution and telemetry rows remain append-only across reader restart (52.566146ms)
|
||||
✔ REQ-PLUG-1 runtime reaches transcript only through loader, over the real bus socket (131.491274ms)
|
||||
✔ REQ-LIMIT-4 loader source records new turn kinds, excludes history and retries exactly once (52.546321ms)
|
||||
✔ REQ-LIMIT-4 cut: unknown is durable and logged next to every total (47.077487ms)
|
||||
✔ REQ-LIMIT-4 disabled: unknown is durable and logged next to every total (46.271817ms)
|
||||
✔ REQ-LIMIT-4 missing-begin: unknown is durable and logged next to every total (40.225039ms)
|
||||
✔ REQ-LIMIT-4 no-new-usage: unknown is durable and logged next to every total (45.02419ms)
|
||||
✔ REQ-LIMIT-4 rewrite: unknown is durable and logged next to every total (47.584801ms)
|
||||
✔ REQ-LIMIT-4 unfinished turn remains visibly unknown after accounting restarts (40.815955ms)
|
||||
✔ usage records are append-only (41.122845ms)
|
||||
✔ REQ-LIMIT-4 parse failure logs its safe code, never transcript content (45.862091ms)
|
||||
✔ REQ-LIMIT-4 resumed run baselines history and exact totals do not overflow (57.327879ms)
|
||||
✔ REQ-PLUG-1 core has no transcript import and disabled sources do not read any transcript (47.939521ms)
|
||||
✔ REQ-LIMIT-4 a resumed thread bills only new assistant messages to its next run (46.384741ms)
|
||||
✔ REQ-LIMIT-4 every enabled source is called; failure is unknown and a partial total stays labelled (98.373431ms)
|
||||
✔ REQ-LIMIT-4 a turn whose reported sum exceeds safe precision is unknown, not rounded (46.863279ms)
|
||||
✔ row 65 a run bound without a transcript directory records no-transcript (47.359644ms)
|
||||
✔ P5 immutable stack key attribution survives rotation and restart without key values (51.503418ms)
|
||||
✔ REQ-PLUG-1 REQ-LIMIT-4 the registry: usage-source at interface version 1, limit-check at 2 (row 125), each a list (1.131497ms)
|
||||
✔ REQ-PLUG-1 checkPlugins accepts one key per kind, each a list of names, empty included (0.214135ms)
|
||||
✔ REQ-PLUG-1 checkPlugins refuses bad shapes, unknown kinds, bad names and duplicates (0.919785ms)
|
||||
✔ REQ-PLUG-1 a kind that switches on one module takes one name, not a list (0.136387ms)
|
||||
✔ REQ-PLUG-1 checkPlugins reports through the caller's fail callback (0.149287ms)
|
||||
✔ P5 usage telemetry is optional, single module, separate from enforcing sources (0.136962ms)
|
||||
✔ REQ-PLUG-1 fixture modules of each kind switch on from a test organization file, no core file changed (8.544145ms)
|
||||
✔ REQ-PLUG-1 a name not matching ^[a-z][a-z0-9-]*$ refuses and keeps the old setting (3.570635ms)
|
||||
✔ REQ-PLUG-1 a missing module directory or index.mjs refuses and keeps the old setting (3.394552ms)
|
||||
✔ REQ-PLUG-1 a symlinked module directory or index.mjs refuses and keeps the old setting (2.605144ms)
|
||||
✔ REQ-PLUG-1 a symlinked kind directory refuses and keeps the old setting (2.314239ms)
|
||||
✔ REQ-PLUG-1 a symlinked packages/plugins refuses (run with --preserve-symlinks so the path keeps it) (30.160706ms)
|
||||
✔ REQ-PLUG-1 index.mjs swapped for a symlink after the lstat checks refuses at the realpath check (3.027836ms)
|
||||
✔ REQ-PLUG-1 a path that can't be read refuses as unreadable, is logged and keeps the old setting (2.75119ms)
|
||||
✔ REQ-PLUG-1 a path that becomes unreadable after the lstat checks refuses at either realpath (2.412894ms)
|
||||
✔ REQ-PLUG-1 a module that fails to load refuses and keeps the old setting (2.793659ms)
|
||||
✔ REQ-PLUG-1 a missing export refuses and keeps the old setting (3.303983ms)
|
||||
✔ REQ-PLUG-1 a different interface version refuses and keeps the old setting (2.5092ms)
|
||||
✔ REQ-PLUG-1 REQ-LIMIT-3 a version 1 limit check refuses after the bump to 2, and the old setting stays (2.97048ms)
|
||||
✔ REQ-PLUG-1 a kind refused on its first load has nothing switched on, and the log names kind and name (1.870072ms)
|
||||
✔ REQ-PLUG-1 the setting's shape: unknown kinds refuse alone, a bad whole setting keeps everything (2.648634ms)
|
||||
✔ REQ-PLUG-1 loads run one at a time, so the last requested setting wins (102.357607ms)
|
||||
✔ REQ-PLUG-1 the loader needs a log callback (1.14637ms)
|
||||
ℹ tests 49
|
||||
ℹ suites 0
|
||||
ℹ pass 49
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 2281.541817
|
||||
@@ -0,0 +1,120 @@
|
||||
✔ REQ-LIMIT-3 limitLeaves finds every limit object and skips the agent numbers (1.223541ms)
|
||||
✔ REQ-LIMIT-3 limitLeaves takes token limits at schema depth only, whatever their names (0.222664ms)
|
||||
✔ REQ-LIMIT-3 with no check switched on a launch is allowed, a turn never stops, and every limit is not enforced (52.7698ms)
|
||||
✔ REQ-LIMIT-3 a fixture check that refuses refuses the launch and stops the turn, logged with the limit and the count (43.539654ms)
|
||||
✔ REQ-LIMIT-3 a report that omits a limit shows it not enforced; a counted entry and a reason come through (42.903925ms)
|
||||
✔ REQ-LIMIT-4 each check gets the business, a copy of the limits, the subject, the records and the time (55.045959ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a throw refuses, stops and fails the report, naming the check and the code (44.040412ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a malformed answer, a promise, a rejected promise, a non-boolean or a bad hit is malformed-answer (47.200469ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a check switched on but not loaded refuses, stops and fails every limit as not-loaded (43.887012ms)
|
||||
✔ REQ-LIMIT-4 state(), never-loaded case: before any load the report shows not enforced, or not-loaded for a switched-on check (42.425785ms)
|
||||
✔ REQ-LIMIT-4 state(), first-load-refused case: a check refused on its first load is not-loaded in mayLaunch, mustStop and report (44.483506ms)
|
||||
✔ REQ-LIMIT-4 fail closed: an unreadable organization file refuses and stops with check null; the report throws (43.702967ms)
|
||||
✔ REQ-LIMIT-4 fail closed: unreadable records refuse and stop with check null and fail the report (0.492979ms)
|
||||
✔ REQ-LIMIT-3 the shipped token-limit, through the real loader, counts known records only since the limit was set (85.991456ms)
|
||||
✔ REQ-LIMIT-3 a token limit for a provider named limit is counted and refuses, beside an agent limit of the same name (51.829594ms)
|
||||
✔ REQ-LIMIT-3 core reaches limit checks only through the plug-in loader (1.348009ms)
|
||||
✖ P5 missing, ambiguous or invalid model key lookup fails closed without leaking a lookup error (41.10118ms)
|
||||
✔ P5 trusted lookup uses the retiring run key rather than the agent current key (39.693163ms)
|
||||
✔ REQ-PLUG-1 schema: plugins is optional, names known kinds and checked module names (9.742544ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the setter writes plugins through the organization writer and logs old and new names (146.282626ms)
|
||||
✔ vikunja:19/309 a patch changes only the kinds it names; null removes one kind, explicitly and in the trail (169.54836ms)
|
||||
✔ vikunja:19/309 an unknown kind (set or removed), a bad module, an empty patch and null on the wrong shape are refused, nothing written (1.751884ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the writer checks the bytes it writes: a Date in plugins is refused there too (21.391321ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 a refused setter write throws a code, changes nothing and logs nothing (1.677099ms)
|
||||
✔ vikunja:19/305 with an exists check, the setter refuses a module no tree file answers to, before anything is written (52.536228ms)
|
||||
✔ P5 optional usage kind and pollSeconds configure through plugins.set; default stays absent and retention bound is strict (94.782042ms)
|
||||
✖ P5 only human can enable/disable telemetry or change polling, including direct organization writes (50.536153ms)
|
||||
✖ P5 Console displays stack count per safe key separately from optional proxy account numbers (1.0934ms)
|
||||
✖ P5 Console escapes hostile labels and labels unavailable telemetry without presenting a fresh zero (0.228091ms)
|
||||
ℹ tests 29
|
||||
ℹ suites 0
|
||||
ℹ pass 25
|
||||
ℹ fail 4
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1398.637079
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/limit-checks.test.mjs:328:1
|
||||
✖ P5 missing, ambiguous or invalid model key lookup fails closed without leaking a lookup error (41.10118ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
+ allow: true
|
||||
- allow: false,
|
||||
- check: null,
|
||||
- code: 'proxy-key-refused'
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/limit-checks.test.mjs:333:10)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { allow: true },
|
||||
expected: { allow: false, check: null, code: 'proxy-key-refused' },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/business/tests/plugin-settings.test.mjs:161:1
|
||||
✖ P5 only human can enable/disable telemetry or change polling, including direct organization writes (50.536153ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/business/tests/plugin-settings.test.mjs:163:56)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: undefined,
|
||||
expected: { code: 'organization-usage-human-only' },
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/webui/tests/usage-render.test.mjs:10:1
|
||||
✖ P5 Console displays stack count per safe key separately from optional proxy account numbers (1.0934ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /Key: 012345abcdef/. Input:
|
||||
|
||||
'<section class="panel" aria-labelledby="token-usage-title"><h2 id="token-usage-title">Token usage</h2><p>Best reading of session-editable transcripts, not proof. Unknown turns may have used more tokens. Account is unassigned until account tracking is configured.</p><div class="table-wrap"><table id="token-usage-table"><thead><tr><th scope="col">Subject</th><th scope="col">Input</th><th scope="col">Output</th><th scope="col">Cache write</th><th scope="col">Cache read</th><th scope="col">Unknown turns</th></tr></thead><tbody><tr><th scope="row">Total</th><td>2</td><td>3</td><td>4</td><td>5</td><td>0</td></tr></tbody></table></div></section>'
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/webui/tests/usage-render.test.mjs:12:34)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.start (node:internal/test_runner/test:1262:17)
|
||||
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: '<section class="panel" aria-labelledby="token-usage-title"><h2 id="token-usage-title">Token usage</h2><p>Best reading of session-editable transcripts, not proof. Unknown turns may have used more tokens. Account is unassigned until account tracking is configured.</p><div class="table-wrap"><table id="token-usage-table"><thead><tr><th scope="col">Subject</th><th scope="col">Input</th><th scope="col">Output</th><th scope="col">Cache write</th><th scope="col">Cache read</th><th scope="col">Unknown turns</th></tr></thead><tbody><tr><th scope="row">Total</th><td>2</td><td>3</td><td>4</td><td>5</td><td>0</td></tr></tbody></table></div></section>',
|
||||
expected: /Key: 012345abcdef/,
|
||||
operator: 'match',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/webui/tests/usage-render.test.mjs:17:1
|
||||
✖ P5 Console escapes hostile labels and labels unavailable telemetry without presenting a fresh zero (0.228091ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /unavailable/. Input:
|
||||
|
||||
'<section class="panel" aria-labelledby="token-usage-title"><h2 id="token-usage-title">Token usage</h2><p>Best reading of session-editable transcripts, not proof. Unknown turns may have used more tokens. Account is unassigned until account tracking is configured.</p><div class="table-wrap"><table id="token-usage-table"><thead><tr><th scope="col">Subject</th><th scope="col">Input</th><th scope="col">Output</th><th scope="col">Cache write</th><th scope="col">Cache read</th><th scope="col">Unknown turns</th></tr></thead><tbody><tr><th scope="row">Total</th><td>2</td><td>3</td><td>4</td><td>5</td><td>0</td></tr></tbody></table></div></section>'
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/webui/tests/usage-render.test.mjs:19:42)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: '<section class="panel" aria-labelledby="token-usage-title"><h2 id="token-usage-title">Token usage</h2><p>Best reading of session-editable transcripts, not proof. Unknown turns may have used more tokens. Account is unassigned until account tracking is configured.</p><div class="table-wrap"><table id="token-usage-table"><thead><tr><th scope="col">Subject</th><th scope="col">Input</th><th scope="col">Output</th><th scope="col">Cache write</th><th scope="col">Cache read</th><th scope="col">Unknown turns</th></tr></thead><tbody><tr><th scope="row">Total</th><td>2</td><td>3</td><td>4</td><td>5</td><td>0</td></tr></tbody></table></div></section>',
|
||||
expected: /unavailable/,
|
||||
operator: 'match',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
✔ REQ-LIMIT-3 limitLeaves finds every limit object and skips the agent numbers (1.351672ms)
|
||||
✔ REQ-LIMIT-3 limitLeaves takes token limits at schema depth only, whatever their names (0.197022ms)
|
||||
✔ REQ-LIMIT-3 with no check switched on a launch is allowed, a turn never stops, and every limit is not enforced (45.900174ms)
|
||||
✔ REQ-LIMIT-3 a fixture check that refuses refuses the launch and stops the turn, logged with the limit and the count (48.270064ms)
|
||||
✔ REQ-LIMIT-3 a report that omits a limit shows it not enforced; a counted entry and a reason come through (46.136204ms)
|
||||
✔ REQ-LIMIT-4 each check gets the business, a copy of the limits, the subject, the records and the time (57.022124ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a throw refuses, stops and fails the report, naming the check and the code (45.147203ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a malformed answer, a promise, a rejected promise, a non-boolean or a bad hit is malformed-answer (47.845585ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a check switched on but not loaded refuses, stops and fails every limit as not-loaded (43.247414ms)
|
||||
✔ REQ-LIMIT-4 state(), never-loaded case: before any load the report shows not enforced, or not-loaded for a switched-on check (45.643077ms)
|
||||
✔ REQ-LIMIT-4 state(), first-load-refused case: a check refused on its first load is not-loaded in mayLaunch, mustStop and report (37.420192ms)
|
||||
✔ REQ-LIMIT-4 fail closed: an unreadable organization file refuses and stops with check null; the report throws (41.526492ms)
|
||||
✔ REQ-LIMIT-4 fail closed: unreadable records refuse and stop with check null and fail the report (0.579005ms)
|
||||
✔ REQ-LIMIT-3 the shipped token-limit, through the real loader, counts known records only since the limit was set (89.130888ms)
|
||||
✔ REQ-LIMIT-3 a token limit for a provider named limit is counted and refuses, beside an agent limit of the same name (53.18557ms)
|
||||
✔ REQ-LIMIT-3 core reaches limit checks only through the plug-in loader (1.432955ms)
|
||||
✖ P5 missing, ambiguous or invalid model key lookup fails closed without leaking a lookup error (45.896754ms)
|
||||
✔ P5 trusted lookup uses the retiring run key rather than the agent current key (40.6658ms)
|
||||
✖ P5 actual model metadata lookup rejects missing/ambiguous owners and never cross-attributes a retiring run (0.282933ms)
|
||||
ℹ tests 19
|
||||
ℹ suites 0
|
||||
ℹ pass 17
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 767.199722
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/limit-checks.test.mjs:328:1
|
||||
✖ P5 missing, ambiguous or invalid model key lookup fails closed without leaking a lookup error (45.896754ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
+ allow: true
|
||||
- allow: false,
|
||||
- check: null,
|
||||
- code: 'proxy-key-refused'
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/limit-checks.test.mjs:333:10)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { allow: true },
|
||||
expected: { allow: false, check: null, code: 'proxy-key-refused' },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/limit-checks.test.mjs:346:1
|
||||
✖ P5 actual model metadata lookup rejects missing/ambiguous owners and never cross-attributes a retiring run (0.282933ms)
|
||||
TypeError: modelUsageKey is not a function
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/limit-checks.test.mjs:351:15)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
@@ -0,0 +1,66 @@
|
||||
✔ REQ-LIMIT-3 limitLeaves finds every limit object and skips the agent numbers (1.471904ms)
|
||||
✔ REQ-LIMIT-3 limitLeaves takes token limits at schema depth only, whatever their names (0.238869ms)
|
||||
✔ REQ-LIMIT-3 with no check switched on a launch is allowed, a turn never stops, and every limit is not enforced (48.889383ms)
|
||||
✔ REQ-LIMIT-3 a fixture check that refuses refuses the launch and stops the turn, logged with the limit and the count (48.804518ms)
|
||||
✔ REQ-LIMIT-3 a report that omits a limit shows it not enforced; a counted entry and a reason come through (47.424391ms)
|
||||
✔ REQ-LIMIT-4 each check gets the business, a copy of the limits, the subject, the records and the time (58.732905ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a throw refuses, stops and fails the report, naming the check and the code (46.311117ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a malformed answer, a promise, a rejected promise, a non-boolean or a bad hit is malformed-answer (52.110899ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a check switched on but not loaded refuses, stops and fails every limit as not-loaded (50.032452ms)
|
||||
✔ REQ-LIMIT-4 state(), never-loaded case: before any load the report shows not enforced, or not-loaded for a switched-on check (45.35538ms)
|
||||
✔ REQ-LIMIT-4 state(), first-load-refused case: a check refused on its first load is not-loaded in mayLaunch, mustStop and report (45.361587ms)
|
||||
✔ REQ-LIMIT-4 fail closed: an unreadable organization file refuses and stops with check null; the report throws (47.343794ms)
|
||||
✔ REQ-LIMIT-4 fail closed: unreadable records refuse and stop with check null and fail the report (0.52398ms)
|
||||
✔ REQ-LIMIT-3 the shipped token-limit, through the real loader, counts known records only since the limit was set (91.231334ms)
|
||||
✔ REQ-LIMIT-3 a token limit for a provider named limit is counted and refuses, beside an agent limit of the same name (56.207075ms)
|
||||
✔ REQ-LIMIT-3 core reaches limit checks only through the plug-in loader (1.2189ms)
|
||||
✖ P5 missing, ambiguous or invalid model key lookup fails closed without leaking a lookup error (44.848352ms)
|
||||
✔ P5 trusted lookup uses the retiring run key rather than the agent current key (43.672096ms)
|
||||
✖ P5 actual model metadata lookup rejects missing/ambiguous owners and never cross-attributes a retiring run (0.426717ms)
|
||||
ℹ tests 19
|
||||
ℹ suites 0
|
||||
ℹ pass 17
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 816.537108
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/limit-checks.test.mjs:328:1
|
||||
✖ P5 missing, ambiguous or invalid model key lookup fails closed without leaking a lookup error (44.848352ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
+ allow: true
|
||||
- allow: false,
|
||||
- check: null,
|
||||
- code: 'proxy-key-refused'
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/limit-checks.test.mjs:333:10)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { allow: true },
|
||||
expected: { allow: false, check: null, code: 'proxy-key-refused' },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/limit-checks.test.mjs:346:1
|
||||
✖ P5 actual model metadata lookup rejects missing/ambiguous owners and never cross-attributes a retiring run (0.426717ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/limit-checks.test.mjs:354:10)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: undefined,
|
||||
expected: { code: 'proxy-key-refused' },
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
✔ REQ-LIMIT-3 limitLeaves finds every limit object and skips the agent numbers (1.497774ms)
|
||||
✔ REQ-LIMIT-3 limitLeaves takes token limits at schema depth only, whatever their names (0.231342ms)
|
||||
✔ REQ-LIMIT-3 with no check switched on a launch is allowed, a turn never stops, and every limit is not enforced (41.157068ms)
|
||||
✔ REQ-LIMIT-3 a fixture check that refuses refuses the launch and stops the turn, logged with the limit and the count (47.622762ms)
|
||||
✔ REQ-LIMIT-3 a report that omits a limit shows it not enforced; a counted entry and a reason come through (40.772915ms)
|
||||
✔ REQ-LIMIT-4 each check gets the business, a copy of the limits, the subject, the records and the time (64.210535ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a throw refuses, stops and fails the report, naming the check and the code (41.33012ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a malformed answer, a promise, a rejected promise, a non-boolean or a bad hit is malformed-answer (46.47583ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a check switched on but not loaded refuses, stops and fails every limit as not-loaded (42.554949ms)
|
||||
✔ REQ-LIMIT-4 state(), never-loaded case: before any load the report shows not enforced, or not-loaded for a switched-on check (42.55839ms)
|
||||
✔ REQ-LIMIT-4 state(), first-load-refused case: a check refused on its first load is not-loaded in mayLaunch, mustStop and report (42.856274ms)
|
||||
✔ REQ-LIMIT-4 fail closed: an unreadable organization file refuses and stops with check null; the report throws (42.087566ms)
|
||||
✔ REQ-LIMIT-4 fail closed: unreadable records refuse and stop with check null and fail the report (0.540151ms)
|
||||
✔ REQ-LIMIT-3 the shipped token-limit, through the real loader, counts known records only since the limit was set (83.555041ms)
|
||||
✔ REQ-LIMIT-3 a token limit for a provider named limit is counted and refuses, beside an agent limit of the same name (50.237156ms)
|
||||
✔ REQ-LIMIT-3 core reaches limit checks only through the plug-in loader (1.834976ms)
|
||||
✔ P5 missing, ambiguous or invalid model key lookup fails closed without leaking a lookup error (41.561579ms)
|
||||
✔ P5 trusted lookup uses the retiring run key rather than the agent current key (40.600997ms)
|
||||
✔ P5 actual model metadata lookup rejects missing/ambiguous owners and never cross-attributes a retiring run (0.439799ms)
|
||||
✔ REQ-PLUG-1 schema: plugins is optional, names known kinds and checked module names (10.470972ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the setter writes plugins through the organization writer and logs old and new names (139.490847ms)
|
||||
✔ vikunja:19/309 a patch changes only the kinds it names; null removes one kind, explicitly and in the trail (177.184056ms)
|
||||
✔ vikunja:19/309 an unknown kind (set or removed), a bad module, an empty patch and null on the wrong shape are refused, nothing written (1.815855ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the writer checks the bytes it writes: a Date in plugins is refused there too (21.853399ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 a refused setter write throws a code, changes nothing and logs nothing (1.605034ms)
|
||||
✔ vikunja:19/305 with an exists check, the setter refuses a module no tree file answers to, before anything is written (52.267349ms)
|
||||
✔ P5 optional usage kind and pollSeconds configure through plugins.set; default stays absent and retention bound is strict (94.963454ms)
|
||||
✔ P5 only human can enable/disable telemetry or change polling, including direct organization writes (142.850292ms)
|
||||
✔ P5 Console displays stack count per safe key separately from optional proxy account numbers (0.865798ms)
|
||||
✔ P5 Console escapes hostile labels and labels unavailable telemetry without presenting a fresh zero (3.686422ms)
|
||||
ℹ tests 30
|
||||
ℹ suites 0
|
||||
ℹ pass 30
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1490.937181
|
||||
@@ -0,0 +1,30 @@
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["75a1bce4e569"]}
|
||||
model-proxy: {"action":"proxy.reconcile","addedKeyIds":[],"removedKeyIds":[]}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["75a1bce4e569"]}
|
||||
model-proxy: {"call":"PUT /v8/management/config/access/api-keys","status":200,"keyIds":["75a1bce4e569","9e2b7988546b"]}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["75a1bce4e569","9e2b7988546b"]}
|
||||
model-proxy: {"action":"proxy.key.issued","keyIds":["9e2b7988546b"],"instance":"demo/coder"}
|
||||
model-proxy: {"call":"GET /v1/models","status":200,"keyIds":["9e2b7988546b"]}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
✖ P5 real runtime binds stack usage to issued key, daily stops at stack count and human-only telemetry settings pass broker contract (212.342125ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 343.620467
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/p5-runtime.test.mjs:13:1
|
||||
✖ P5 real runtime binds stack usage to issued key, daily stops at stack count and human-only telemetry settings pass broker contract (212.342125ms)
|
||||
Error: invalid-launch-process
|
||||
at Object.bindLaunch (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/src/runtime.mjs:641:15)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-runtime.test.mjs:41:16)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
code: 'invalid-launch-process'
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["44299c50ade8"]}
|
||||
model-proxy: {"action":"proxy.reconcile","addedKeyIds":[],"removedKeyIds":[]}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["44299c50ade8"]}
|
||||
model-proxy: {"call":"PUT /v8/management/config/access/api-keys","status":200,"keyIds":["44299c50ade8","9f64355841b6"]}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["44299c50ade8","9f64355841b6"]}
|
||||
model-proxy: {"action":"proxy.key.issued","keyIds":["9f64355841b6"],"instance":"demo/coder"}
|
||||
model-proxy: {"call":"GET /v1/models","status":200,"keyIds":["9f64355841b6"]}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
✖ P5 real runtime binds stack usage to issued key, daily stops at stack count and human-only telemetry settings pass broker contract (218.643013ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 0
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 343.099863
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/p5-runtime.test.mjs:14:1
|
||||
✖ P5 real runtime binds stack usage to issued key, daily stops at stack count and human-only telemetry settings pass broker contract (218.643013ms)
|
||||
Error: unauthenticated
|
||||
at fail (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/src/broker.mjs:230:9)
|
||||
at #session (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/src/broker.mjs:657:39)
|
||||
at Broker.request (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/src/broker.mjs:4817:28)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-runtime.test.mjs:43:13)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
code: 'unauthenticated'
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["deae56d6265f"]}
|
||||
model-proxy: {"action":"proxy.reconcile","addedKeyIds":[],"removedKeyIds":[]}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["deae56d6265f"]}
|
||||
model-proxy: {"call":"PUT /v8/management/config/access/api-keys","status":200,"keyIds":["deae56d6265f","f39c9ad3cf05"]}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["deae56d6265f","f39c9ad3cf05"]}
|
||||
model-proxy: {"action":"proxy.key.issued","keyIds":["f39c9ad3cf05"],"instance":"demo/coder"}
|
||||
model-proxy: {"call":"GET /v1/models","status":200,"keyIds":["f39c9ad3cf05"]}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mustStop","subject":{"instance":"coder","provider":null,"model":null,"account":null,"run":"p5-run","modelKeyId":"f39c9ad3cf05"},"path":["tokens","keys","f39c9ad3cf05"],"limit":2,"count":2,"unknownTurns":0}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mayLaunch","subject":{"instance":"coder","provider":"fixture","model":"fake","account":null,"modelKeyId":"f39c9ad3cf05"},"path":["tokens","keys","f39c9ad3cf05"],"limit":2,"count":2,"unknownTurns":0}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
✔ P5 real runtime binds stack usage to issued key, daily stops at stack count and human-only telemetry settings pass broker contract (304.08638ms)
|
||||
ℹ tests 1
|
||||
ℹ suites 0
|
||||
ℹ pass 1
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 420.753441
|
||||
@@ -0,0 +1,40 @@
|
||||
✔ P5 usage plugin off by default, default poll is 15 seconds and configured polls skip early ticks (86.257274ms)
|
||||
✔ P5 safe telemetry stores failures per key and proxy-labelled accounts; no client/upstream value enters store/log/view or quota records (54.618111ms)
|
||||
✔ P5 unknown msk key goes only to value-free reconcile log and other businesses stay isolated (44.583676ms)
|
||||
✔ P5 queue failure is safe, does not enforce and does not retry before poll deadline (46.4743ms)
|
||||
✔ P5 retiring key keeps attribution and telemetry rows remain append-only across reader restart (56.121284ms)
|
||||
✔ P5 malformed queue batch is atomic: no valid prefix, body or credential can reach store/log/view (47.108755ms)
|
||||
✔ P5 concurrent ticks issue one bounded queue read and a closed collector never polls again (49.990509ms)
|
||||
✔ REQ-LIMIT-4 loader source records new turn kinds, excludes history and retries exactly once (56.900609ms)
|
||||
✔ REQ-LIMIT-4 cut: unknown is durable and logged next to every total (51.730832ms)
|
||||
✔ REQ-LIMIT-4 disabled: unknown is durable and logged next to every total (50.614029ms)
|
||||
✔ REQ-LIMIT-4 missing-begin: unknown is durable and logged next to every total (44.230231ms)
|
||||
✔ REQ-LIMIT-4 no-new-usage: unknown is durable and logged next to every total (48.44147ms)
|
||||
✔ REQ-LIMIT-4 rewrite: unknown is durable and logged next to every total (45.801767ms)
|
||||
✔ REQ-LIMIT-4 unfinished turn remains visibly unknown after accounting restarts (39.52636ms)
|
||||
✔ usage records are append-only (37.948303ms)
|
||||
✔ REQ-LIMIT-4 parse failure logs its safe code, never transcript content (47.7119ms)
|
||||
✔ REQ-LIMIT-4 resumed run baselines history and exact totals do not overflow (55.743022ms)
|
||||
✔ REQ-PLUG-1 core has no transcript import and disabled sources do not read any transcript (57.173303ms)
|
||||
✔ REQ-LIMIT-4 a resumed thread bills only new assistant messages to its next run (41.62154ms)
|
||||
✔ REQ-LIMIT-4 every enabled source is called; failure is unknown and a partial total stays labelled (46.188396ms)
|
||||
✔ REQ-LIMIT-4 a turn whose reported sum exceeds safe precision is unknown, not rounded (46.675381ms)
|
||||
✔ row 65 a run bound without a transcript directory records no-transcript (43.283736ms)
|
||||
✔ P5 immutable stack key attribution survives rotation and restart without key values (46.409665ms)
|
||||
✔ P5 malformed key metadata is dropped rather than stored or exposed as a key value (45.477235ms)
|
||||
✔ P5 queue read uses actual bounded fixed management GET and immediately drops client and upstream values (14.43995ms)
|
||||
✔ P5 bad envelope refuses safely with no retry (2.606864ms)
|
||||
✔ P5 over count refuses safely with no retry (1.613165ms)
|
||||
✔ P5 missing key refuses safely with no retry (1.32277ms)
|
||||
✔ P5 bad counts refuses safely with no retry (2.00608ms)
|
||||
✔ P5 redirect refuses safely with no retry (1.518136ms)
|
||||
✔ P5 refusal refuses safely with no retry (1.062337ms)
|
||||
✔ P5 malformed event after a valid event rejects the entire queue before any credential can escape (1.122725ms)
|
||||
ℹ tests 32
|
||||
ℹ suites 0
|
||||
ℹ pass 32
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1490.423611
|
||||
@@ -0,0 +1,99 @@
|
||||
✔ P5 usage plugin off by default, default poll is 15 seconds and configured polls skip early ticks (60.34137ms)
|
||||
✖ P5 safe telemetry stores failures per key and proxy-labelled accounts; no client/upstream value enters store/log/view or quota records (43.55479ms)
|
||||
✖ P5 unknown msk key goes only to value-free reconcile log and other businesses stay isolated (42.788302ms)
|
||||
✔ P5 queue failure is safe, does not enforce and does not retry before poll deadline (43.315969ms)
|
||||
✖ P5 retiring key keeps attribution and telemetry rows remain append-only across reader restart (40.209703ms)
|
||||
✔ P5 malformed queue batch is atomic: no valid prefix, body or credential can reach store/log/view (38.596309ms)
|
||||
✔ P5 concurrent ticks issue one bounded queue read and a closed collector never polls again (45.908134ms)
|
||||
✖ P5 queue read uses actual bounded fixed management GET and immediately drops client and upstream values (16.729146ms)
|
||||
✔ P5 bad envelope refuses safely with no retry (3.674119ms)
|
||||
✔ P5 over count refuses safely with no retry (1.818219ms)
|
||||
✔ P5 missing key refuses safely with no retry (1.550156ms)
|
||||
✔ P5 bad counts refuses safely with no retry (2.537033ms)
|
||||
✔ P5 redirect refuses safely with no retry (1.858685ms)
|
||||
✔ P5 refusal refuses safely with no retry (1.153412ms)
|
||||
✔ P5 malformed event after a valid event rejects the entire queue before any credential can escape (1.135306ms)
|
||||
ℹ tests 15
|
||||
ℹ suites 0
|
||||
ℹ pass 11
|
||||
ℹ fail 4
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 487.776777
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/proxy-usage.test.mjs:36:1
|
||||
✖ P5 safe telemetry stores failures per key and proxy-labelled accounts; no client/upstream value enters store/log/view or quota records (43.55479ms)
|
||||
TypeError: Cannot read properties of undefined (reading 'keyId')
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/proxy-usage.test.mjs:38:87)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
|
||||
test at packages/bus/tests/proxy-usage.test.mjs:47:1
|
||||
✖ P5 unknown msk key goes only to value-free reconcile log and other businesses stay isolated (42.788302ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
+ undefined
|
||||
- {
|
||||
- action: 'proxy.usage.reconcile',
|
||||
- code: 'proxy-usage-unknown-key',
|
||||
- keyId: 'f76403e5ce2e'
|
||||
- }
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/proxy-usage.test.mjs:49:9)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: undefined,
|
||||
expected: { action: 'proxy.usage.reconcile', keyId: 'f76403e5ce2e', code: 'proxy-usage-unknown-key' },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/bus/tests/proxy-usage.test.mjs:58:1
|
||||
✖ P5 retiring key keeps attribution and telemetry rows remain append-only across reader restart (40.209703ms)
|
||||
AssertionError [ERR_ASSERTION]: Missing expected exception.
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/proxy-usage.test.mjs:63:9)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: undefined,
|
||||
expected: /append-only/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at packages/model-proxy/tests/usage-client.test.mjs:21:1
|
||||
✖ P5 queue read uses actual bounded fixed management GET and immediately drops client and upstream values (16.729146ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
[
|
||||
{
|
||||
+ accountId: 'made-up-upstream-canary',
|
||||
- accountId: '51dfa8a6722b',
|
||||
cacheRead: 4,
|
||||
cacheWrite: 3,
|
||||
failed: true,
|
||||
input: 7,
|
||||
keyId: 'd1e3e19ac482',
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/model-proxy/tests/usage-client.test.mjs:24:10)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: [ { keyId: 'd1e3e19ac482', accountId: 'made-up-upstream-canary', managed: true, failed: true, statusCode: 503, input: 7, output: 2, cacheWrite: 3, cacheRead: 4 } ],
|
||||
expected: [ { keyId: 'd1e3e19ac482', accountId: '51dfa8a6722b', managed: true, failed: true, statusCode: 503, input: 7, output: 2, cacheWrite: 3, cacheRead: 4 } ],
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
✔ P5 usage plugin off by default, default poll is 15 seconds and configured polls skip early ticks (63.115978ms)
|
||||
✔ P5 safe telemetry stores failures per key and proxy-labelled accounts; no client/upstream value enters store/log/view or quota records (53.184947ms)
|
||||
✔ P5 unknown msk key goes only to value-free reconcile log and other businesses stay isolated (43.353706ms)
|
||||
✔ P5 queue failure is safe, does not enforce and does not retry before poll deadline (42.937785ms)
|
||||
✔ P5 retiring key keeps attribution and telemetry rows remain append-only across reader restart (48.231864ms)
|
||||
✔ P5 malformed queue batch is atomic: no valid prefix, body or credential can reach store/log/view (42.352423ms)
|
||||
✔ P5 concurrent ticks issue one bounded queue read and a closed collector never polls again (43.470712ms)
|
||||
✔ P5 queue read uses actual bounded fixed management GET and immediately drops client and upstream values (15.069336ms)
|
||||
✔ P5 bad envelope refuses safely with no retry (2.896886ms)
|
||||
✔ P5 over count refuses safely with no retry (1.591065ms)
|
||||
✔ P5 missing key refuses safely with no retry (1.351768ms)
|
||||
✔ P5 bad counts refuses safely with no retry (2.127704ms)
|
||||
✔ P5 redirect refuses safely with no retry (1.349646ms)
|
||||
✔ P5 refusal refuses safely with no retry (1.162024ms)
|
||||
✔ P5 malformed event after a valid event rejects the entire queue before any credential can escape (1.135262ms)
|
||||
ℹ tests 15
|
||||
ℹ suites 0
|
||||
ℹ pass 15
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 508.770711
|
||||
@@ -0,0 +1,243 @@
|
||||
serial nice19; private HOME/XDG_CONFIG_HOME/TMPDIR/MOSAIC_CONFIG; unchanged whole-file budgets
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mayLaunch","subject":{"instance":"coder","provider":"anthropic","model":"opus","account":"jason-max"},"path":["tokens","daily","jason-max"],"limit":0,"count":0,"unknownTurns":0}
|
||||
usage: {"event":"usage-unknown","business":"demo","run":"run1","instance":"coder","turn":"bc8872d6-c10d-4cbc-963c-dd87cf9163e5","source":"@none","code":"baseline-unknown"}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mustStop","subject":{"instance":"coder","provider":"anthropic","model":"opus","account":"jason-max","run":"run1"},"path":["tokens","daily","jason-max"],"limit":0,"count":0,"unknownTurns":1}
|
||||
usage: {"event":"usage-unknown","business":"demo","run":"run1","instance":"coder","turn":"3e17a52f-1444-4d91-a204-87e39766f9c6","source":"@none","code":"baseline-unknown"}
|
||||
✔ REQ-LIMIT-2 runtime: limits counts the daily quota, and mayLaunch refuses only the account at it (170.726529ms)
|
||||
✔ REQ-LIMIT-4 runtime: a run bound with the account writes it on its usage records and stops at the quota (145.594621ms)
|
||||
✔ REQ-LIMIT-4 runtime: a run bound without an account records null and the daily quota never stops it (126.673361ms)
|
||||
✔ REQ-LIMIT-4 bindLaunch keeps the account off session.launched, refuses one that is not an identifier, and takes null as none (67.580463ms)
|
||||
✔ REQ-LIMIT-3 limitLeaves finds every limit object and skips the agent numbers (1.298781ms)
|
||||
✔ REQ-LIMIT-3 limitLeaves takes token limits at schema depth only, whatever their names (0.222463ms)
|
||||
✔ REQ-LIMIT-3 with no check switched on a launch is allowed, a turn never stops, and every limit is not enforced (47.459097ms)
|
||||
✔ REQ-LIMIT-3 a fixture check that refuses refuses the launch and stops the turn, logged with the limit and the count (46.035967ms)
|
||||
✔ REQ-LIMIT-3 a report that omits a limit shows it not enforced; a counted entry and a reason come through (45.718506ms)
|
||||
✔ REQ-LIMIT-4 each check gets the business, a copy of the limits, the subject, the records and the time (57.755296ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a throw refuses, stops and fails the report, naming the check and the code (45.052811ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a malformed answer, a promise, a rejected promise, a non-boolean or a bad hit is malformed-answer (51.313528ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a check switched on but not loaded refuses, stops and fails every limit as not-loaded (46.094531ms)
|
||||
✔ REQ-LIMIT-4 state(), never-loaded case: before any load the report shows not enforced, or not-loaded for a switched-on check (48.189649ms)
|
||||
✔ REQ-LIMIT-4 state(), first-load-refused case: a check refused on its first load is not-loaded in mayLaunch, mustStop and report (44.413841ms)
|
||||
✔ REQ-LIMIT-4 fail closed: an unreadable organization file refuses and stops with check null; the report throws (46.465199ms)
|
||||
✔ REQ-LIMIT-4 fail closed: unreadable records refuse and stop with check null and fail the report (0.636118ms)
|
||||
✔ REQ-LIMIT-3 the shipped token-limit, through the real loader, counts known records only since the limit was set (87.250164ms)
|
||||
✔ REQ-LIMIT-3 a token limit for a provider named limit is counted and refuses, beside an agent limit of the same name (52.454059ms)
|
||||
✔ REQ-LIMIT-3 core reaches limit checks only through the plug-in loader (2.054757ms)
|
||||
✔ P5 missing, ambiguous or invalid model key lookup fails closed without leaking a lookup error (42.170203ms)
|
||||
✔ P5 trusted lookup uses the retiring run key rather than the agent current key (41.545306ms)
|
||||
✔ P5 actual model metadata lookup rejects missing/ambiguous owners and never cross-attributes a retiring run (0.418717ms)
|
||||
✖ REQ-LIMIT-4 a role run at its limit stops at the end of its turn: RESULT and read land first, the claim is revoked by limit-check (106.432474ms)
|
||||
✔ REQ-LIMIT-4 the stop also lands on state; a run with no stop ends without a limit (170.782587ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a mustStop throw or a malformed answer stops the run, naming the bus and the code (437.666292ms)
|
||||
✔ REQ-LIMIT-4 a thread run at its limit is released with the reason, and its end record names the limit (120.745836ms)
|
||||
✔ REQ-LIMIT-4 a broker with no limit checks configured never stops a run (80.230732ms)
|
||||
limits: {"event":"limit-reached","business":"demo","check":"token-limit","export":"mayLaunch","subject":{"instance":"coder","provider":"zai","model":"glm-5.3-flash","account":null},"path":["tokens","instances","coder"],"limit":0,"count":0,"unknownTurns":0}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
usage: {"event":"usage-unknown","business":"demo","run":"run1","instance":"coder","turn":"3646df55-73df-46ac-a828-41d4c0adef5c","source":"@none","code":"baseline-unknown"}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"token-limit","export":"mustStop","subject":{"instance":"coder","provider":"zai","model":"glm-5.3-flash","account":null,"run":"run1"},"path":["tokens","instances","coder"],"limit":0,"count":0,"unknownTurns":1}
|
||||
usage: {"event":"usage-unknown","business":"demo","run":"run1","instance":"coder","turn":"ae4d4f3a-9306-4a9d-88c5-234c2f2bfcaf","source":"@none","code":"baseline-unknown"}
|
||||
✔ REQ-LIMIT-3 REQ-LIMIT-4 runtime: limits carries the token count, mayLaunch refuses at the limit, a reset moves since (243.095091ms)
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
✔ REQ-LIMIT-3 runtime: with no limit check switched on, the limit shows not enforced and every launch is allowed (90.928952ms)
|
||||
✔ REQ-LIMIT-4 runtime: the broker asks the shipped token-limit after a turn, and the run at its limit stops on its next receive (143.039435ms)
|
||||
✔ REQ-LIMIT-4 runtime: with no usage source a turn is unknown, counts zero and stops nothing under a limit of 1 (136.591564ms)
|
||||
✔ REQ-LIMIT-3 runtime: switching a limit check on with plugins.set loads it without a launch or a turn (171.913947ms)
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["ddaa88bc74e9"]}
|
||||
model-proxy: {"action":"proxy.reconcile","addedKeyIds":[],"removedKeyIds":[]}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["ddaa88bc74e9"]}
|
||||
model-proxy: {"call":"PUT /v8/management/config/access/api-keys","status":200,"keyIds":["ddaa88bc74e9","fd2b06e41cec"]}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["ddaa88bc74e9","fd2b06e41cec"]}
|
||||
model-proxy: {"action":"proxy.key.issued","keyIds":["fd2b06e41cec"],"instance":"demo/coder"}
|
||||
model-proxy: {"call":"GET /v1/models","status":200,"keyIds":["fd2b06e41cec"]}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mustStop","subject":{"instance":"coder","provider":null,"model":null,"account":null,"run":"p5-run","modelKeyId":"fd2b06e41cec"},"path":["tokens","keys","fd2b06e41cec"],"limit":2,"count":2,"unknownTurns":0}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mayLaunch","subject":{"instance":"coder","provider":"fixture","model":"fake","account":null,"modelKeyId":"fd2b06e41cec"},"path":["tokens","keys","fd2b06e41cec"],"limit":2,"count":2,"unknownTurns":0}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
✔ P5 real runtime binds stack usage to issued key, daily stops at stack count and human-only telemetry settings pass broker contract (313.95876ms)
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
✔ plugins and plugins.set refuse every non-human session and a forged actor, and pass only the patch with the verified actor (100.42834ms)
|
||||
✔ runtime: the switch changes the organization file, the receipt carries the actor, and a bad shape, an unknown module and a stale revision are refused with nothing written (261.328835ms)
|
||||
✔ vikunja:19/309 through the broker, a patch switches the kinds it names and keeps the rest; null removes one kind and is trailed (199.005826ms)
|
||||
✔ P5 usage plugin off by default, default poll is 15 seconds and configured polls skip early ticks (59.508865ms)
|
||||
✔ P5 safe telemetry stores failures per key and proxy-labelled accounts; no client/upstream value enters store/log/view or quota records (54.132395ms)
|
||||
✔ P5 unknown msk key goes only to value-free reconcile log and other businesses stay isolated (42.918239ms)
|
||||
✔ P5 queue failure is safe, does not enforce and does not retry before poll deadline (47.414676ms)
|
||||
✔ P5 retiring key keeps attribution and telemetry rows remain append-only across reader restart (49.580277ms)
|
||||
✔ P5 malformed queue batch is atomic: no valid prefix, body or credential can reach store/log/view (42.767702ms)
|
||||
✔ P5 concurrent ticks issue one bounded queue read and a closed collector never polls again (44.597112ms)
|
||||
✔ REQ-LIMIT-4 usage protocol binds run identity, requires a delivered turn and isolates businesses (115.479121ms)
|
||||
✔ REQ-PLUG-1 runtime reaches transcript only through loader, over the real bus socket (137.456433ms)
|
||||
✔ REQ-LIMIT-4 loader source records new turn kinds, excludes history and retries exactly once (52.575663ms)
|
||||
✔ REQ-LIMIT-4 cut: unknown is durable and logged next to every total (47.838399ms)
|
||||
✔ REQ-LIMIT-4 disabled: unknown is durable and logged next to every total (46.771667ms)
|
||||
✔ REQ-LIMIT-4 missing-begin: unknown is durable and logged next to every total (40.568247ms)
|
||||
✔ REQ-LIMIT-4 no-new-usage: unknown is durable and logged next to every total (45.022848ms)
|
||||
✔ REQ-LIMIT-4 rewrite: unknown is durable and logged next to every total (44.520995ms)
|
||||
✔ REQ-LIMIT-4 unfinished turn remains visibly unknown after accounting restarts (38.477112ms)
|
||||
✔ usage records are append-only (38.207707ms)
|
||||
✔ REQ-LIMIT-4 parse failure logs its safe code, never transcript content (49.361853ms)
|
||||
✔ REQ-LIMIT-4 resumed run baselines history and exact totals do not overflow (59.674051ms)
|
||||
✔ REQ-PLUG-1 core has no transcript import and disabled sources do not read any transcript (52.284427ms)
|
||||
✔ REQ-LIMIT-4 a resumed thread bills only new assistant messages to its next run (54.284346ms)
|
||||
✔ REQ-LIMIT-4 every enabled source is called; failure is unknown and a partial total stays labelled (54.236183ms)
|
||||
✔ REQ-LIMIT-4 a turn whose reported sum exceeds safe precision is unknown, not rounded (50.417947ms)
|
||||
✔ row 65 a run bound without a transcript directory records no-transcript (49.190606ms)
|
||||
✔ P5 immutable stack key attribution survives rotation and restart without key values (45.910581ms)
|
||||
✔ P5 malformed key metadata is dropped rather than stored or exposed as a key value (45.051417ms)
|
||||
✔ REQ-PLUG-1 schema: plugins is optional, names known kinds and checked module names (9.756957ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the setter writes plugins through the organization writer and logs old and new names (139.461766ms)
|
||||
✔ vikunja:19/309 a patch changes only the kinds it names; null removes one kind, explicitly and in the trail (198.116707ms)
|
||||
✔ vikunja:19/309 an unknown kind (set or removed), a bad module, an empty patch and null on the wrong shape are refused, nothing written (1.940571ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the writer checks the bytes it writes: a Date in plugins is refused there too (23.77339ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 a refused setter write throws a code, changes nothing and logs nothing (1.651382ms)
|
||||
✔ vikunja:19/305 with an exists check, the setter refuses a module no tree file answers to, before anything is written (56.64271ms)
|
||||
✔ P5 optional usage kind and pollSeconds configure through plugins.set; default stays absent and retention bound is strict (100.452598ms)
|
||||
✔ P5 only human can enable/disable telemetry or change polling, including direct organization writes (148.009247ms)
|
||||
✔ REQ-LIMIT-3 schema: each subject kind, limit 0 and no ceiling are accepted; bad limits, times, keys and undeclared instances refuse (12.986058ms)
|
||||
✔ REQ-LIMIT-3 the writer stamps since: a new limit gets now, a changed one keeps its time, a different time is refused (248.032277ms)
|
||||
✔ REQ-LIMIT-3 only tokens.* at schema depth holds token limits: agent limits named `limit` save as sent, and a token limit named `limit` is stamped and reset (276.275719ms)
|
||||
✔ REQ-LIMIT-3 a reset moves since to now, is logged with its actor, and refuses a path that is not a limit (149.313217ms)
|
||||
✔ REQ-LIMIT-2 schema: launch.account names a credential set; a daily quota needs a reset and an IANA zone and names the account (22.104886ms)
|
||||
✔ REQ-LIMIT-2 the writer stamps a daily quota's since, keeps its reset and zone, and a reset moves since (155.859496ms)
|
||||
✔ P5 per-model-key quotas are unset by default, accept digit-leading IDs and only the human changes or resets them (232.766603ms)
|
||||
✔ probeKey observes 200 with one agent-authenticated GET /v1/models (13.606016ms)
|
||||
✔ probeKey observes 401 with one agent-authenticated GET /v1/models (2.349516ms)
|
||||
✔ probeKey observes 503 with one agent-authenticated GET /v1/models (1.394451ms)
|
||||
✔ proxy-down: agent-key probe connection failure is sanitized (1.448631ms)
|
||||
✔ proxy-down: silent listener cannot extend probe request deadline (50.92774ms)
|
||||
✔ agent-key probe returns redirect status without following Location or exposing key (2.519341ms)
|
||||
✔ proxy-client-invalid: https://127.0.0.1:18318 (0.954469ms)
|
||||
✔ proxy-client-invalid: http://example.com:18318 (0.688091ms)
|
||||
✔ proxy-client-invalid: http://localhost:18318 (0.089486ms)
|
||||
✔ proxy-client-invalid: http://127.0.0.1:8317 (0.072442ms)
|
||||
✔ proxy-client-invalid: http://user:[email protected]:18318 (0.075664ms)
|
||||
✔ proxy-client-invalid: http://127.0.0.1:18318/path (0.064187ms)
|
||||
✔ client GET/PUT v8 only, Authorization header, receipt IDs without values or bodies (15.756687ms)
|
||||
✔ proxy-client-refused (3.167201ms)
|
||||
✔ proxy-client-response (1.333201ms)
|
||||
✔ proxy-client-redirect (1.083098ms)
|
||||
✔ proxy-client-down: transport errors redact details (0.993207ms)
|
||||
✔ proxy-client-invalid: PUT rejects object key records and empty strings locally (0.155978ms)
|
||||
✔ proxy-management-key-invalid: missing, symlink and public key file refuse without values (1.086163ms)
|
||||
✔ bus management-key loader supplies a private fixture key without exposing it on the client (0.529214ms)
|
||||
✔ proxy-client-response: truncated response remains a redacted named refusal (12.081487ms)
|
||||
✔ management client ignores ambient fetch dispatchers (1.152012ms)
|
||||
✔ proxy-key-invalid: Latin-1 leaves complete config/data inventories unchanged (3.391538ms)
|
||||
✔ proxy-key-invalid: leading space leaves complete config/data inventories unchanged (1.062708ms)
|
||||
✔ proxy-key-invalid: trailing space leaves complete config/data inventories unchanged (1.046332ms)
|
||||
✔ proxy-key-invalid: internal space leaves complete config/data inventories unchanged (1.087954ms)
|
||||
✔ printable non-space ASCII control initializes and authenticates with unchanged existing files (16.664061ms)
|
||||
✔ OAuth management calls keep URL and state out of receipts (16.723462ms)
|
||||
✔ upstream key goes only in request body and upstream refusal body is discarded (3.387523ms)
|
||||
✔ redirected management calls are not followed or retried (1.835042ms)
|
||||
✔ P5 queue read uses actual bounded fixed management GET and immediately drops client and upstream values (14.543908ms)
|
||||
✔ P5 bad envelope refuses safely with no retry (2.805976ms)
|
||||
✔ P5 over count refuses safely with no retry (1.641432ms)
|
||||
✔ P5 missing key refuses safely with no retry (1.977544ms)
|
||||
✔ P5 bad counts refuses safely with no retry (1.458ms)
|
||||
✔ P5 redirect refuses safely with no retry (1.387336ms)
|
||||
✔ P5 refusal refuses safely with no retry (1.028864ms)
|
||||
✔ P5 malformed event after a valid event rejects the entire queue before any credential can escape (1.11627ms)
|
||||
✔ REQ-LIMIT-2 daily-quota exports interface version 2 with mayLaunch, mustStop and report (1.248222ms)
|
||||
✔ REQ-LIMIT-2 the count sums every kind of the account's known records since the later of the day start and since (11.695173ms)
|
||||
✔ REQ-LIMIT-2 a launch with no account (pi) is covered by no daily quota (0.286778ms)
|
||||
✔ REQ-LIMIT-4 an unknown turn adds nothing and is counted apart (0.491571ms)
|
||||
✔ REQ-LIMIT-2 the day turns at the reset in its zone, not in UTC, and before it the day is yesterday's (0.574704ms)
|
||||
✔ REQ-LIMIT-2 the spring DST change makes the day after a 00:00 reset 23 hours long (0.368738ms)
|
||||
✔ REQ-LIMIT-2 the fall DST change makes the day after a 00:00 reset 25 hours long (0.297179ms)
|
||||
✔ REQ-LIMIT-2 a reset the clocks skip starts the day at the first instant after the gap (0.789063ms)
|
||||
✔ REQ-LIMIT-2 a reset the clocks repeat starts one day, at the first one (0.436754ms)
|
||||
✔ REQ-LIMIT-2 a launch is refused at the quota, a turn that reaches it stops, and the next day allows again (1.07467ms)
|
||||
✔ REQ-LIMIT-2 counts past the safe integer range come back as digit strings (0.372713ms)
|
||||
✔ REQ-LIMIT-4 bad leaves, records or times throw a code, and the check reads nothing but its arguments (2.387209ms)
|
||||
✔ REQ-LIMIT-2 no daily quotas: every launch is allowed and the report is empty (0.190068ms)
|
||||
✔ P5 daily quota for a model key ID matches stack key records and resets the next day (0.797912ms)
|
||||
✔ REQ-PLUG-1 REQ-LIMIT-4 the registry: usage-source at interface version 1, limit-check at 2 (row 125), each a list (1.067108ms)
|
||||
✔ REQ-PLUG-1 checkPlugins accepts one key per kind, each a list of names, empty included (0.242701ms)
|
||||
✔ REQ-PLUG-1 checkPlugins refuses bad shapes, unknown kinds, bad names and duplicates (0.499586ms)
|
||||
✔ REQ-PLUG-1 a kind that switches on one module takes one name, not a list (0.148124ms)
|
||||
✔ REQ-PLUG-1 checkPlugins reports through the caller's fail callback (0.132027ms)
|
||||
✔ P5 usage telemetry is optional, single module, separate from enforcing sources (0.141236ms)
|
||||
✔ REQ-PLUG-1 fixture modules of each kind switch on from a test organization file, no core file changed (9.357471ms)
|
||||
✔ REQ-PLUG-1 a name not matching ^[a-z][a-z0-9-]*$ refuses and keeps the old setting (3.869634ms)
|
||||
✔ REQ-PLUG-1 a missing module directory or index.mjs refuses and keeps the old setting (2.937122ms)
|
||||
✔ REQ-PLUG-1 a symlinked module directory or index.mjs refuses and keeps the old setting (2.673271ms)
|
||||
✔ REQ-PLUG-1 a symlinked kind directory refuses and keeps the old setting (2.374164ms)
|
||||
✔ REQ-PLUG-1 a symlinked packages/plugins refuses (run with --preserve-symlinks so the path keeps it) (27.658454ms)
|
||||
✔ REQ-PLUG-1 index.mjs swapped for a symlink after the lstat checks refuses at the realpath check (2.627026ms)
|
||||
✔ REQ-PLUG-1 a path that can't be read refuses as unreadable, is logged and keeps the old setting (2.181959ms)
|
||||
✔ REQ-PLUG-1 a path that becomes unreadable after the lstat checks refuses at either realpath (2.491019ms)
|
||||
✔ REQ-PLUG-1 a module that fails to load refuses and keeps the old setting (2.663113ms)
|
||||
✔ REQ-PLUG-1 a missing export refuses and keeps the old setting (3.78261ms)
|
||||
✔ REQ-PLUG-1 a different interface version refuses and keeps the old setting (2.634605ms)
|
||||
✔ REQ-PLUG-1 REQ-LIMIT-3 a version 1 limit check refuses after the bump to 2, and the old setting stays (2.598243ms)
|
||||
✔ REQ-PLUG-1 a kind refused on its first load has nothing switched on, and the log names kind and name (1.844243ms)
|
||||
✔ REQ-PLUG-1 the setting's shape: unknown kinds refuse alone, a bad whole setting keeps everything (2.647337ms)
|
||||
✔ REQ-PLUG-1 loads run one at a time, so the last requested setting wins (102.801872ms)
|
||||
✔ REQ-PLUG-1 the loader needs a log callback (1.263318ms)
|
||||
✔ REQ-LIMIT-3 token-limit exports interface version 2 with mayLaunch, mustStop and report (1.188308ms)
|
||||
✔ REQ-LIMIT-3 each subject kind refuses at its limit and allows under it (1.33092ms)
|
||||
✔ REQ-LIMIT-3 a limit covers only its own subject's records and launches (0.355614ms)
|
||||
✔ REQ-LIMIT-4 only known records count; an unknown turn adds nothing and is counted apart (0.231653ms)
|
||||
✔ REQ-LIMIT-3 a reset moves since: records before it no longer count (0.148217ms)
|
||||
✔ REQ-LIMIT-3 limit 0 refuses with no records; the first limit hit in file order is named (0.136573ms)
|
||||
✔ REQ-LIMIT-3 a key limit is not enforced while every record's account is null (decision 150 Q1) (0.176874ms)
|
||||
✔ REQ-LIMIT-3 counts past the safe integer range come back as digit strings (0.124961ms)
|
||||
✔ REQ-LIMIT-4 bad records or times throw a code, and the check reads nothing but its arguments (0.607578ms)
|
||||
✔ REQ-LIMIT-3 no token limits: every launch is allowed and the report is empty (0.23856ms)
|
||||
✔ REQ-LIMIT-3 token-limit ignores tokens.daily, which the daily-quota check enforces (row 126) (0.114066ms)
|
||||
✔ P5 a model key ID limit counts stack records by key ID without an account (0.118256ms)
|
||||
✔ P5 Console displays stack count per safe key separately from optional proxy account numbers (0.841797ms)
|
||||
✔ P5 Console escapes hostile labels and labels unavailable telemetry without presenting a fresh zero (0.176474ms)
|
||||
✔ REQ-WEB-1 usage read keeps unknown counts and each token kind; no query or write is accepted (25.573147ms)
|
||||
✔ REQ-WEB-1 malformed usage is refused instead of shown as zero (4.896859ms)
|
||||
ℹ tests 170
|
||||
ℹ suites 0
|
||||
ℹ pass 169
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 9018.08934
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/limit-stop.test.mjs:51:1
|
||||
✖ REQ-LIMIT-4 a role run at its limit stops at the end of its turn: RESULT and read land first, the claim is revoked by limit-check (106.432474ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
... Skipped lines
|
||||
|
||||
[
|
||||
{
|
||||
business: 'demo',
|
||||
subject: {
|
||||
account: null,
|
||||
...
|
||||
provider: 'anthropic',
|
||||
+ run: 'run1'
|
||||
}
|
||||
},
|
||||
{
|
||||
business: 'demo',
|
||||
subject: {
|
||||
...
|
||||
provider: 'anthropic',
|
||||
+ run: 'run1'
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/limit-stop.test.mjs:61:10)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: [ { business: 'demo', subject: [Object] }, { business: 'demo', subject: [Object] } ],
|
||||
expected: [ { business: 'demo', subject: [Object] }, { business: 'demo', subject: [Object] } ],
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
serial nice19; private HOME/XDG_CONFIG_HOME/TMPDIR/MOSAIC_CONFIG; unchanged whole-file budgets
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mayLaunch","subject":{"instance":"coder","provider":"anthropic","model":"opus","account":"jason-max"},"path":["tokens","daily","jason-max"],"limit":0,"count":0,"unknownTurns":0}
|
||||
usage: {"event":"usage-unknown","business":"demo","run":"run1","instance":"coder","turn":"5bb2f720-5e85-4a68-a925-a3353c40a2f8","source":"@none","code":"baseline-unknown"}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mustStop","subject":{"instance":"coder","provider":"anthropic","model":"opus","account":"jason-max"},"path":["tokens","daily","jason-max"],"limit":0,"count":0,"unknownTurns":1}
|
||||
usage: {"event":"usage-unknown","business":"demo","run":"run1","instance":"coder","turn":"705b4abe-0076-4b91-a1cc-5086242adeed","source":"@none","code":"baseline-unknown"}
|
||||
✔ REQ-LIMIT-2 runtime: limits counts the daily quota, and mayLaunch refuses only the account at it (161.759642ms)
|
||||
✔ REQ-LIMIT-4 runtime: a run bound with the account writes it on its usage records and stops at the quota (143.832834ms)
|
||||
✔ REQ-LIMIT-4 runtime: a run bound without an account records null and the daily quota never stops it (121.34683ms)
|
||||
✔ REQ-LIMIT-4 bindLaunch keeps the account off session.launched, refuses one that is not an identifier, and takes null as none (69.700044ms)
|
||||
✔ REQ-LIMIT-3 limitLeaves finds every limit object and skips the agent numbers (1.251176ms)
|
||||
✔ REQ-LIMIT-3 limitLeaves takes token limits at schema depth only, whatever their names (0.204566ms)
|
||||
✔ REQ-LIMIT-3 with no check switched on a launch is allowed, a turn never stops, and every limit is not enforced (51.271224ms)
|
||||
✔ REQ-LIMIT-3 a fixture check that refuses refuses the launch and stops the turn, logged with the limit and the count (52.372536ms)
|
||||
✔ REQ-LIMIT-3 a report that omits a limit shows it not enforced; a counted entry and a reason come through (45.813258ms)
|
||||
✔ REQ-LIMIT-4 each check gets the business, a copy of the limits, the subject, the records and the time (54.966516ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a throw refuses, stops and fails the report, naming the check and the code (45.689186ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a malformed answer, a promise, a rejected promise, a non-boolean or a bad hit is malformed-answer (47.849713ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a check switched on but not loaded refuses, stops and fails every limit as not-loaded (48.476916ms)
|
||||
✔ REQ-LIMIT-4 state(), never-loaded case: before any load the report shows not enforced, or not-loaded for a switched-on check (50.630185ms)
|
||||
✔ REQ-LIMIT-4 state(), first-load-refused case: a check refused on its first load is not-loaded in mayLaunch, mustStop and report (43.636714ms)
|
||||
✔ REQ-LIMIT-4 fail closed: an unreadable organization file refuses and stops with check null; the report throws (43.52912ms)
|
||||
✔ REQ-LIMIT-4 fail closed: unreadable records refuse and stop with check null and fail the report (0.50935ms)
|
||||
✔ REQ-LIMIT-3 the shipped token-limit, through the real loader, counts known records only since the limit was set (85.225278ms)
|
||||
✔ REQ-LIMIT-3 a token limit for a provider named limit is counted and refuses, beside an agent limit of the same name (51.638301ms)
|
||||
✔ REQ-LIMIT-3 core reaches limit checks only through the plug-in loader (1.900971ms)
|
||||
✔ P5 missing, ambiguous or invalid model key lookup fails closed without leaking a lookup error (52.673427ms)
|
||||
✔ P5 trusted lookup uses the retiring run key rather than the agent current key (41.052561ms)
|
||||
✔ P5 actual model metadata lookup rejects missing/ambiguous owners and never cross-attributes a retiring run (0.486898ms)
|
||||
✔ REQ-LIMIT-4 a role run at its limit stops at the end of its turn: RESULT and read land first, the claim is revoked by limit-check (142.265785ms)
|
||||
✔ REQ-LIMIT-4 the stop also lands on state; a run with no stop ends without a limit (186.467373ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a mustStop throw or a malformed answer stops the run, naming the bus and the code (423.452103ms)
|
||||
✔ REQ-LIMIT-4 a thread run at its limit is released with the reason, and its end record names the limit (110.322117ms)
|
||||
✔ REQ-LIMIT-4 a broker with no limit checks configured never stops a run (77.036392ms)
|
||||
limits: {"event":"limit-reached","business":"demo","check":"token-limit","export":"mayLaunch","subject":{"instance":"coder","provider":"zai","model":"glm-5.3-flash","account":null},"path":["tokens","instances","coder"],"limit":0,"count":0,"unknownTurns":0}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
usage: {"event":"usage-unknown","business":"demo","run":"run1","instance":"coder","turn":"071301b4-8009-4918-9b07-39907d1d5082","source":"@none","code":"baseline-unknown"}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"token-limit","export":"mustStop","subject":{"instance":"coder","provider":"zai","model":"glm-5.3-flash","account":null},"path":["tokens","instances","coder"],"limit":0,"count":0,"unknownTurns":1}
|
||||
usage: {"event":"usage-unknown","business":"demo","run":"run1","instance":"coder","turn":"231aab8c-068f-4e5a-81e9-19b1cf7d34cc","source":"@none","code":"baseline-unknown"}
|
||||
✔ REQ-LIMIT-3 REQ-LIMIT-4 runtime: limits carries the token count, mayLaunch refuses at the limit, a reset moves since (248.63219ms)
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
✔ REQ-LIMIT-3 runtime: with no limit check switched on, the limit shows not enforced and every launch is allowed (87.393715ms)
|
||||
✔ REQ-LIMIT-4 runtime: the broker asks the shipped token-limit after a turn, and the run at its limit stops on its next receive (140.096907ms)
|
||||
✔ REQ-LIMIT-4 runtime: with no usage source a turn is unknown, counts zero and stops nothing under a limit of 1 (122.214342ms)
|
||||
✔ REQ-LIMIT-3 runtime: switching a limit check on with plugins.set loads it without a launch or a turn (161.718448ms)
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["2817f62132a8"]}
|
||||
model-proxy: {"action":"proxy.reconcile","addedKeyIds":[],"removedKeyIds":[]}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["2817f62132a8"]}
|
||||
model-proxy: {"call":"PUT /v8/management/config/access/api-keys","status":200,"keyIds":["2817f62132a8","e87aa1b93018"]}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["2817f62132a8","e87aa1b93018"]}
|
||||
model-proxy: {"action":"proxy.key.issued","keyIds":["e87aa1b93018"],"instance":"demo/coder"}
|
||||
model-proxy: {"call":"GET /v1/models","status":200,"keyIds":["e87aa1b93018"]}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mustStop","subject":{"instance":"coder","provider":null,"model":null,"account":null,"modelKeyId":"e87aa1b93018"},"path":["tokens","keys","e87aa1b93018"],"limit":2,"count":2,"unknownTurns":0}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mayLaunch","subject":{"instance":"coder","provider":"fixture","model":"fake","account":null,"modelKeyId":"e87aa1b93018"},"path":["tokens","keys","e87aa1b93018"],"limit":2,"count":2,"unknownTurns":0}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
✔ P5 real runtime binds stack usage to issued key, daily stops at stack count and human-only telemetry settings pass broker contract (311.047592ms)
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
✔ plugins and plugins.set refuse every non-human session and a forged actor, and pass only the patch with the verified actor (99.333676ms)
|
||||
✔ runtime: the switch changes the organization file, the receipt carries the actor, and a bad shape, an unknown module and a stale revision are refused with nothing written (257.002212ms)
|
||||
✔ vikunja:19/309 through the broker, a patch switches the kinds it names and keeps the rest; null removes one kind and is trailed (196.173099ms)
|
||||
✔ P5 usage plugin off by default, default poll is 15 seconds and configured polls skip early ticks (58.628561ms)
|
||||
✔ P5 safe telemetry stores failures per key and proxy-labelled accounts; no client/upstream value enters store/log/view or quota records (52.79243ms)
|
||||
✔ P5 unknown msk key goes only to value-free reconcile log and other businesses stay isolated (42.569864ms)
|
||||
✔ P5 queue failure is safe, does not enforce and does not retry before poll deadline (41.831504ms)
|
||||
✔ P5 retiring key keeps attribution and telemetry rows remain append-only across reader restart (47.808191ms)
|
||||
✔ P5 malformed queue batch is atomic: no valid prefix, body or credential can reach store/log/view (43.023649ms)
|
||||
✔ P5 concurrent ticks issue one bounded queue read and a closed collector never polls again (42.774113ms)
|
||||
✔ REQ-LIMIT-4 usage protocol binds run identity, requires a delivered turn and isolates businesses (111.658595ms)
|
||||
✔ REQ-PLUG-1 runtime reaches transcript only through loader, over the real bus socket (136.372459ms)
|
||||
✔ REQ-LIMIT-4 loader source records new turn kinds, excludes history and retries exactly once (52.523881ms)
|
||||
✔ REQ-LIMIT-4 cut: unknown is durable and logged next to every total (60.980995ms)
|
||||
✔ REQ-LIMIT-4 disabled: unknown is durable and logged next to every total (47.608728ms)
|
||||
✔ REQ-LIMIT-4 missing-begin: unknown is durable and logged next to every total (40.927657ms)
|
||||
✔ REQ-LIMIT-4 no-new-usage: unknown is durable and logged next to every total (55.771008ms)
|
||||
✔ REQ-LIMIT-4 rewrite: unknown is durable and logged next to every total (57.407378ms)
|
||||
✔ REQ-LIMIT-4 unfinished turn remains visibly unknown after accounting restarts (42.03284ms)
|
||||
✔ usage records are append-only (41.064096ms)
|
||||
✔ REQ-LIMIT-4 parse failure logs its safe code, never transcript content (46.863323ms)
|
||||
✔ REQ-LIMIT-4 resumed run baselines history and exact totals do not overflow (51.492502ms)
|
||||
✔ REQ-PLUG-1 core has no transcript import and disabled sources do not read any transcript (40.548781ms)
|
||||
✔ REQ-LIMIT-4 a resumed thread bills only new assistant messages to its next run (41.97363ms)
|
||||
✔ REQ-LIMIT-4 every enabled source is called; failure is unknown and a partial total stays labelled (50.186944ms)
|
||||
✔ REQ-LIMIT-4 a turn whose reported sum exceeds safe precision is unknown, not rounded (44.545546ms)
|
||||
✔ row 65 a run bound without a transcript directory records no-transcript (44.101897ms)
|
||||
✔ P5 immutable stack key attribution survives rotation and restart without key values (44.09141ms)
|
||||
✔ P5 malformed key metadata is dropped rather than stored or exposed as a key value (44.151576ms)
|
||||
✔ REQ-PLUG-1 schema: plugins is optional, names known kinds and checked module names (9.654239ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the setter writes plugins through the organization writer and logs old and new names (136.405265ms)
|
||||
✔ vikunja:19/309 a patch changes only the kinds it names; null removes one kind, explicitly and in the trail (164.709168ms)
|
||||
✔ vikunja:19/309 an unknown kind (set or removed), a bad module, an empty patch and null on the wrong shape are refused, nothing written (1.961195ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the writer checks the bytes it writes: a Date in plugins is refused there too (20.250129ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 a refused setter write throws a code, changes nothing and logs nothing (1.590323ms)
|
||||
✔ vikunja:19/305 with an exists check, the setter refuses a module no tree file answers to, before anything is written (50.378509ms)
|
||||
✔ P5 optional usage kind and pollSeconds configure through plugins.set; default stays absent and retention bound is strict (93.589584ms)
|
||||
✔ P5 only human can enable/disable telemetry or change polling, including direct organization writes (146.907219ms)
|
||||
✔ REQ-LIMIT-3 schema: each subject kind, limit 0 and no ceiling are accepted; bad limits, times, keys and undeclared instances refuse (14.755461ms)
|
||||
✔ REQ-LIMIT-3 the writer stamps since: a new limit gets now, a changed one keeps its time, a different time is refused (223.35974ms)
|
||||
✔ REQ-LIMIT-3 only tokens.* at schema depth holds token limits: agent limits named `limit` save as sent, and a token limit named `limit` is stamped and reset (262.018477ms)
|
||||
✔ REQ-LIMIT-3 a reset moves since to now, is logged with its actor, and refuses a path that is not a limit (136.45906ms)
|
||||
✔ REQ-LIMIT-2 schema: launch.account names a credential set; a daily quota needs a reset and an IANA zone and names the account (22.468222ms)
|
||||
✔ REQ-LIMIT-2 the writer stamps a daily quota's since, keeps its reset and zone, and a reset moves since (146.912888ms)
|
||||
✔ P5 per-model-key quotas are unset by default, accept digit-leading IDs and only the human changes or resets them (199.214764ms)
|
||||
✔ probeKey observes 200 with one agent-authenticated GET /v1/models (13.500079ms)
|
||||
✔ probeKey observes 401 with one agent-authenticated GET /v1/models (2.29275ms)
|
||||
✔ probeKey observes 503 with one agent-authenticated GET /v1/models (1.453939ms)
|
||||
✔ proxy-down: agent-key probe connection failure is sanitized (1.448596ms)
|
||||
✔ proxy-down: silent listener cannot extend probe request deadline (51.226767ms)
|
||||
✔ agent-key probe returns redirect status without following Location or exposing key (2.599627ms)
|
||||
✔ proxy-client-invalid: https://127.0.0.1:18318 (0.940367ms)
|
||||
✔ proxy-client-invalid: http://example.com:18318 (0.110721ms)
|
||||
✔ proxy-client-invalid: http://localhost:18318 (0.551474ms)
|
||||
✔ proxy-client-invalid: http://127.0.0.1:8317 (0.085358ms)
|
||||
✔ proxy-client-invalid: http://user:[email protected]:18318 (0.082245ms)
|
||||
✔ proxy-client-invalid: http://127.0.0.1:18318/path (0.071237ms)
|
||||
✔ client GET/PUT v8 only, Authorization header, receipt IDs without values or bodies (16.679264ms)
|
||||
✔ proxy-client-refused (2.60845ms)
|
||||
✔ proxy-client-response (1.279043ms)
|
||||
✔ proxy-client-redirect (1.146966ms)
|
||||
✔ proxy-client-down: transport errors redact details (0.949938ms)
|
||||
✔ proxy-client-invalid: PUT rejects object key records and empty strings locally (0.180359ms)
|
||||
✔ proxy-management-key-invalid: missing, symlink and public key file refuse without values (0.938153ms)
|
||||
✔ bus management-key loader supplies a private fixture key without exposing it on the client (0.489424ms)
|
||||
✔ proxy-client-response: truncated response remains a redacted named refusal (12.060482ms)
|
||||
✔ management client ignores ambient fetch dispatchers (1.377676ms)
|
||||
✔ proxy-key-invalid: Latin-1 leaves complete config/data inventories unchanged (3.526441ms)
|
||||
✔ proxy-key-invalid: leading space leaves complete config/data inventories unchanged (1.110569ms)
|
||||
✔ proxy-key-invalid: trailing space leaves complete config/data inventories unchanged (1.01067ms)
|
||||
✔ proxy-key-invalid: internal space leaves complete config/data inventories unchanged (1.13613ms)
|
||||
✔ printable non-space ASCII control initializes and authenticates with unchanged existing files (17.073708ms)
|
||||
✔ OAuth management calls keep URL and state out of receipts (16.393438ms)
|
||||
✔ upstream key goes only in request body and upstream refusal body is discarded (3.072175ms)
|
||||
✔ redirected management calls are not followed or retried (1.57426ms)
|
||||
✔ P5 queue read uses actual bounded fixed management GET and immediately drops client and upstream values (15.82294ms)
|
||||
✔ P5 bad envelope refuses safely with no retry (2.96929ms)
|
||||
✔ P5 over count refuses safely with no retry (1.741334ms)
|
||||
✔ P5 missing key refuses safely with no retry (1.466913ms)
|
||||
✔ P5 bad counts refuses safely with no retry (2.929775ms)
|
||||
✔ P5 redirect refuses safely with no retry (1.463954ms)
|
||||
✔ P5 refusal refuses safely with no retry (1.03957ms)
|
||||
✔ P5 malformed event after a valid event rejects the entire queue before any credential can escape (1.194237ms)
|
||||
✔ REQ-LIMIT-2 daily-quota exports interface version 2 with mayLaunch, mustStop and report (1.253421ms)
|
||||
✔ REQ-LIMIT-2 the count sums every kind of the account's known records since the later of the day start and since (12.848519ms)
|
||||
✔ REQ-LIMIT-2 a launch with no account (pi) is covered by no daily quota (0.34571ms)
|
||||
✔ REQ-LIMIT-4 an unknown turn adds nothing and is counted apart (0.530747ms)
|
||||
✔ REQ-LIMIT-2 the day turns at the reset in its zone, not in UTC, and before it the day is yesterday's (0.735447ms)
|
||||
✔ REQ-LIMIT-2 the spring DST change makes the day after a 00:00 reset 23 hours long (0.388703ms)
|
||||
✔ REQ-LIMIT-2 the fall DST change makes the day after a 00:00 reset 25 hours long (0.354873ms)
|
||||
✔ REQ-LIMIT-2 a reset the clocks skip starts the day at the first instant after the gap (0.967098ms)
|
||||
✔ REQ-LIMIT-2 a reset the clocks repeat starts one day, at the first one (0.478992ms)
|
||||
✔ REQ-LIMIT-2 a launch is refused at the quota, a turn that reaches it stops, and the next day allows again (1.167482ms)
|
||||
✔ REQ-LIMIT-2 counts past the safe integer range come back as digit strings (0.375179ms)
|
||||
✔ REQ-LIMIT-4 bad leaves, records or times throw a code, and the check reads nothing but its arguments (2.739059ms)
|
||||
✔ REQ-LIMIT-2 no daily quotas: every launch is allowed and the report is empty (0.22961ms)
|
||||
✔ P5 daily quota for a model key ID matches stack key records and resets the next day (0.935079ms)
|
||||
✔ REQ-PLUG-1 REQ-LIMIT-4 the registry: usage-source at interface version 1, limit-check at 2 (row 125), each a list (1.194208ms)
|
||||
✔ REQ-PLUG-1 checkPlugins accepts one key per kind, each a list of names, empty included (0.254856ms)
|
||||
✔ REQ-PLUG-1 checkPlugins refuses bad shapes, unknown kinds, bad names and duplicates (1.125412ms)
|
||||
✔ REQ-PLUG-1 a kind that switches on one module takes one name, not a list (0.161968ms)
|
||||
✔ REQ-PLUG-1 checkPlugins reports through the caller's fail callback (0.141125ms)
|
||||
✔ P5 usage telemetry is optional, single module, separate from enforcing sources (0.146226ms)
|
||||
✔ REQ-PLUG-1 fixture modules of each kind switch on from a test organization file, no core file changed (9.365221ms)
|
||||
✔ REQ-PLUG-1 a name not matching ^[a-z][a-z0-9-]*$ refuses and keeps the old setting (4.138219ms)
|
||||
✔ REQ-PLUG-1 a missing module directory or index.mjs refuses and keeps the old setting (3.181488ms)
|
||||
✔ REQ-PLUG-1 a symlinked module directory or index.mjs refuses and keeps the old setting (3.076206ms)
|
||||
✔ REQ-PLUG-1 a symlinked kind directory refuses and keeps the old setting (2.618445ms)
|
||||
✔ REQ-PLUG-1 a symlinked packages/plugins refuses (run with --preserve-symlinks so the path keeps it) (30.33829ms)
|
||||
✔ REQ-PLUG-1 index.mjs swapped for a symlink after the lstat checks refuses at the realpath check (2.849943ms)
|
||||
✔ REQ-PLUG-1 a path that can't be read refuses as unreadable, is logged and keeps the old setting (2.25734ms)
|
||||
✔ REQ-PLUG-1 a path that becomes unreadable after the lstat checks refuses at either realpath (2.597703ms)
|
||||
✔ REQ-PLUG-1 a module that fails to load refuses and keeps the old setting (2.743636ms)
|
||||
✔ REQ-PLUG-1 a missing export refuses and keeps the old setting (3.876351ms)
|
||||
✔ REQ-PLUG-1 a different interface version refuses and keeps the old setting (2.717178ms)
|
||||
✔ REQ-PLUG-1 REQ-LIMIT-3 a version 1 limit check refuses after the bump to 2, and the old setting stays (2.639476ms)
|
||||
✔ REQ-PLUG-1 a kind refused on its first load has nothing switched on, and the log names kind and name (1.884786ms)
|
||||
✔ REQ-PLUG-1 the setting's shape: unknown kinds refuse alone, a bad whole setting keeps everything (3.078835ms)
|
||||
✔ REQ-PLUG-1 loads run one at a time, so the last requested setting wins (102.865433ms)
|
||||
✔ REQ-PLUG-1 the loader needs a log callback (1.252523ms)
|
||||
✔ REQ-LIMIT-3 token-limit exports interface version 2 with mayLaunch, mustStop and report (1.15958ms)
|
||||
✔ REQ-LIMIT-3 each subject kind refuses at its limit and allows under it (1.269598ms)
|
||||
✔ REQ-LIMIT-3 a limit covers only its own subject's records and launches (0.319894ms)
|
||||
✔ REQ-LIMIT-4 only known records count; an unknown turn adds nothing and is counted apart (0.245595ms)
|
||||
✔ REQ-LIMIT-3 a reset moves since: records before it no longer count (0.147653ms)
|
||||
✔ REQ-LIMIT-3 limit 0 refuses with no records; the first limit hit in file order is named (0.136545ms)
|
||||
✔ REQ-LIMIT-3 a key limit is not enforced while every record's account is null (decision 150 Q1) (0.161235ms)
|
||||
✔ REQ-LIMIT-3 counts past the safe integer range come back as digit strings (0.131986ms)
|
||||
✔ REQ-LIMIT-4 bad records or times throw a code, and the check reads nothing but its arguments (0.612439ms)
|
||||
✔ REQ-LIMIT-3 no token limits: every launch is allowed and the report is empty (0.225872ms)
|
||||
✔ REQ-LIMIT-3 token-limit ignores tokens.daily, which the daily-quota check enforces (row 126) (0.115054ms)
|
||||
✔ P5 a model key ID limit counts stack records by key ID without an account (0.118321ms)
|
||||
✔ P5 Console displays stack count per safe key separately from optional proxy account numbers (0.840194ms)
|
||||
✔ P5 Console escapes hostile labels and labels unavailable telemetry without presenting a fresh zero (0.169412ms)
|
||||
✔ REQ-WEB-1 usage read keeps unknown counts and each token kind; no query or write is accepted (25.71419ms)
|
||||
✔ REQ-WEB-1 malformed usage is refused instead of shown as zero (4.903993ms)
|
||||
ℹ tests 170
|
||||
ℹ suites 0
|
||||
ℹ pass 170
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 8854.156666
|
||||
@@ -0,0 +1,36 @@
|
||||
✔ P5 broker preserves original plugin subject and derives internal run context from authenticated native caller (99.462478ms)
|
||||
✖ P5 configured key quotas never use a supplied safe-looking ID when trusted metadata lookup is missing (43.555167ms)
|
||||
✔ P5 internal context resolves exactly current or retained generation; wrong business, instance, run and owner refuse (0.357162ms)
|
||||
ℹ tests 3
|
||||
ℹ suites 0
|
||||
ℹ pass 2
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 237.626033
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/p5-key-context.test.mjs:23:1
|
||||
✖ P5 configured key quotas never use a supplied safe-looking ID when trusted metadata lookup is missing (43.555167ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
+ stop: false
|
||||
- check: null,
|
||||
- code: 'proxy-key-refused',
|
||||
- stop: true
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-key-context.test.mjs:27:9)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { stop: false },
|
||||
expected: { stop: true, check: null, code: 'proxy-key-refused' },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
✔ REQ-LIMIT-4 a role run at its limit stops at the end of its turn: RESULT and read land first, the claim is revoked by limit-check (135.950817ms)
|
||||
✔ REQ-LIMIT-4 the stop also lands on state; a run with no stop ends without a limit (183.02595ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a mustStop throw or a malformed answer stops the run, naming the bus and the code (446.621104ms)
|
||||
✔ REQ-LIMIT-4 a thread run at its limit is released with the reason, and its end record names the limit (114.707723ms)
|
||||
✔ REQ-LIMIT-4 a broker with no limit checks configured never stops a run (71.318028ms)
|
||||
✔ P5 broker preserves original plugin subject and derives internal run context from authenticated native caller (89.174131ms)
|
||||
✔ P5 configured key quotas never use a supplied safe-looking ID when trusted metadata lookup is missing (41.80406ms)
|
||||
✔ P5 internal context resolves exactly current or retained generation; wrong business, instance, run and owner refuse (0.436962ms)
|
||||
✔ P5 usage plugin off by default, default poll is 15 seconds and configured polls skip early ticks (57.810472ms)
|
||||
✔ P5 safe telemetry stores failures per key and proxy-labelled accounts; no client/upstream value enters store/log/view or quota records (54.180897ms)
|
||||
✔ P5 unknown msk key goes only to value-free reconcile log and other businesses stay isolated (41.762914ms)
|
||||
✔ P5 queue failure is safe, does not enforce and does not retry before poll deadline (43.65014ms)
|
||||
✔ P5 retiring key keeps attribution and telemetry rows remain append-only across reader restart (50.005361ms)
|
||||
✔ P5 malformed queue batch is atomic: no valid prefix, body or credential can reach store/log/view (42.308399ms)
|
||||
✔ P5 concurrent ticks issue one bounded queue read and a closed collector never polls again (46.350571ms)
|
||||
ℹ tests 15
|
||||
ℹ suites 0
|
||||
ℹ pass 15
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1674.306377
|
||||
@@ -0,0 +1,207 @@
|
||||
serial nice19; private HOME/XDG_CONFIG_HOME/TMPDIR/MOSAIC_CONFIG; unchanged whole-file budgets
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mayLaunch","subject":{"instance":"coder","provider":"anthropic","model":"opus","account":"jason-max"},"path":["tokens","daily","jason-max"],"limit":0,"count":0,"unknownTurns":0}
|
||||
usage: {"event":"usage-unknown","business":"demo","run":"run1","instance":"coder","turn":"4fe53301-641b-494d-a461-847c03170e3f","source":"@none","code":"baseline-unknown"}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mustStop","subject":{"instance":"coder","provider":"anthropic","model":"opus","account":"jason-max"},"path":["tokens","daily","jason-max"],"limit":0,"count":0,"unknownTurns":1}
|
||||
usage: {"event":"usage-unknown","business":"demo","run":"run1","instance":"coder","turn":"797da8e3-f04c-4e40-b8e1-bfb60b07c554","source":"@none","code":"baseline-unknown"}
|
||||
✔ REQ-LIMIT-2 runtime: limits counts the daily quota, and mayLaunch refuses only the account at it (158.160821ms)
|
||||
✔ REQ-LIMIT-4 runtime: a run bound with the account writes it on its usage records and stops at the quota (143.809206ms)
|
||||
✔ REQ-LIMIT-4 runtime: a run bound without an account records null and the daily quota never stops it (121.006833ms)
|
||||
✔ REQ-LIMIT-4 bindLaunch keeps the account off session.launched, refuses one that is not an identifier, and takes null as none (64.961645ms)
|
||||
✔ REQ-LIMIT-3 limitLeaves finds every limit object and skips the agent numbers (1.220027ms)
|
||||
✔ REQ-LIMIT-3 limitLeaves takes token limits at schema depth only, whatever their names (0.214936ms)
|
||||
✔ REQ-LIMIT-3 with no check switched on a launch is allowed, a turn never stops, and every limit is not enforced (44.021673ms)
|
||||
✔ REQ-LIMIT-3 a fixture check that refuses refuses the launch and stops the turn, logged with the limit and the count (43.052934ms)
|
||||
✔ REQ-LIMIT-3 a report that omits a limit shows it not enforced; a counted entry and a reason come through (40.139268ms)
|
||||
✔ REQ-LIMIT-4 each check gets the business, a copy of the limits, the subject, the records and the time (52.680831ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a throw refuses, stops and fails the report, naming the check and the code (47.313105ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a malformed answer, a promise, a rejected promise, a non-boolean or a bad hit is malformed-answer (46.754294ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a check switched on but not loaded refuses, stops and fails every limit as not-loaded (42.493056ms)
|
||||
✔ REQ-LIMIT-4 state(), never-loaded case: before any load the report shows not enforced, or not-loaded for a switched-on check (41.402846ms)
|
||||
✔ REQ-LIMIT-4 state(), first-load-refused case: a check refused on its first load is not-loaded in mayLaunch, mustStop and report (41.969573ms)
|
||||
✔ REQ-LIMIT-4 fail closed: an unreadable organization file refuses and stops with check null; the report throws (41.694193ms)
|
||||
✔ REQ-LIMIT-4 fail closed: unreadable records refuse and stop with check null and fail the report (0.52246ms)
|
||||
✔ REQ-LIMIT-3 the shipped token-limit, through the real loader, counts known records only since the limit was set (83.096899ms)
|
||||
✔ REQ-LIMIT-3 a token limit for a provider named limit is counted and refuses, beside an agent limit of the same name (50.535823ms)
|
||||
✔ REQ-LIMIT-3 core reaches limit checks only through the plug-in loader (1.710249ms)
|
||||
✔ P5 missing, ambiguous or invalid model key lookup fails closed without leaking a lookup error (41.544044ms)
|
||||
✔ P5 trusted lookup uses the retiring run key rather than the agent current key (39.590387ms)
|
||||
✔ P5 actual model metadata lookup rejects missing/ambiguous owners and never cross-attributes a retiring run (0.460753ms)
|
||||
✔ REQ-LIMIT-4 a role run at its limit stops at the end of its turn: RESULT and read land first, the claim is revoked by limit-check (132.493862ms)
|
||||
✔ REQ-LIMIT-4 the stop also lands on state; a run with no stop ends without a limit (177.559162ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a mustStop throw or a malformed answer stops the run, naming the bus and the code (440.047034ms)
|
||||
✔ REQ-LIMIT-4 a thread run at its limit is released with the reason, and its end record names the limit (109.873105ms)
|
||||
✔ REQ-LIMIT-4 a broker with no limit checks configured never stops a run (77.150566ms)
|
||||
limits: {"event":"limit-reached","business":"demo","check":"token-limit","export":"mayLaunch","subject":{"instance":"coder","provider":"zai","model":"glm-5.3-flash","account":null},"path":["tokens","instances","coder"],"limit":0,"count":0,"unknownTurns":0}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
usage: {"event":"usage-unknown","business":"demo","run":"run1","instance":"coder","turn":"b338e07c-04c8-4942-902f-484f07e73153","source":"@none","code":"baseline-unknown"}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"token-limit","export":"mustStop","subject":{"instance":"coder","provider":"zai","model":"glm-5.3-flash","account":null},"path":["tokens","instances","coder"],"limit":0,"count":0,"unknownTurns":1}
|
||||
usage: {"event":"usage-unknown","business":"demo","run":"run1","instance":"coder","turn":"fd7f45ea-e03c-49dd-a53c-e385fdd5acbf","source":"@none","code":"baseline-unknown"}
|
||||
✔ REQ-LIMIT-3 REQ-LIMIT-4 runtime: limits carries the token count, mayLaunch refuses at the limit, a reset moves since (245.80231ms)
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
✔ REQ-LIMIT-3 runtime: with no limit check switched on, the limit shows not enforced and every launch is allowed (84.052026ms)
|
||||
✔ REQ-LIMIT-4 runtime: the broker asks the shipped token-limit after a turn, and the run at its limit stops on its next receive (136.937413ms)
|
||||
✔ REQ-LIMIT-4 runtime: with no usage source a turn is unknown, counts zero and stops nothing under a limit of 1 (118.705264ms)
|
||||
✔ REQ-LIMIT-3 runtime: switching a limit check on with plugins.set loads it without a launch or a turn (165.970294ms)
|
||||
✔ P5 broker preserves original plugin subject and derives internal run context from authenticated native caller (90.023506ms)
|
||||
✔ P5 configured key quotas never use a supplied safe-looking ID when trusted metadata lookup is missing (42.127316ms)
|
||||
✔ P5 internal context resolves exactly current or retained generation; wrong business, instance, run and owner refuse (0.383979ms)
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["59bfaebcb056"]}
|
||||
model-proxy: {"action":"proxy.reconcile","addedKeyIds":[],"removedKeyIds":[]}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["59bfaebcb056"]}
|
||||
model-proxy: {"call":"PUT /v8/management/config/access/api-keys","status":200,"keyIds":["59bfaebcb056","fa6669b39602"]}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["59bfaebcb056","fa6669b39602"]}
|
||||
model-proxy: {"action":"proxy.key.issued","keyIds":["fa6669b39602"],"instance":"demo/coder"}
|
||||
model-proxy: {"call":"GET /v1/models","status":200,"keyIds":["fa6669b39602"]}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mustStop","subject":{"instance":"coder","provider":null,"model":null,"account":null,"modelKeyId":"fa6669b39602"},"path":["tokens","keys","fa6669b39602"],"limit":2,"count":2,"unknownTurns":0}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mayLaunch","subject":{"instance":"coder","provider":"fixture","model":"fake","account":null,"modelKeyId":"fa6669b39602"},"path":["tokens","keys","fa6669b39602"],"limit":2,"count":2,"unknownTurns":0}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
✔ P5 real runtime binds stack usage to issued key, daily stops at stack count and human-only telemetry settings pass broker contract (325.548897ms)
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
✔ plugins and plugins.set refuse every non-human session and a forged actor, and pass only the patch with the verified actor (104.870501ms)
|
||||
✔ runtime: the switch changes the organization file, the receipt carries the actor, and a bad shape, an unknown module and a stale revision are refused with nothing written (268.507544ms)
|
||||
✔ vikunja:19/309 through the broker, a patch switches the kinds it names and keeps the rest; null removes one kind and is trailed (215.488037ms)
|
||||
✔ P5 usage plugin off by default, default poll is 15 seconds and configured polls skip early ticks (60.18695ms)
|
||||
✔ P5 safe telemetry stores failures per key and proxy-labelled accounts; no client/upstream value enters store/log/view or quota records (56.879533ms)
|
||||
✔ P5 unknown msk key goes only to value-free reconcile log and other businesses stay isolated (46.789381ms)
|
||||
✔ P5 queue failure is safe, does not enforce and does not retry before poll deadline (43.152978ms)
|
||||
✔ P5 retiring key keeps attribution and telemetry rows remain append-only across reader restart (49.497425ms)
|
||||
✔ P5 malformed queue batch is atomic: no valid prefix, body or credential can reach store/log/view (46.179514ms)
|
||||
✔ P5 concurrent ticks issue one bounded queue read and a closed collector never polls again (46.481349ms)
|
||||
✔ REQ-LIMIT-4 usage protocol binds run identity, requires a delivered turn and isolates businesses (113.617169ms)
|
||||
✔ REQ-PLUG-1 runtime reaches transcript only through loader, over the real bus socket (154.197141ms)
|
||||
✔ REQ-LIMIT-4 loader source records new turn kinds, excludes history and retries exactly once (55.1487ms)
|
||||
✔ REQ-LIMIT-4 cut: unknown is durable and logged next to every total (48.001192ms)
|
||||
✔ REQ-LIMIT-4 disabled: unknown is durable and logged next to every total (52.699151ms)
|
||||
✔ REQ-LIMIT-4 missing-begin: unknown is durable and logged next to every total (43.859028ms)
|
||||
✔ REQ-LIMIT-4 no-new-usage: unknown is durable and logged next to every total (49.684957ms)
|
||||
✔ REQ-LIMIT-4 rewrite: unknown is durable and logged next to every total (48.842941ms)
|
||||
✔ REQ-LIMIT-4 unfinished turn remains visibly unknown after accounting restarts (46.725304ms)
|
||||
✔ usage records are append-only (43.666526ms)
|
||||
✔ REQ-LIMIT-4 parse failure logs its safe code, never transcript content (50.791657ms)
|
||||
✔ REQ-LIMIT-4 resumed run baselines history and exact totals do not overflow (67.235771ms)
|
||||
✔ REQ-PLUG-1 core has no transcript import and disabled sources do not read any transcript (50.444244ms)
|
||||
✔ REQ-LIMIT-4 a resumed thread bills only new assistant messages to its next run (48.518074ms)
|
||||
✔ REQ-LIMIT-4 every enabled source is called; failure is unknown and a partial total stays labelled (52.596237ms)
|
||||
✔ REQ-LIMIT-4 a turn whose reported sum exceeds safe precision is unknown, not rounded (48.989984ms)
|
||||
✔ row 65 a run bound without a transcript directory records no-transcript (47.601985ms)
|
||||
✔ P5 immutable stack key attribution survives rotation and restart without key values (58.908338ms)
|
||||
✔ P5 malformed key metadata is dropped rather than stored or exposed as a key value (48.622269ms)
|
||||
✔ REQ-PLUG-1 schema: plugins is optional, names known kinds and checked module names (11.123203ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the setter writes plugins through the organization writer and logs old and new names (144.541984ms)
|
||||
✔ vikunja:19/309 a patch changes only the kinds it names; null removes one kind, explicitly and in the trail (186.444017ms)
|
||||
✔ vikunja:19/309 an unknown kind (set or removed), a bad module, an empty patch and null on the wrong shape are refused, nothing written (2.070716ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the writer checks the bytes it writes: a Date in plugins is refused there too (24.002633ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 a refused setter write throws a code, changes nothing and logs nothing (1.819444ms)
|
||||
✔ vikunja:19/305 with an exists check, the setter refuses a module no tree file answers to, before anything is written (53.502998ms)
|
||||
✔ P5 optional usage kind and pollSeconds configure through plugins.set; default stays absent and retention bound is strict (102.914554ms)
|
||||
✔ P5 only human can enable/disable telemetry or change polling, including direct organization writes (153.795381ms)
|
||||
✔ REQ-LIMIT-3 schema: each subject kind, limit 0 and no ceiling are accepted; bad limits, times, keys and undeclared instances refuse (12.633498ms)
|
||||
✔ REQ-LIMIT-3 the writer stamps since: a new limit gets now, a changed one keeps its time, a different time is refused (250.719331ms)
|
||||
✔ REQ-LIMIT-3 only tokens.* at schema depth holds token limits: agent limits named `limit` save as sent, and a token limit named `limit` is stamped and reset (279.391871ms)
|
||||
✔ REQ-LIMIT-3 a reset moves since to now, is logged with its actor, and refuses a path that is not a limit (143.161688ms)
|
||||
✔ REQ-LIMIT-2 schema: launch.account names a credential set; a daily quota needs a reset and an IANA zone and names the account (22.600091ms)
|
||||
✔ REQ-LIMIT-2 the writer stamps a daily quota's since, keeps its reset and zone, and a reset moves since (147.449414ms)
|
||||
✔ P5 per-model-key quotas are unset by default, accept digit-leading IDs and only the human changes or resets them (211.379051ms)
|
||||
✔ probeKey observes 200 with one agent-authenticated GET /v1/models (13.650453ms)
|
||||
✔ probeKey observes 401 with one agent-authenticated GET /v1/models (2.452411ms)
|
||||
✔ probeKey observes 503 with one agent-authenticated GET /v1/models (1.454096ms)
|
||||
✔ proxy-down: agent-key probe connection failure is sanitized (1.507584ms)
|
||||
✔ proxy-down: silent listener cannot extend probe request deadline (51.18593ms)
|
||||
✔ agent-key probe returns redirect status without following Location or exposing key (2.629896ms)
|
||||
✔ proxy-client-invalid: https://127.0.0.1:18318 (0.940604ms)
|
||||
✔ proxy-client-invalid: http://example.com:18318 (0.620294ms)
|
||||
✔ proxy-client-invalid: http://localhost:18318 (0.082993ms)
|
||||
✔ proxy-client-invalid: http://127.0.0.1:8317 (0.075406ms)
|
||||
✔ proxy-client-invalid: http://user:[email protected]:18318 (0.082019ms)
|
||||
✔ proxy-client-invalid: http://127.0.0.1:18318/path (0.077949ms)
|
||||
✔ client GET/PUT v8 only, Authorization header, receipt IDs without values or bodies (16.759591ms)
|
||||
✔ proxy-client-refused (2.644555ms)
|
||||
✔ proxy-client-response (1.257544ms)
|
||||
✔ proxy-client-redirect (1.116738ms)
|
||||
✔ proxy-client-down: transport errors redact details (0.932782ms)
|
||||
✔ proxy-client-invalid: PUT rejects object key records and empty strings locally (0.174045ms)
|
||||
✔ proxy-management-key-invalid: missing, symlink and public key file refuse without values (0.93563ms)
|
||||
✔ bus management-key loader supplies a private fixture key without exposing it on the client (0.481342ms)
|
||||
✔ proxy-client-response: truncated response remains a redacted named refusal (11.038179ms)
|
||||
✔ management client ignores ambient fetch dispatchers (1.371561ms)
|
||||
✔ proxy-key-invalid: Latin-1 leaves complete config/data inventories unchanged (3.426795ms)
|
||||
✔ proxy-key-invalid: leading space leaves complete config/data inventories unchanged (1.114261ms)
|
||||
✔ proxy-key-invalid: trailing space leaves complete config/data inventories unchanged (1.011023ms)
|
||||
✔ proxy-key-invalid: internal space leaves complete config/data inventories unchanged (1.128478ms)
|
||||
✔ printable non-space ASCII control initializes and authenticates with unchanged existing files (16.93766ms)
|
||||
✔ OAuth management calls keep URL and state out of receipts (16.303618ms)
|
||||
✔ upstream key goes only in request body and upstream refusal body is discarded (3.098596ms)
|
||||
✔ redirected management calls are not followed or retried (1.618972ms)
|
||||
✔ P5 queue read uses actual bounded fixed management GET and immediately drops client and upstream values (14.682335ms)
|
||||
✔ P5 bad envelope refuses safely with no retry (2.770996ms)
|
||||
✔ P5 over count refuses safely with no retry (1.619582ms)
|
||||
✔ P5 missing key refuses safely with no retry (2.024573ms)
|
||||
✔ P5 bad counts refuses safely with no retry (1.40751ms)
|
||||
✔ P5 redirect refuses safely with no retry (1.380605ms)
|
||||
✔ P5 refusal refuses safely with no retry (0.992984ms)
|
||||
✔ P5 malformed event after a valid event rejects the entire queue before any credential can escape (1.079984ms)
|
||||
✔ REQ-LIMIT-2 daily-quota exports interface version 2 with mayLaunch, mustStop and report (1.195525ms)
|
||||
✔ REQ-LIMIT-2 the count sums every kind of the account's known records since the later of the day start and since (12.385039ms)
|
||||
✔ REQ-LIMIT-2 a launch with no account (pi) is covered by no daily quota (0.294446ms)
|
||||
✔ REQ-LIMIT-4 an unknown turn adds nothing and is counted apart (0.448244ms)
|
||||
✔ REQ-LIMIT-2 the day turns at the reset in its zone, not in UTC, and before it the day is yesterday's (0.585636ms)
|
||||
✔ REQ-LIMIT-2 the spring DST change makes the day after a 00:00 reset 23 hours long (0.344176ms)
|
||||
✔ REQ-LIMIT-2 the fall DST change makes the day after a 00:00 reset 25 hours long (0.309404ms)
|
||||
✔ REQ-LIMIT-2 a reset the clocks skip starts the day at the first instant after the gap (0.823288ms)
|
||||
✔ REQ-LIMIT-2 a reset the clocks repeat starts one day, at the first one (0.462864ms)
|
||||
✔ REQ-LIMIT-2 a launch is refused at the quota, a turn that reaches it stops, and the next day allows again (1.053193ms)
|
||||
✔ REQ-LIMIT-2 counts past the safe integer range come back as digit strings (0.384911ms)
|
||||
✔ REQ-LIMIT-4 bad leaves, records or times throw a code, and the check reads nothing but its arguments (2.335648ms)
|
||||
✔ REQ-LIMIT-2 no daily quotas: every launch is allowed and the report is empty (0.194429ms)
|
||||
✔ P5 daily quota for a model key ID matches stack key records and resets the next day (0.764141ms)
|
||||
✔ REQ-PLUG-1 REQ-LIMIT-4 the registry: usage-source at interface version 1, limit-check at 2 (row 125), each a list (1.078533ms)
|
||||
✔ REQ-PLUG-1 checkPlugins accepts one key per kind, each a list of names, empty included (0.243968ms)
|
||||
✔ REQ-PLUG-1 checkPlugins refuses bad shapes, unknown kinds, bad names and duplicates (0.928754ms)
|
||||
✔ REQ-PLUG-1 a kind that switches on one module takes one name, not a list (0.133743ms)
|
||||
✔ REQ-PLUG-1 checkPlugins reports through the caller's fail callback (0.128969ms)
|
||||
✔ P5 usage telemetry is optional, single module, separate from enforcing sources (0.180465ms)
|
||||
✔ REQ-PLUG-1 fixture modules of each kind switch on from a test organization file, no core file changed (9.158842ms)
|
||||
✔ REQ-PLUG-1 a name not matching ^[a-z][a-z0-9-]*$ refuses and keeps the old setting (4.034236ms)
|
||||
✔ REQ-PLUG-1 a missing module directory or index.mjs refuses and keeps the old setting (3.123767ms)
|
||||
✔ REQ-PLUG-1 a symlinked module directory or index.mjs refuses and keeps the old setting (2.857748ms)
|
||||
✔ REQ-PLUG-1 a symlinked kind directory refuses and keeps the old setting (2.422702ms)
|
||||
✔ REQ-PLUG-1 a symlinked packages/plugins refuses (run with --preserve-symlinks so the path keeps it) (27.290401ms)
|
||||
✔ REQ-PLUG-1 index.mjs swapped for a symlink after the lstat checks refuses at the realpath check (2.752498ms)
|
||||
✔ REQ-PLUG-1 a path that can't be read refuses as unreadable, is logged and keeps the old setting (2.289418ms)
|
||||
✔ REQ-PLUG-1 a path that becomes unreadable after the lstat checks refuses at either realpath (2.561921ms)
|
||||
✔ REQ-PLUG-1 a module that fails to load refuses and keeps the old setting (2.761977ms)
|
||||
✔ REQ-PLUG-1 a missing export refuses and keeps the old setting (3.894842ms)
|
||||
✔ REQ-PLUG-1 a different interface version refuses and keeps the old setting (2.759495ms)
|
||||
✔ REQ-PLUG-1 REQ-LIMIT-3 a version 1 limit check refuses after the bump to 2, and the old setting stays (2.719036ms)
|
||||
✔ REQ-PLUG-1 a kind refused on its first load has nothing switched on, and the log names kind and name (2.205867ms)
|
||||
✔ REQ-PLUG-1 the setting's shape: unknown kinds refuse alone, a bad whole setting keeps everything (3.120271ms)
|
||||
✔ REQ-PLUG-1 loads run one at a time, so the last requested setting wins (103.864421ms)
|
||||
✔ REQ-PLUG-1 the loader needs a log callback (1.369307ms)
|
||||
✔ REQ-LIMIT-3 token-limit exports interface version 2 with mayLaunch, mustStop and report (1.204087ms)
|
||||
✔ REQ-LIMIT-3 each subject kind refuses at its limit and allows under it (1.293377ms)
|
||||
✔ REQ-LIMIT-3 a limit covers only its own subject's records and launches (0.332255ms)
|
||||
✔ REQ-LIMIT-4 only known records count; an unknown turn adds nothing and is counted apart (0.241481ms)
|
||||
✔ REQ-LIMIT-3 a reset moves since: records before it no longer count (0.148082ms)
|
||||
✔ REQ-LIMIT-3 limit 0 refuses with no records; the first limit hit in file order is named (0.130431ms)
|
||||
✔ REQ-LIMIT-3 a key limit is not enforced while every record's account is null (decision 150 Q1) (0.168183ms)
|
||||
✔ REQ-LIMIT-3 counts past the safe integer range come back as digit strings (0.134841ms)
|
||||
✔ REQ-LIMIT-4 bad records or times throw a code, and the check reads nothing but its arguments (0.611062ms)
|
||||
✔ REQ-LIMIT-3 no token limits: every launch is allowed and the report is empty (0.218561ms)
|
||||
✔ REQ-LIMIT-3 token-limit ignores tokens.daily, which the daily-quota check enforces (row 126) (0.116475ms)
|
||||
✔ P5 a model key ID limit counts stack records by key ID without an account (0.113961ms)
|
||||
✔ P5 Console displays stack count per safe key separately from optional proxy account numbers (0.908576ms)
|
||||
✔ P5 Console escapes hostile labels and labels unavailable telemetry without presenting a fresh zero (0.662967ms)
|
||||
✔ REQ-WEB-1 usage read keeps unknown counts and each token kind; no query or write is accepted (26.726073ms)
|
||||
✔ REQ-WEB-1 malformed usage is refused instead of shown as zero (5.304556ms)
|
||||
ℹ tests 173
|
||||
ℹ suites 0
|
||||
ℹ pass 173
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 9284.877315
|
||||
@@ -0,0 +1,37 @@
|
||||
✔ P5 broker preserves original plugin subject and derives internal run context from authenticated native caller (100.714572ms)
|
||||
✔ P5 configured key quotas never use a supplied safe-looking ID when trusted metadata lookup is missing (42.059265ms)
|
||||
✔ P5 internal context resolves exactly current or retained generation; wrong business, instance, run and owner refuse (0.383747ms)
|
||||
✖ P5 model-key mustStop without native run context fails closed even when the current key resolves (42.738629ms)
|
||||
ℹ tests 4
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 276.940054
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at packages/bus/tests/p5-key-context.test.mjs:39:1
|
||||
✖ P5 model-key mustStop without native run context fails closed even when the current key resolves (42.738629ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
{
|
||||
+ stop: false
|
||||
- check: null,
|
||||
- code: 'proxy-key-refused',
|
||||
- stop: true
|
||||
}
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/.t3/worktrees/mosaic-stack/t3-79263d4f/packages/bus/tests/p5-key-context.test.mjs:43:9)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: { stop: false },
|
||||
expected: { stop: true, check: null, code: 'proxy-key-refused' },
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
serial nice19; private HOME/XDG_CONFIG_HOME/TMPDIR/MOSAIC_CONFIG; unchanged whole-file budgets
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mayLaunch","subject":{"instance":"coder","provider":"anthropic","model":"opus","account":"jason-max"},"path":["tokens","daily","jason-max"],"limit":0,"count":0,"unknownTurns":0}
|
||||
usage: {"event":"usage-unknown","business":"demo","run":"run1","instance":"coder","turn":"713a4859-153d-4efb-9e60-6abbd4549b0e","source":"@none","code":"baseline-unknown"}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mustStop","subject":{"instance":"coder","provider":"anthropic","model":"opus","account":"jason-max"},"path":["tokens","daily","jason-max"],"limit":0,"count":0,"unknownTurns":1}
|
||||
usage: {"event":"usage-unknown","business":"demo","run":"run1","instance":"coder","turn":"6615caa1-e75d-463c-b6b8-789d6dc77e40","source":"@none","code":"baseline-unknown"}
|
||||
✔ REQ-LIMIT-2 runtime: limits counts the daily quota, and mayLaunch refuses only the account at it (160.549327ms)
|
||||
✔ REQ-LIMIT-4 runtime: a run bound with the account writes it on its usage records and stops at the quota (143.628999ms)
|
||||
✔ REQ-LIMIT-4 runtime: a run bound without an account records null and the daily quota never stops it (123.342684ms)
|
||||
✔ REQ-LIMIT-4 bindLaunch keeps the account off session.launched, refuses one that is not an identifier, and takes null as none (67.349794ms)
|
||||
✔ REQ-LIMIT-3 limitLeaves finds every limit object and skips the agent numbers (1.271433ms)
|
||||
✔ REQ-LIMIT-3 limitLeaves takes token limits at schema depth only, whatever their names (0.194636ms)
|
||||
✔ REQ-LIMIT-3 with no check switched on a launch is allowed, a turn never stops, and every limit is not enforced (45.635942ms)
|
||||
✔ REQ-LIMIT-3 a fixture check that refuses refuses the launch and stops the turn, logged with the limit and the count (46.176242ms)
|
||||
✔ REQ-LIMIT-3 a report that omits a limit shows it not enforced; a counted entry and a reason come through (44.938267ms)
|
||||
✔ REQ-LIMIT-4 each check gets the business, a copy of the limits, the subject, the records and the time (54.558566ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a throw refuses, stops and fails the report, naming the check and the code (46.342833ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a malformed answer, a promise, a rejected promise, a non-boolean or a bad hit is malformed-answer (47.766687ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a check switched on but not loaded refuses, stops and fails every limit as not-loaded (43.59231ms)
|
||||
✔ REQ-LIMIT-4 state(), never-loaded case: before any load the report shows not enforced, or not-loaded for a switched-on check (48.104463ms)
|
||||
✔ REQ-LIMIT-4 state(), first-load-refused case: a check refused on its first load is not-loaded in mayLaunch, mustStop and report (42.805959ms)
|
||||
✔ REQ-LIMIT-4 fail closed: an unreadable organization file refuses and stops with check null; the report throws (43.597155ms)
|
||||
✔ REQ-LIMIT-4 fail closed: unreadable records refuse and stop with check null and fail the report (0.492317ms)
|
||||
✔ REQ-LIMIT-3 the shipped token-limit, through the real loader, counts known records only since the limit was set (91.037972ms)
|
||||
✔ REQ-LIMIT-3 a token limit for a provider named limit is counted and refuses, beside an agent limit of the same name (50.368678ms)
|
||||
✔ REQ-LIMIT-3 core reaches limit checks only through the plug-in loader (1.715607ms)
|
||||
✔ P5 missing, ambiguous or invalid model key lookup fails closed without leaking a lookup error (40.810413ms)
|
||||
✔ P5 trusted lookup uses the retiring run key rather than the agent current key (35.820247ms)
|
||||
✔ P5 actual model metadata lookup rejects missing/ambiguous owners and never cross-attributes a retiring run (0.45891ms)
|
||||
✔ REQ-LIMIT-4 a role run at its limit stops at the end of its turn: RESULT and read land first, the claim is revoked by limit-check (121.318326ms)
|
||||
✔ REQ-LIMIT-4 the stop also lands on state; a run with no stop ends without a limit (168.385765ms)
|
||||
✔ REQ-LIMIT-4 fail closed: a mustStop throw or a malformed answer stops the run, naming the bus and the code (417.685568ms)
|
||||
✔ REQ-LIMIT-4 a thread run at its limit is released with the reason, and its end record names the limit (114.909337ms)
|
||||
✔ REQ-LIMIT-4 a broker with no limit checks configured never stops a run (77.129589ms)
|
||||
limits: {"event":"limit-reached","business":"demo","check":"token-limit","export":"mayLaunch","subject":{"instance":"coder","provider":"zai","model":"glm-5.3-flash","account":null},"path":["tokens","instances","coder"],"limit":0,"count":0,"unknownTurns":0}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
usage: {"event":"usage-unknown","business":"demo","run":"run1","instance":"coder","turn":"5c3d20b7-bbe0-44e1-876f-393c04bf33e3","source":"@none","code":"baseline-unknown"}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"token-limit","export":"mustStop","subject":{"instance":"coder","provider":"zai","model":"glm-5.3-flash","account":null},"path":["tokens","instances","coder"],"limit":0,"count":0,"unknownTurns":1}
|
||||
usage: {"event":"usage-unknown","business":"demo","run":"run1","instance":"coder","turn":"1ed92631-bf69-4279-8f2e-da5c8c2d9061","source":"@none","code":"baseline-unknown"}
|
||||
✔ REQ-LIMIT-3 REQ-LIMIT-4 runtime: limits carries the token count, mayLaunch refuses at the limit, a reset moves since (242.78734ms)
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
✔ REQ-LIMIT-3 runtime: with no limit check switched on, the limit shows not enforced and every launch is allowed (83.772136ms)
|
||||
✔ REQ-LIMIT-4 runtime: the broker asks the shipped token-limit after a turn, and the run at its limit stops on its next receive (135.822066ms)
|
||||
✔ REQ-LIMIT-4 runtime: with no usage source a turn is unknown, counts zero and stops nothing under a limit of 1 (121.123659ms)
|
||||
✔ REQ-LIMIT-3 runtime: switching a limit check on with plugins.set loads it without a launch or a turn (159.884938ms)
|
||||
✔ P5 broker preserves original plugin subject and derives internal run context from authenticated native caller (89.685601ms)
|
||||
✔ P5 configured key quotas never use a supplied safe-looking ID when trusted metadata lookup is missing (41.975207ms)
|
||||
✔ P5 internal context resolves exactly current or retained generation; wrong business, instance, run and owner refuse (0.374876ms)
|
||||
✔ P5 model-key mustStop without native run context fails closed even when the current key resolves (39.706143ms)
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["2ab905e62cf4"]}
|
||||
model-proxy: {"action":"proxy.reconcile","addedKeyIds":[],"removedKeyIds":[]}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["2ab905e62cf4"]}
|
||||
model-proxy: {"call":"PUT /v8/management/config/access/api-keys","status":200,"keyIds":["2ab905e62cf4","f81b23885f0a"]}
|
||||
model-proxy: {"call":"GET /v8/management/config/access/api-keys","status":200,"keyIds":["2ab905e62cf4","f81b23885f0a"]}
|
||||
model-proxy: {"action":"proxy.key.issued","keyIds":["f81b23885f0a"],"instance":"demo/coder"}
|
||||
model-proxy: {"call":"GET /v1/models","status":200,"keyIds":["f81b23885f0a"]}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mustStop","subject":{"instance":"coder","provider":null,"model":null,"account":null,"modelKeyId":"f81b23885f0a"},"path":["tokens","keys","f81b23885f0a"],"limit":2,"count":2,"unknownTurns":0}
|
||||
limits: {"event":"limit-reached","business":"demo","check":"daily-quota","export":"mayLaunch","subject":{"instance":"coder","provider":"fixture","model":"fake","account":null,"modelKeyId":"f81b23885f0a"},"path":["tokens","keys","f81b23885f0a"],"limit":2,"count":2,"unknownTurns":0}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
✔ P5 real runtime binds stack usage to issued key, daily stops at stack count and human-only telemetry settings pass broker contract (319.346483ms)
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
organization: {"event":"reload-needs-restart","business":"demo"}
|
||||
✔ plugins and plugins.set refuse every non-human session and a forged actor, and pass only the patch with the verified actor (102.705755ms)
|
||||
✔ runtime: the switch changes the organization file, the receipt carries the actor, and a bad shape, an unknown module and a stale revision are refused with nothing written (258.622237ms)
|
||||
✔ vikunja:19/309 through the broker, a patch switches the kinds it names and keeps the rest; null removes one kind and is trailed (194.943673ms)
|
||||
✔ P5 usage plugin off by default, default poll is 15 seconds and configured polls skip early ticks (58.879723ms)
|
||||
✔ P5 safe telemetry stores failures per key and proxy-labelled accounts; no client/upstream value enters store/log/view or quota records (51.610465ms)
|
||||
✔ P5 unknown msk key goes only to value-free reconcile log and other businesses stay isolated (41.842706ms)
|
||||
✔ P5 queue failure is safe, does not enforce and does not retry before poll deadline (43.265972ms)
|
||||
✔ P5 retiring key keeps attribution and telemetry rows remain append-only across reader restart (45.846149ms)
|
||||
✔ P5 malformed queue batch is atomic: no valid prefix, body or credential can reach store/log/view (42.767318ms)
|
||||
✔ P5 concurrent ticks issue one bounded queue read and a closed collector never polls again (42.425739ms)
|
||||
✔ REQ-LIMIT-4 usage protocol binds run identity, requires a delivered turn and isolates businesses (107.035274ms)
|
||||
✔ REQ-PLUG-1 runtime reaches transcript only through loader, over the real bus socket (138.029928ms)
|
||||
✔ REQ-LIMIT-4 loader source records new turn kinds, excludes history and retries exactly once (102.708913ms)
|
||||
✔ REQ-LIMIT-4 cut: unknown is durable and logged next to every total (51.29996ms)
|
||||
✔ REQ-LIMIT-4 disabled: unknown is durable and logged next to every total (44.547138ms)
|
||||
✔ REQ-LIMIT-4 missing-begin: unknown is durable and logged next to every total (40.305662ms)
|
||||
✔ REQ-LIMIT-4 no-new-usage: unknown is durable and logged next to every total (46.243747ms)
|
||||
✔ REQ-LIMIT-4 rewrite: unknown is durable and logged next to every total (49.699154ms)
|
||||
✔ REQ-LIMIT-4 unfinished turn remains visibly unknown after accounting restarts (41.750326ms)
|
||||
✔ usage records are append-only (44.741061ms)
|
||||
✔ REQ-LIMIT-4 parse failure logs its safe code, never transcript content (46.066508ms)
|
||||
✔ REQ-LIMIT-4 resumed run baselines history and exact totals do not overflow (58.388899ms)
|
||||
✔ REQ-PLUG-1 core has no transcript import and disabled sources do not read any transcript (45.643672ms)
|
||||
✔ REQ-LIMIT-4 a resumed thread bills only new assistant messages to its next run (46.749719ms)
|
||||
✔ REQ-LIMIT-4 every enabled source is called; failure is unknown and a partial total stays labelled (51.822533ms)
|
||||
✔ REQ-LIMIT-4 a turn whose reported sum exceeds safe precision is unknown, not rounded (53.80965ms)
|
||||
✔ row 65 a run bound without a transcript directory records no-transcript (57.433717ms)
|
||||
✔ P5 immutable stack key attribution survives rotation and restart without key values (47.921754ms)
|
||||
✔ P5 malformed key metadata is dropped rather than stored or exposed as a key value (48.881094ms)
|
||||
✔ REQ-PLUG-1 schema: plugins is optional, names known kinds and checked module names (9.919614ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the setter writes plugins through the organization writer and logs old and new names (141.282316ms)
|
||||
✔ vikunja:19/309 a patch changes only the kinds it names; null removes one kind, explicitly and in the trail (199.085632ms)
|
||||
✔ vikunja:19/309 an unknown kind (set or removed), a bad module, an empty patch and null on the wrong shape are refused, nothing written (5.994558ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the writer checks the bytes it writes: a Date in plugins is refused there too (29.095644ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 a refused setter write throws a code, changes nothing and logs nothing (2.986444ms)
|
||||
✔ vikunja:19/305 with an exists check, the setter refuses a module no tree file answers to, before anything is written (64.912764ms)
|
||||
✔ P5 optional usage kind and pollSeconds configure through plugins.set; default stays absent and retention bound is strict (124.041908ms)
|
||||
✔ P5 only human can enable/disable telemetry or change polling, including direct organization writes (163.47796ms)
|
||||
✔ REQ-LIMIT-3 schema: each subject kind, limit 0 and no ceiling are accepted; bad limits, times, keys and undeclared instances refuse (25.815386ms)
|
||||
✔ REQ-LIMIT-3 the writer stamps since: a new limit gets now, a changed one keeps its time, a different time is refused (253.253525ms)
|
||||
✔ REQ-LIMIT-3 only tokens.* at schema depth holds token limits: agent limits named `limit` save as sent, and a token limit named `limit` is stamped and reset (294.58611ms)
|
||||
✔ REQ-LIMIT-3 a reset moves since to now, is logged with its actor, and refuses a path that is not a limit (144.894737ms)
|
||||
✔ REQ-LIMIT-2 schema: launch.account names a credential set; a daily quota needs a reset and an IANA zone and names the account (26.673634ms)
|
||||
✔ REQ-LIMIT-2 the writer stamps a daily quota's since, keeps its reset and zone, and a reset moves since (173.373389ms)
|
||||
✔ P5 per-model-key quotas are unset by default, accept digit-leading IDs and only the human changes or resets them (221.557913ms)
|
||||
✔ probeKey observes 200 with one agent-authenticated GET /v1/models (13.906006ms)
|
||||
✔ probeKey observes 401 with one agent-authenticated GET /v1/models (2.654873ms)
|
||||
✔ probeKey observes 503 with one agent-authenticated GET /v1/models (1.465852ms)
|
||||
✔ proxy-down: agent-key probe connection failure is sanitized (1.484469ms)
|
||||
✔ proxy-down: silent listener cannot extend probe request deadline (52.146773ms)
|
||||
✔ agent-key probe returns redirect status without following Location or exposing key (2.580254ms)
|
||||
✔ proxy-client-invalid: https://127.0.0.1:18318 (0.937801ms)
|
||||
✔ proxy-client-invalid: http://example.com:18318 (0.535029ms)
|
||||
✔ proxy-client-invalid: http://localhost:18318 (0.087694ms)
|
||||
✔ proxy-client-invalid: http://127.0.0.1:8317 (0.069318ms)
|
||||
✔ proxy-client-invalid: http://user:[email protected]:18318 (0.073249ms)
|
||||
✔ proxy-client-invalid: http://127.0.0.1:18318/path (0.061539ms)
|
||||
✔ client GET/PUT v8 only, Authorization header, receipt IDs without values or bodies (16.662783ms)
|
||||
✔ proxy-client-refused (2.363491ms)
|
||||
✔ proxy-client-response (1.26715ms)
|
||||
✔ proxy-client-redirect (1.119781ms)
|
||||
✔ proxy-client-down: transport errors redact details (0.943923ms)
|
||||
✔ proxy-client-invalid: PUT rejects object key records and empty strings locally (0.172918ms)
|
||||
✔ proxy-management-key-invalid: missing, symlink and public key file refuse without values (0.890633ms)
|
||||
✔ bus management-key loader supplies a private fixture key without exposing it on the client (0.473687ms)
|
||||
✔ proxy-client-response: truncated response remains a redacted named refusal (10.816438ms)
|
||||
✔ management client ignores ambient fetch dispatchers (1.14023ms)
|
||||
✔ proxy-key-invalid: Latin-1 leaves complete config/data inventories unchanged (3.507611ms)
|
||||
✔ proxy-key-invalid: leading space leaves complete config/data inventories unchanged (1.092119ms)
|
||||
✔ proxy-key-invalid: trailing space leaves complete config/data inventories unchanged (1.004054ms)
|
||||
✔ proxy-key-invalid: internal space leaves complete config/data inventories unchanged (1.102862ms)
|
||||
✔ printable non-space ASCII control initializes and authenticates with unchanged existing files (16.268442ms)
|
||||
✔ OAuth management calls keep URL and state out of receipts (16.20323ms)
|
||||
✔ upstream key goes only in request body and upstream refusal body is discarded (3.013252ms)
|
||||
✔ redirected management calls are not followed or retried (1.543184ms)
|
||||
✔ P5 queue read uses actual bounded fixed management GET and immediately drops client and upstream values (14.200284ms)
|
||||
✔ P5 bad envelope refuses safely with no retry (2.700404ms)
|
||||
✔ P5 over count refuses safely with no retry (1.604716ms)
|
||||
✔ P5 missing key refuses safely with no retry (1.370666ms)
|
||||
✔ P5 bad counts refuses safely with no retry (2.020663ms)
|
||||
✔ P5 redirect refuses safely with no retry (1.338733ms)
|
||||
✔ P5 refusal refuses safely with no retry (0.975888ms)
|
||||
✔ P5 malformed event after a valid event rejects the entire queue before any credential can escape (1.062269ms)
|
||||
✔ REQ-LIMIT-2 daily-quota exports interface version 2 with mayLaunch, mustStop and report (1.111774ms)
|
||||
✔ REQ-LIMIT-2 the count sums every kind of the account's known records since the later of the day start and since (11.668338ms)
|
||||
✔ REQ-LIMIT-2 a launch with no account (pi) is covered by no daily quota (0.297908ms)
|
||||
✔ REQ-LIMIT-4 an unknown turn adds nothing and is counted apart (0.432147ms)
|
||||
✔ REQ-LIMIT-2 the day turns at the reset in its zone, not in UTC, and before it the day is yesterday's (0.598992ms)
|
||||
✔ REQ-LIMIT-2 the spring DST change makes the day after a 00:00 reset 23 hours long (0.356206ms)
|
||||
✔ REQ-LIMIT-2 the fall DST change makes the day after a 00:00 reset 25 hours long (0.313154ms)
|
||||
✔ REQ-LIMIT-2 a reset the clocks skip starts the day at the first instant after the gap (0.81377ms)
|
||||
✔ REQ-LIMIT-2 a reset the clocks repeat starts one day, at the first one (0.455025ms)
|
||||
✔ REQ-LIMIT-2 a launch is refused at the quota, a turn that reaches it stops, and the next day allows again (1.086843ms)
|
||||
✔ REQ-LIMIT-2 counts past the safe integer range come back as digit strings (0.349512ms)
|
||||
✔ REQ-LIMIT-4 bad leaves, records or times throw a code, and the check reads nothing but its arguments (2.388492ms)
|
||||
✔ REQ-LIMIT-2 no daily quotas: every launch is allowed and the report is empty (0.195575ms)
|
||||
✔ P5 daily quota for a model key ID matches stack key records and resets the next day (0.769635ms)
|
||||
✔ REQ-PLUG-1 REQ-LIMIT-4 the registry: usage-source at interface version 1, limit-check at 2 (row 125), each a list (1.012155ms)
|
||||
✔ REQ-PLUG-1 checkPlugins accepts one key per kind, each a list of names, empty included (0.250245ms)
|
||||
✔ REQ-PLUG-1 checkPlugins refuses bad shapes, unknown kinds, bad names and duplicates (0.922679ms)
|
||||
✔ REQ-PLUG-1 a kind that switches on one module takes one name, not a list (0.147977ms)
|
||||
✔ REQ-PLUG-1 checkPlugins reports through the caller's fail callback (0.122575ms)
|
||||
✔ P5 usage telemetry is optional, single module, separate from enforcing sources (0.132403ms)
|
||||
✔ REQ-PLUG-1 fixture modules of each kind switch on from a test organization file, no core file changed (9.032509ms)
|
||||
✔ REQ-PLUG-1 a name not matching ^[a-z][a-z0-9-]*$ refuses and keeps the old setting (3.876412ms)
|
||||
✔ REQ-PLUG-1 a missing module directory or index.mjs refuses and keeps the old setting (2.975479ms)
|
||||
✔ REQ-PLUG-1 a symlinked module directory or index.mjs refuses and keeps the old setting (2.818854ms)
|
||||
✔ REQ-PLUG-1 a symlinked kind directory refuses and keeps the old setting (2.461598ms)
|
||||
✔ REQ-PLUG-1 a symlinked packages/plugins refuses (run with --preserve-symlinks so the path keeps it) (30.463335ms)
|
||||
✔ REQ-PLUG-1 index.mjs swapped for a symlink after the lstat checks refuses at the realpath check (2.687366ms)
|
||||
✔ REQ-PLUG-1 a path that can't be read refuses as unreadable, is logged and keeps the old setting (2.214904ms)
|
||||
✔ REQ-PLUG-1 a path that becomes unreadable after the lstat checks refuses at either realpath (2.519903ms)
|
||||
✔ REQ-PLUG-1 a module that fails to load refuses and keeps the old setting (2.657821ms)
|
||||
✔ REQ-PLUG-1 a missing export refuses and keeps the old setting (3.655045ms)
|
||||
✔ REQ-PLUG-1 a different interface version refuses and keeps the old setting (2.640761ms)
|
||||
✔ REQ-PLUG-1 REQ-LIMIT-3 a version 1 limit check refuses after the bump to 2, and the old setting stays (2.650255ms)
|
||||
✔ REQ-PLUG-1 a kind refused on its first load has nothing switched on, and the log names kind and name (2.148582ms)
|
||||
✔ REQ-PLUG-1 the setting's shape: unknown kinds refuse alone, a bad whole setting keeps everything (2.724542ms)
|
||||
✔ REQ-PLUG-1 loads run one at a time, so the last requested setting wins (103.671706ms)
|
||||
✔ REQ-PLUG-1 the loader needs a log callback (1.199165ms)
|
||||
✔ REQ-LIMIT-3 token-limit exports interface version 2 with mayLaunch, mustStop and report (0.667098ms)
|
||||
✔ REQ-LIMIT-3 each subject kind refuses at its limit and allows under it (1.777171ms)
|
||||
✔ REQ-LIMIT-3 a limit covers only its own subject's records and launches (0.345096ms)
|
||||
✔ REQ-LIMIT-4 only known records count; an unknown turn adds nothing and is counted apart (0.242181ms)
|
||||
✔ REQ-LIMIT-3 a reset moves since: records before it no longer count (0.147915ms)
|
||||
✔ REQ-LIMIT-3 limit 0 refuses with no records; the first limit hit in file order is named (0.129665ms)
|
||||
✔ REQ-LIMIT-3 a key limit is not enforced while every record's account is null (decision 150 Q1) (0.156705ms)
|
||||
✔ REQ-LIMIT-3 counts past the safe integer range come back as digit strings (0.145396ms)
|
||||
✔ REQ-LIMIT-4 bad records or times throw a code, and the check reads nothing but its arguments (0.617108ms)
|
||||
✔ REQ-LIMIT-3 no token limits: every launch is allowed and the report is empty (0.218957ms)
|
||||
✔ REQ-LIMIT-3 token-limit ignores tokens.daily, which the daily-quota check enforces (row 126) (0.119273ms)
|
||||
✔ P5 a model key ID limit counts stack records by key ID without an account (0.120965ms)
|
||||
✔ P5 Console displays stack count per safe key separately from optional proxy account numbers (0.925558ms)
|
||||
✔ P5 Console escapes hostile labels and labels unavailable telemetry without presenting a fresh zero (0.191209ms)
|
||||
✔ REQ-WEB-1 usage read keeps unknown counts and each token kind; no query or write is accepted (27.325912ms)
|
||||
✔ REQ-WEB-1 malformed usage is refused instead of shown as zero (5.087908ms)
|
||||
ℹ tests 174
|
||||
ℹ suites 0
|
||||
ℹ pass 174
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 9323.231998
|
||||
@@ -0,0 +1,944 @@
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/bus/tests/daily-quota-runtime.test.mjs","sha256":"dbbfa80b4082fd44e2f08539b5455653fac062321b8f2106f638e2d8161fa3eb"}
|
||||
{"path":"packages/bus/src/store.mjs","sha256":"dd7fce9706402efd1c5a5b81f7d0fa3793de203e7a6aef4e118e934aebdc7c84"}
|
||||
{"path":"packages/bus/src/broker.mjs","sha256":"c0144adade79c2cfc6b8247721393f0250b1d64f6c6c04d85738cb80939c42e5"}
|
||||
{"path":"packages/bus/src/proxy-page-vocabulary.mjs","sha256":"cec059ea4bef5ef62f6181123bfe64bca21d8985d5357471da8c0a3199a877f9"}
|
||||
{"path":"packages/model-proxy/src/validation.mjs","sha256":"e66453cf6662677cf28cbad1ae8f7509917d333e5b80404ab02c53f5cf75e9e1"}
|
||||
{"path":"packages/bus/src/address.mjs","sha256":"232a1c77c2f17011c53b55fc6052f70985598210769d41d7c2c0b535328aad23"}
|
||||
{"path":"packages/processing-control/src/state.mjs","sha256":"ed834770fed863cb0c15b75062de1fd63dea940f3b42020b769a7e62b319c8ed"}
|
||||
{"path":"packages/plugins/src/kinds.mjs","sha256":"eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78"}
|
||||
{"path":"packages/tasks/src/requirements.mjs","sha256":"38e7b85650247759f06c09fce205b2970b8368bc81491f51dc6b3c90ba2a846d"}
|
||||
{"path":"packages/bus/src/landing.mjs","sha256":"9919febc7679168e0a72c0ef51983120283e595fea290a5e8e948409bf5c911b"}
|
||||
{"path":"packages/business/src/vocabulary.mjs","sha256":"de1f04628e400084a46e77fd7e03c7a039f0f80c9e07bb486c9c012f187aa3eb"}
|
||||
{"path":"packages/bus/schema.sql","sha256":"a2ba3a46f12e56139ecae9e55227d00847842aedec50c1d92aaae28844ca48e7"}
|
||||
{"path":"packages/bus/src/migrations/3b.sql","sha256":"179ffe356d4ff19a49b5ebad39b6c6bfd7771deb8e1b7c55b5e746f039d69e65"}
|
||||
{"path":"packages/bus/src/migrations/3b-3c.sql","sha256":"b753f630301bf125e9e286b4156d0736930dd8fb9cd8eb2ebf316688f9191a07"}
|
||||
{"path":"packages/bus/src/migrations/3c-3d.sql","sha256":"0423832d05aa68f9191d7362827bd19310001165b895fb2de40b962fe68f9d56"}
|
||||
{"path":"packages/bus/src/migrations/3d-3e.sql","sha256":"d9aacc974d5047790e65c30a90068259bb9396dc92d4904eae3b9c5dbbb2f077"}
|
||||
{"path":"packages/bus/src/migrations/3e-3f.sql","sha256":"bf0b72c606b1a56a1610f09619b0c1118f1f300c636824ea13fd51a4ca6ac4b3"}
|
||||
{"path":"packages/bus/src/migrations/3f-3g.sql","sha256":"82f54b264919e34282bc214e34e9849f701cd3723b9b2f0a0d107c16f939dc05"}
|
||||
{"path":"packages/bus/src/migrations/3g-3h.sql","sha256":"76168e4f9f6b427286ddb8402fd833acadb01d6325a85f60e9ccf8d42fe2d1d0"}
|
||||
{"path":"packages/bus/src/migrations/3h-3i.sql","sha256":"e058e6cea8da7b6e649f3e03f2b81dc5444ee940a64274d0e367124c93545035"}
|
||||
{"path":"packages/bus/src/migrations/3i-3j.sql","sha256":"5ad122ca950e43e066f3d9ed215e73353e6b26de6687b961a8818d69c9465031"}
|
||||
{"path":"packages/bus/src/migrations/3j-3k.sql","sha256":"2e2bb1fe70076f5e24406a18a923b9e55c4192178a0a704a1b9716032676f9d4"}
|
||||
{"path":"packages/bus/src/migrations/3k-3l.sql","sha256":"eb2822c73e527697399691ae520092277ddbd4d2a9a42a0731b3c81cc3569e58"}
|
||||
{"path":"packages/bus/src/migrations/3l-3m.sql","sha256":"791879f06a3e97d3cfbe6112e2fb6502457af30b3e0198e3da1192038906d156"}
|
||||
{"path":"packages/bus/src/migrations/3m-3n.sql","sha256":"b40bc6a7bedc459d6827cbf0414619e48fc5dce2febdeff70a647345f2281c3a"}
|
||||
{"path":"packages/bus/src/runtime.mjs","sha256":"969d04eb06b97093c7f9f0dfa6b51084c781e967e2668814083bbba84a2af7b6"}
|
||||
{"path":"packages/project/src/index.mjs","sha256":"3ab38cc40ce9ed1a714a59a1f2c336c3792a59431a6a9cc655ba6a2f47513899"}
|
||||
{"path":"packages/project/src/paths.mjs","sha256":"bd9debcf3f9bb92560e74f220a0b108dfe24154bc6d1fb03c5ec414356d451f9"}
|
||||
{"path":"packages/project/src/git.mjs","sha256":"af6865a4cace92ef27910098507ffedfc8dfe768cea088b1fee21d0876cc556e"}
|
||||
{"path":"packages/seat/src/checkout.mjs","sha256":"5aca02491fe8df51487968ce62c776d493d0fe693cc41478b84bef7b49c8948d"}
|
||||
{"path":"packages/processing-control/src/effects.mjs","sha256":"3bc600649267f011e21ed8266fb16927b0ad3a0e2c49e4b54062d34c544d0c17"}
|
||||
{"path":"packages/processing-control/src/runtimes.mjs","sha256":"7145420aa354180689a5c84423928fc60c8123476dcfed3364c9cf4542f8c7ea"}
|
||||
{"path":"packages/project/src/validate.mjs","sha256":"e49ab5e825f0706da2f3c8dfcf33c1331a38d77ca2d35b03359ee68ea74652c5"}
|
||||
{"path":"packages/project/src/read.mjs","sha256":"42113cd20eb8f04dd252f9963a6f1a84806af9cae7beb6808c4d584a2548220c"}
|
||||
{"path":"packages/library/src/index.mjs","sha256":"98c2c2877549c3e2c5963ec4e49d99ab3b6d6ad54fb3bfae86cf98542207157e"}
|
||||
{"path":"packages/library/src/problems.mjs","sha256":"0c8764b03dae0150c56af74bcb113cf583dcbe1fa0c6f7386ef2d48d59a6bd31"}
|
||||
{"path":"packages/library/src/mapping.mjs","sha256":"c83c626c7cdc2a00ba4217c34b889ca0517cd2022d1f8fc9e7d3a14a0293a802"}
|
||||
{"path":"packages/library/src/scope.mjs","sha256":"97e12255f52ad638eeacd152eb26822f9a2aa72cd30e2fed1193f51cd6e56192"}
|
||||
{"path":"packages/library/src/supporting.mjs","sha256":"6a3b4de2070e62b1cca1c0ab20f2883d3153fc61608d1bf7670cecea08765b4c"}
|
||||
{"path":"packages/library/src/links.mjs","sha256":"def32a176cb70c86248e45908edde22f9c4c5f88575a4af0a396a05f617358bc"}
|
||||
{"path":"packages/library/src/reader.mjs","sha256":"ea126533afb7e74b71419eb943febb6b242eb96fc6917d9df1019db3e7e6ce8d"}
|
||||
{"path":"packages/library/src/render.mjs","sha256":"bfc3de029d3c8f0dcc96c90fde30d6da58bbb5b72d8f13e3f536c0d735c73ca5"}
|
||||
{"path":"packages/library/src/survey.mjs","sha256":"016bfa5c80572c0baf90ced39cb3d3ec66d395f0be15c2727b9552a9dd849093"}
|
||||
{"path":"packages/library/src/mirror.mjs","sha256":"26b824d6885e5c6d1b8bd71e754a9fa333c26307693f7e6a0c6a8e6300ecb4ae"}
|
||||
{"path":"packages/library/src/sync.mjs","sha256":"a58f3aec5ed9b3530b363e2fdbd38bc9ded7635d261ab2fca3cb31c45dcd3dfa"}
|
||||
{"path":"packages/library/src/index-build.mjs","sha256":"70c1fe75cb2149c9a074d55a6301d5b66157c2dc2e777b92bac338cce09d89c7"}
|
||||
{"path":"packages/library/src/query.mjs","sha256":"bafe113bee70f17bd249876d6bdd1c08fa051223c2111955e5d5f275bd76bba0"}
|
||||
{"path":"packages/library/src/limits.mjs","sha256":"98ef45ed61144aaea44d8aea1ac43082b6d340297e46846d01772da38728e530"}
|
||||
{"path":"packages/library/src/guard.mjs","sha256":"f710d9600a17f6e2989a289cfe84e58f161d86c7306605946ce05fa71b364eb2"}
|
||||
{"path":"packages/library/src/reply-protocol.mjs","sha256":"7b46f47b5e9d6b554b5d39bce2cd95c4610f5f35b8ab8fdc5a2864b3214be809"}
|
||||
{"path":"packages/library/src/write.mjs","sha256":"a301b7c7e3f42f66cb69d88991220f4e236f25a6e5951c61e79ec4ef2b714198"}
|
||||
{"path":"packages/bus/src/credentials.mjs","sha256":"10485afcf94c29ac9f3d5ba30b12248a2379efd69185ff9fb90e9fed25fe0678"}
|
||||
{"path":"packages/bus/src/server.mjs","sha256":"8318bed9168ac3f58c09de40a139b68aacefd684e6c117406e181e2ca5ab4ec7"}
|
||||
{"path":"packages/bus/src/interpreter.mjs","sha256":"56bfc8dcba476886d7de61a1e798aae8e3041c2434c62d44fc40a168d22bb3bd"}
|
||||
{"path":"packages/bus/src/peercred.mjs","sha256":"29c88655e8b9aed8db604573c9213fd9f3c40ef35ff04f4eda8fbe8f1b8a32d7"}
|
||||
{"path":"packages/business/src/launch-settings.mjs","sha256":"e14d73f719664499d809909962a6ecc16d4ffb9d824fcdee699e0778809d9e96"}
|
||||
{"path":"packages/business/src/organization.mjs","sha256":"fa4ba1ae878cd27287865fa12115f8a6c1175a2dfd1011d5f8aca11e46e669c7"}
|
||||
{"path":"packages/business/src/business.mjs","sha256":"aaa4578fd4133f64119de6c8786a14759240a8910677529fdeae57173058b7d9"}
|
||||
{"path":"packages/business/src/errors.mjs","sha256":"cd4eb5960c17ce32f26d1a49196866ce04efc42c1d90b18b046af5fda8b9ff0a"}
|
||||
{"path":"packages/business/src/launch.mjs","sha256":"0aa94dbd14acd379a4837cc3e70b9618b3fa797d74124314e7245a8a3070e98c"}
|
||||
{"path":"packages/business/src/util.mjs","sha256":"e1f0e70a4bbba8ae2ad6185ab61770b15acda403e90fc708e13027a1e9ec663c"}
|
||||
{"path":"packages/business/src/vars.mjs","sha256":"f6b15ee8dad2d985c0ae66b1f106ca46cb56ec86ac8cd5dec8a05c887596a421"}
|
||||
{"path":"packages/business/src/credentials.mjs","sha256":"c3422b1e144177f9dd3015ac036ee1d2cde02bd2b3be406364f3b3f45d8c9b73"}
|
||||
{"path":"packages/business/src/role.mjs","sha256":"b10af84d7422da4d0e8c0a4fea1064eebbc2fac6a838a1b3939b554e22dedfc9"}
|
||||
{"path":"packages/business/src/resolve.mjs","sha256":"712183465fee099606223d84423afc54e3386a0c8e468c68d5ac39c1e676d109"}
|
||||
{"path":"packages/business/src/project.mjs","sha256":"9472996134c520c31971e66006d1c1683709f6df4f76fe3445bdc97a18637eff"}
|
||||
{"path":"packages/seat/src/session.mjs","sha256":"c37a6ef6f6d2b4e61443e77d800656bf31e38913bf7dbdc4ca955f4a83b13a41"}
|
||||
{"path":"packages/seat/src/proc.mjs","sha256":"382cbf7e0ff336911e288ce858bdbfbec693bc2b69879720d1f0b4c7d8455198"}
|
||||
{"path":"packages/seat/src/sandbox.mjs","sha256":"0868f393f6fb117d430428ec390e435359737eae0792b4a4d1f54797c7a6c1bf"}
|
||||
{"path":"packages/seat/src/seat.mjs","sha256":"eec970961a667c9e614d1474d33c31a019b2cf1b0bf931a51458d874bca13a15"}
|
||||
{"path":"packages/seat/src/compactions.mjs","sha256":"c5de99284b8fa61763b8dd30a58809bbc086529eeb10587586d52b0df2754774"}
|
||||
{"path":"packages/seat/src/working.mjs","sha256":"621f5c223811444336f0f5d6ad10bc7afce075491653c0527d6c26ca568b79c3"}
|
||||
{"path":"packages/plugins/src/loader.mjs","sha256":"2e99f9222424cf9503253701568f0bb5ef579a22930f9f224e5b63ad6b4f745f"}
|
||||
{"path":"packages/business/src/plugin-settings.mjs","sha256":"9d2c68dd21c6c9553af75f4b137c4f169e95761f32528767e0518d0313311f50"}
|
||||
{"path":"packages/model-proxy/src/client.mjs","sha256":"f5f86cad661034f223a76352d877fa8d7883bfa921a7a01282347a9a03272441"}
|
||||
{"path":"packages/model-proxy/src/common.mjs","sha256":"a6fb88352018b8f21593a0bb9311f87162c80d8b1e05e62b4d43b1e69af21b23"}
|
||||
{"path":"packages/bus/src/proxy-page.mjs","sha256":"af36aae674f46a4e5eacfe176fde8b58cd0b171a6d70e07ee6d479e0f558cce7"}
|
||||
{"path":"packages/model-proxy/src/settings.mjs","sha256":"1eac4b5741b360a077bb1c871c008b64f7c7119afc64be4d6e4a0dcdb3a313bb"}
|
||||
{"path":"packages/bus/src/model-keys.mjs","sha256":"b4e11975bd56db4c816ada297902f033b3db7754d4a05319f03d640e17374550"}
|
||||
{"path":"packages/business/src/instance-settings.mjs","sha256":"09f2bde85a6d7a8f0b1d1c60ac589b845b0c95e991b2f807758878416b13c6bd"}
|
||||
{"path":"packages/bus/src/credential-verbs.mjs","sha256":"86b4321dd436b97e389101873197dbab95b3d2202e5ef7da712c4978f4f9159f"}
|
||||
{"path":"packages/bus/src/business.mjs","sha256":"ff927da3cf22fbacc9ace77b2e8b803bffc2953fb58cf7ab4e5f6f6493732996"}
|
||||
{"path":"packages/bus/src/web.mjs","sha256":"68efa3c9d0a72095f503208ed5c2e660ef9bca68d3ea15f0fc2f1826a68e09cc"}
|
||||
{"path":"packages/discord/src/web.mjs","sha256":"e5a7b64720872b12b34223549537ace05ebf0ca8a29b2f844d2b7c5cc9ea41f7"}
|
||||
{"path":"packages/bus/src/host-run.mjs","sha256":"324c05b16253e0fcfc1a0299d1d8ab45850ea723fad1f67bcc07fc031f50d593"}
|
||||
{"path":"packages/bus/src/host-grant.mjs","sha256":"48337cdbc41d503f17962d3e3ad014183b1286165f97da6fd88b4faa50be3949"}
|
||||
{"path":"packages/business/src/hosts.mjs","sha256":"e08b11b70b54f13e3b18996dd903f841e04fd6c64791e96063df8b164c663882"}
|
||||
{"path":"packages/bus/src/gitea-grant.mjs","sha256":"27d7d5322c2f12641e350867d3ac6f838b33832951e69f057e3a7a28b8ac4d5b"}
|
||||
{"path":"packages/bus/src/principal.mjs","sha256":"2b1e18be825e8264b16506d6294863acbba812956cfdf8e056f21faaa94f7137"}
|
||||
{"path":"packages/bus/src/human.mjs","sha256":"bb13c146717cdc46d75d157177e400edac4d3e10f14fe511027a25fd44cec885"}
|
||||
{"path":"packages/bus/src/tester.mjs","sha256":"5e9e08ca8069e1de35232f26d48a77792388128dda659893909f2d34b5af2346"}
|
||||
{"path":"packages/business/src/access.mjs","sha256":"af028c999a6ab4d42b321c3f047e683b226c7ad232a2ae9cfc623b7dd5a4dd5f"}
|
||||
{"path":"packages/bus/src/usage.mjs","sha256":"4ae57d053c4b217e1c1a22ada3ed1c5d4a3f0e61b8d2798e9db37997cd071a29"}
|
||||
{"path":"packages/bus/src/proxy-usage.mjs","sha256":"5a6c3707e6a64304cfd37f1875eb378c6eb58bf438cc40365fe913eaec7cee59"}
|
||||
{"path":"packages/bus/src/limits.mjs","sha256":"18c1aacd280ebf0f200d5e6fc1dd1a7e098a3046c1cb8427140bb2198ac81cd3"}
|
||||
{"path":"packages/processing-control/src/coordinator.mjs","sha256":"ddc7318297abc4ec4dd03d425820b7323db609e554cfc5341cfdfa6934271e73"}
|
||||
{"path":"packages/discord/src/processing.mjs","sha256":"8fa9968862dff77fa6d8be5210c22d13712fd622a8cbc722d167be5be80d0783"}
|
||||
{"path":"packages/discord/src/binding.mjs","sha256":"5ab69c4111dd9589a197172ffe6968bf414f41c552b7910e5478a27c446cfaec"}
|
||||
{"path":"packages/discord/src/setspark.mjs","sha256":"ba09d286e707860afa53300f8802ac8e6193ab2d2e7abe9d2b07cbdef3822387"}
|
||||
{"path":"packages/discord/src/errors.mjs","sha256":"917b0e6c4f100e93f056b925e38d97eacdd8b2596e39fbd3f88c0b62b973d8ed"}
|
||||
{"path":"packages/discord/src/tools.mjs","sha256":"975503616245bb6051f06ecbf47436ce7d030f21af23042df7f3341062df967f"}
|
||||
{"path":"packages/discord/src/git.mjs","sha256":"c28e04a0055997ea0b34bea1ad2912adb248d5fd43713df1e6f5a661d87949b7"}
|
||||
{"path":"packages/discord/src/journal.mjs","sha256":"12684e926574c3fe7f693a03b60d1393df483f5feb4b47c9dd7c5a7ac050aec5"}
|
||||
{"path":"packages/processing-control/src/containers.mjs","sha256":"781973277c09133de15fc39be35b372a79066479097d46923c8ab7782f011dcd"}
|
||||
{"path":"packages/project/schemas/project.schema.json","sha256":"f069c012e9660d5d0491a21f98e936b725f6818e1c3136dfec61b3c800bd58de"}
|
||||
{"path":"packages/project/schemas/requirement.schema.json","sha256":"79a1e7b567af7162bb88ca69861075fc579a858e8aec4e49824ccdc370b690c3"}
|
||||
{"path":"packages/project/schemas/decision.schema.json","sha256":"925bb03ac99e5845e4bfa20b4561a331f034f88e187db82213df6602a7ceee4b"}
|
||||
{"path":"packages/model-proxy/PIN","sha256":"889ac9589fadf7654d4dbb914f968cbafe4255ed215bd6a9ff3f331757c9017b"}
|
||||
{"path":"packages/business/tests/helpers.mjs","sha256":"a6a9971b42ddf176d9415caee3efc2eb16791dead5f0f0557d28449a550aefa1"}
|
||||
{"path":"packages/plugins/harness/claude-code/index.mjs","sha256":"a317ac544359d321bb91b67cd87fc6ef431b72df9ac9f7f2a9ff291ed1a9109a"}
|
||||
{"path":"packages/harness/src/gate.mjs","sha256":"a74ef2db4093c0c797ba9e7e28e4e4df0ceac9040385f00e60a273f39af9610b"}
|
||||
{"path":"packages/plugins/harness/pi/index.mjs","sha256":"39c225f157b8f66b416625bda689153505743ffcfdc32964bb1f3d2c6fcb73af"}
|
||||
{"path":"packages/plugins/harness/pi/compactions.mjs","sha256":"aabaf5c4602e28f025c18b2e2ddd6fa0d1648870101a5de0c4424d97b24472dd"}
|
||||
{"path":"packages/plugins/limit-check/daily-quota/index.mjs","sha256":"3749b9f6dd681ef424ee7d7e4d80ccee87b3655df8cd8fe9ccd0d505dcaaee9b"}
|
||||
{"path":"packages/tasks/requirements.json","sha256":"80b58323994d70e8bb496d81225aeb3d2cdfda464654b68b3b082e9af1fac5c1"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/bus/tests/limit-checks.test.mjs","sha256":"45870a4903d1996915c0086a6beb4d0a4c75b38386b7c5e6d98b5bc811c3b541"}
|
||||
{"path":"packages/bus/src/store.mjs","sha256":"dd7fce9706402efd1c5a5b81f7d0fa3793de203e7a6aef4e118e934aebdc7c84"}
|
||||
{"path":"packages/bus/src/limits.mjs","sha256":"18c1aacd280ebf0f200d5e6fc1dd1a7e098a3046c1cb8427140bb2198ac81cd3"}
|
||||
{"path":"packages/plugins/src/loader.mjs","sha256":"2e99f9222424cf9503253701568f0bb5ef579a22930f9f224e5b63ad6b4f745f"}
|
||||
{"path":"packages/plugins/src/kinds.mjs","sha256":"eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78"}
|
||||
{"path":"packages/bus/src/usage.mjs","sha256":"4ae57d053c4b217e1c1a22ada3ed1c5d4a3f0e61b8d2798e9db37997cd071a29"}
|
||||
{"path":"packages/plugins/tests/helpers.mjs","sha256":"5d5e5dccdae3f94b8540d187a8899ec36f9c9933cae3933249c2d8c400c75aa2"}
|
||||
{"path":"packages/bus/schema.sql","sha256":"a2ba3a46f12e56139ecae9e55227d00847842aedec50c1d92aaae28844ca48e7"}
|
||||
{"path":"packages/bus/src/migrations/3b.sql","sha256":"179ffe356d4ff19a49b5ebad39b6c6bfd7771deb8e1b7c55b5e746f039d69e65"}
|
||||
{"path":"packages/bus/src/migrations/3b-3c.sql","sha256":"b753f630301bf125e9e286b4156d0736930dd8fb9cd8eb2ebf316688f9191a07"}
|
||||
{"path":"packages/bus/src/migrations/3c-3d.sql","sha256":"0423832d05aa68f9191d7362827bd19310001165b895fb2de40b962fe68f9d56"}
|
||||
{"path":"packages/bus/src/migrations/3d-3e.sql","sha256":"d9aacc974d5047790e65c30a90068259bb9396dc92d4904eae3b9c5dbbb2f077"}
|
||||
{"path":"packages/bus/src/migrations/3e-3f.sql","sha256":"bf0b72c606b1a56a1610f09619b0c1118f1f300c636824ea13fd51a4ca6ac4b3"}
|
||||
{"path":"packages/bus/src/migrations/3f-3g.sql","sha256":"82f54b264919e34282bc214e34e9849f701cd3723b9b2f0a0d107c16f939dc05"}
|
||||
{"path":"packages/bus/src/migrations/3g-3h.sql","sha256":"76168e4f9f6b427286ddb8402fd833acadb01d6325a85f60e9ccf8d42fe2d1d0"}
|
||||
{"path":"packages/bus/src/migrations/3h-3i.sql","sha256":"e058e6cea8da7b6e649f3e03f2b81dc5444ee940a64274d0e367124c93545035"}
|
||||
{"path":"packages/bus/src/migrations/3i-3j.sql","sha256":"5ad122ca950e43e066f3d9ed215e73353e6b26de6687b961a8818d69c9465031"}
|
||||
{"path":"packages/bus/src/migrations/3j-3k.sql","sha256":"2e2bb1fe70076f5e24406a18a923b9e55c4192178a0a704a1b9716032676f9d4"}
|
||||
{"path":"packages/bus/src/migrations/3k-3l.sql","sha256":"eb2822c73e527697399691ae520092277ddbd4d2a9a42a0731b3c81cc3569e58"}
|
||||
{"path":"packages/bus/src/migrations/3l-3m.sql","sha256":"791879f06a3e97d3cfbe6112e2fb6502457af30b3e0198e3da1192038906d156"}
|
||||
{"path":"packages/bus/src/migrations/3m-3n.sql","sha256":"b40bc6a7bedc459d6827cbf0414619e48fc5dce2febdeff70a647345f2281c3a"}
|
||||
{"path":"packages/plugins/limit-check/token-limit/index.mjs","sha256":"4d0c6f5f87101f94608c02001a49d62cef113da48c539b2d2488dfbed1a4c524"}
|
||||
{"path":"packages/bus/src/runtime.mjs","sha256":"969d04eb06b97093c7f9f0dfa6b51084c781e967e2668814083bbba84a2af7b6"}
|
||||
{"path":"packages/bus/src/broker.mjs","sha256":"c0144adade79c2cfc6b8247721393f0250b1d64f6c6c04d85738cb80939c42e5"}
|
||||
{"path":"packages/bus/src/process.mjs","sha256":"ed13afdce6359df31d35a79496ebb4afdefef82030a8326a76b2a25b37e98d9d"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/bus/tests/limit-stop.test.mjs","sha256":"561d0950b788d08ad9a79ccd6572ad6976ba4b2e2b1c79d1e4d06827a84c131b"}
|
||||
{"path":"packages/bus/src/store.mjs","sha256":"dd7fce9706402efd1c5a5b81f7d0fa3793de203e7a6aef4e118e934aebdc7c84"}
|
||||
{"path":"packages/bus/src/broker.mjs","sha256":"c0144adade79c2cfc6b8247721393f0250b1d64f6c6c04d85738cb80939c42e5"}
|
||||
{"path":"packages/bus/src/proxy-page-vocabulary.mjs","sha256":"cec059ea4bef5ef62f6181123bfe64bca21d8985d5357471da8c0a3199a877f9"}
|
||||
{"path":"packages/model-proxy/src/validation.mjs","sha256":"e66453cf6662677cf28cbad1ae8f7509917d333e5b80404ab02c53f5cf75e9e1"}
|
||||
{"path":"packages/bus/src/address.mjs","sha256":"232a1c77c2f17011c53b55fc6052f70985598210769d41d7c2c0b535328aad23"}
|
||||
{"path":"packages/processing-control/src/state.mjs","sha256":"ed834770fed863cb0c15b75062de1fd63dea940f3b42020b769a7e62b319c8ed"}
|
||||
{"path":"packages/plugins/src/kinds.mjs","sha256":"eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78"}
|
||||
{"path":"packages/tasks/src/requirements.mjs","sha256":"38e7b85650247759f06c09fce205b2970b8368bc81491f51dc6b3c90ba2a846d"}
|
||||
{"path":"packages/bus/src/landing.mjs","sha256":"9919febc7679168e0a72c0ef51983120283e595fea290a5e8e948409bf5c911b"}
|
||||
{"path":"packages/business/src/vocabulary.mjs","sha256":"de1f04628e400084a46e77fd7e03c7a039f0f80c9e07bb486c9c012f187aa3eb"}
|
||||
{"path":"packages/bus/schema.sql","sha256":"a2ba3a46f12e56139ecae9e55227d00847842aedec50c1d92aaae28844ca48e7"}
|
||||
{"path":"packages/bus/src/migrations/3b.sql","sha256":"179ffe356d4ff19a49b5ebad39b6c6bfd7771deb8e1b7c55b5e746f039d69e65"}
|
||||
{"path":"packages/bus/src/migrations/3b-3c.sql","sha256":"b753f630301bf125e9e286b4156d0736930dd8fb9cd8eb2ebf316688f9191a07"}
|
||||
{"path":"packages/bus/src/migrations/3c-3d.sql","sha256":"0423832d05aa68f9191d7362827bd19310001165b895fb2de40b962fe68f9d56"}
|
||||
{"path":"packages/bus/src/migrations/3d-3e.sql","sha256":"d9aacc974d5047790e65c30a90068259bb9396dc92d4904eae3b9c5dbbb2f077"}
|
||||
{"path":"packages/bus/src/migrations/3e-3f.sql","sha256":"bf0b72c606b1a56a1610f09619b0c1118f1f300c636824ea13fd51a4ca6ac4b3"}
|
||||
{"path":"packages/bus/src/migrations/3f-3g.sql","sha256":"82f54b264919e34282bc214e34e9849f701cd3723b9b2f0a0d107c16f939dc05"}
|
||||
{"path":"packages/bus/src/migrations/3g-3h.sql","sha256":"76168e4f9f6b427286ddb8402fd833acadb01d6325a85f60e9ccf8d42fe2d1d0"}
|
||||
{"path":"packages/bus/src/migrations/3h-3i.sql","sha256":"e058e6cea8da7b6e649f3e03f2b81dc5444ee940a64274d0e367124c93545035"}
|
||||
{"path":"packages/bus/src/migrations/3i-3j.sql","sha256":"5ad122ca950e43e066f3d9ed215e73353e6b26de6687b961a8818d69c9465031"}
|
||||
{"path":"packages/bus/src/migrations/3j-3k.sql","sha256":"2e2bb1fe70076f5e24406a18a923b9e55c4192178a0a704a1b9716032676f9d4"}
|
||||
{"path":"packages/bus/src/migrations/3k-3l.sql","sha256":"eb2822c73e527697399691ae520092277ddbd4d2a9a42a0731b3c81cc3569e58"}
|
||||
{"path":"packages/bus/src/migrations/3l-3m.sql","sha256":"791879f06a3e97d3cfbe6112e2fb6502457af30b3e0198e3da1192038906d156"}
|
||||
{"path":"packages/bus/src/migrations/3m-3n.sql","sha256":"b40bc6a7bedc459d6827cbf0414619e48fc5dce2febdeff70a647345f2281c3a"}
|
||||
{"path":"roles/assistant.json","sha256":"5f63ff52aaccf06a0f2415ffdd9d1903c202679cf953bef5266a6841b5e39ab7"}
|
||||
{"path":"packages/tasks/requirements.json","sha256":"80b58323994d70e8bb496d81225aeb3d2cdfda464654b68b3b082e9af1fac5c1"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/bus/tests/limits-runtime.test.mjs","sha256":"a2e553025edbe6e930c9d03b48289c53b51b153ac9ae49bb21bf721b725f1913"}
|
||||
{"path":"packages/bus/src/runtime.mjs","sha256":"969d04eb06b97093c7f9f0dfa6b51084c781e967e2668814083bbba84a2af7b6"}
|
||||
{"path":"packages/bus/src/store.mjs","sha256":"dd7fce9706402efd1c5a5b81f7d0fa3793de203e7a6aef4e118e934aebdc7c84"}
|
||||
{"path":"packages/project/src/index.mjs","sha256":"3ab38cc40ce9ed1a714a59a1f2c336c3792a59431a6a9cc655ba6a2f47513899"}
|
||||
{"path":"packages/project/src/paths.mjs","sha256":"bd9debcf3f9bb92560e74f220a0b108dfe24154bc6d1fb03c5ec414356d451f9"}
|
||||
{"path":"packages/project/src/git.mjs","sha256":"af6865a4cace92ef27910098507ffedfc8dfe768cea088b1fee21d0876cc556e"}
|
||||
{"path":"packages/seat/src/checkout.mjs","sha256":"5aca02491fe8df51487968ce62c776d493d0fe693cc41478b84bef7b49c8948d"}
|
||||
{"path":"packages/processing-control/src/effects.mjs","sha256":"3bc600649267f011e21ed8266fb16927b0ad3a0e2c49e4b54062d34c544d0c17"}
|
||||
{"path":"packages/processing-control/src/state.mjs","sha256":"ed834770fed863cb0c15b75062de1fd63dea940f3b42020b769a7e62b319c8ed"}
|
||||
{"path":"packages/processing-control/src/runtimes.mjs","sha256":"7145420aa354180689a5c84423928fc60c8123476dcfed3364c9cf4542f8c7ea"}
|
||||
{"path":"packages/project/src/validate.mjs","sha256":"e49ab5e825f0706da2f3c8dfcf33c1331a38d77ca2d35b03359ee68ea74652c5"}
|
||||
{"path":"packages/project/src/read.mjs","sha256":"42113cd20eb8f04dd252f9963a6f1a84806af9cae7beb6808c4d584a2548220c"}
|
||||
{"path":"packages/library/src/index.mjs","sha256":"98c2c2877549c3e2c5963ec4e49d99ab3b6d6ad54fb3bfae86cf98542207157e"}
|
||||
{"path":"packages/library/src/problems.mjs","sha256":"0c8764b03dae0150c56af74bcb113cf583dcbe1fa0c6f7386ef2d48d59a6bd31"}
|
||||
{"path":"packages/library/src/mapping.mjs","sha256":"c83c626c7cdc2a00ba4217c34b889ca0517cd2022d1f8fc9e7d3a14a0293a802"}
|
||||
{"path":"packages/library/src/scope.mjs","sha256":"97e12255f52ad638eeacd152eb26822f9a2aa72cd30e2fed1193f51cd6e56192"}
|
||||
{"path":"packages/library/src/supporting.mjs","sha256":"6a3b4de2070e62b1cca1c0ab20f2883d3153fc61608d1bf7670cecea08765b4c"}
|
||||
{"path":"packages/library/src/links.mjs","sha256":"def32a176cb70c86248e45908edde22f9c4c5f88575a4af0a396a05f617358bc"}
|
||||
{"path":"packages/library/src/reader.mjs","sha256":"ea126533afb7e74b71419eb943febb6b242eb96fc6917d9df1019db3e7e6ce8d"}
|
||||
{"path":"packages/library/src/render.mjs","sha256":"bfc3de029d3c8f0dcc96c90fde30d6da58bbb5b72d8f13e3f536c0d735c73ca5"}
|
||||
{"path":"packages/library/src/survey.mjs","sha256":"016bfa5c80572c0baf90ced39cb3d3ec66d395f0be15c2727b9552a9dd849093"}
|
||||
{"path":"packages/library/src/mirror.mjs","sha256":"26b824d6885e5c6d1b8bd71e754a9fa333c26307693f7e6a0c6a8e6300ecb4ae"}
|
||||
{"path":"packages/library/src/sync.mjs","sha256":"a58f3aec5ed9b3530b363e2fdbd38bc9ded7635d261ab2fca3cb31c45dcd3dfa"}
|
||||
{"path":"packages/library/src/index-build.mjs","sha256":"70c1fe75cb2149c9a074d55a6301d5b66157c2dc2e777b92bac338cce09d89c7"}
|
||||
{"path":"packages/library/src/query.mjs","sha256":"bafe113bee70f17bd249876d6bdd1c08fa051223c2111955e5d5f275bd76bba0"}
|
||||
{"path":"packages/library/src/limits.mjs","sha256":"98ef45ed61144aaea44d8aea1ac43082b6d340297e46846d01772da38728e530"}
|
||||
{"path":"packages/library/src/guard.mjs","sha256":"f710d9600a17f6e2989a289cfe84e58f161d86c7306605946ce05fa71b364eb2"}
|
||||
{"path":"packages/library/src/reply-protocol.mjs","sha256":"7b46f47b5e9d6b554b5d39bce2cd95c4610f5f35b8ab8fdc5a2864b3214be809"}
|
||||
{"path":"packages/library/src/write.mjs","sha256":"a301b7c7e3f42f66cb69d88991220f4e236f25a6e5951c61e79ec4ef2b714198"}
|
||||
{"path":"packages/business/src/vocabulary.mjs","sha256":"de1f04628e400084a46e77fd7e03c7a039f0f80c9e07bb486c9c012f187aa3eb"}
|
||||
{"path":"packages/bus/src/broker.mjs","sha256":"c0144adade79c2cfc6b8247721393f0250b1d64f6c6c04d85738cb80939c42e5"}
|
||||
{"path":"packages/bus/src/proxy-page-vocabulary.mjs","sha256":"cec059ea4bef5ef62f6181123bfe64bca21d8985d5357471da8c0a3199a877f9"}
|
||||
{"path":"packages/model-proxy/src/validation.mjs","sha256":"e66453cf6662677cf28cbad1ae8f7509917d333e5b80404ab02c53f5cf75e9e1"}
|
||||
{"path":"packages/bus/src/address.mjs","sha256":"232a1c77c2f17011c53b55fc6052f70985598210769d41d7c2c0b535328aad23"}
|
||||
{"path":"packages/plugins/src/kinds.mjs","sha256":"eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78"}
|
||||
{"path":"packages/tasks/src/requirements.mjs","sha256":"38e7b85650247759f06c09fce205b2970b8368bc81491f51dc6b3c90ba2a846d"}
|
||||
{"path":"packages/bus/src/landing.mjs","sha256":"9919febc7679168e0a72c0ef51983120283e595fea290a5e8e948409bf5c911b"}
|
||||
{"path":"packages/bus/src/credentials.mjs","sha256":"10485afcf94c29ac9f3d5ba30b12248a2379efd69185ff9fb90e9fed25fe0678"}
|
||||
{"path":"packages/bus/src/server.mjs","sha256":"8318bed9168ac3f58c09de40a139b68aacefd684e6c117406e181e2ca5ab4ec7"}
|
||||
{"path":"packages/bus/src/interpreter.mjs","sha256":"56bfc8dcba476886d7de61a1e798aae8e3041c2434c62d44fc40a168d22bb3bd"}
|
||||
{"path":"packages/bus/src/peercred.mjs","sha256":"29c88655e8b9aed8db604573c9213fd9f3c40ef35ff04f4eda8fbe8f1b8a32d7"}
|
||||
{"path":"packages/business/src/launch-settings.mjs","sha256":"e14d73f719664499d809909962a6ecc16d4ffb9d824fcdee699e0778809d9e96"}
|
||||
{"path":"packages/business/src/organization.mjs","sha256":"fa4ba1ae878cd27287865fa12115f8a6c1175a2dfd1011d5f8aca11e46e669c7"}
|
||||
{"path":"packages/business/src/business.mjs","sha256":"aaa4578fd4133f64119de6c8786a14759240a8910677529fdeae57173058b7d9"}
|
||||
{"path":"packages/business/src/errors.mjs","sha256":"cd4eb5960c17ce32f26d1a49196866ce04efc42c1d90b18b046af5fda8b9ff0a"}
|
||||
{"path":"packages/business/src/launch.mjs","sha256":"0aa94dbd14acd379a4837cc3e70b9618b3fa797d74124314e7245a8a3070e98c"}
|
||||
{"path":"packages/business/src/util.mjs","sha256":"e1f0e70a4bbba8ae2ad6185ab61770b15acda403e90fc708e13027a1e9ec663c"}
|
||||
{"path":"packages/business/src/vars.mjs","sha256":"f6b15ee8dad2d985c0ae66b1f106ca46cb56ec86ac8cd5dec8a05c887596a421"}
|
||||
{"path":"packages/business/src/credentials.mjs","sha256":"c3422b1e144177f9dd3015ac036ee1d2cde02bd2b3be406364f3b3f45d8c9b73"}
|
||||
{"path":"packages/business/src/role.mjs","sha256":"b10af84d7422da4d0e8c0a4fea1064eebbc2fac6a838a1b3939b554e22dedfc9"}
|
||||
{"path":"packages/business/src/resolve.mjs","sha256":"712183465fee099606223d84423afc54e3386a0c8e468c68d5ac39c1e676d109"}
|
||||
{"path":"packages/business/src/project.mjs","sha256":"9472996134c520c31971e66006d1c1683709f6df4f76fe3445bdc97a18637eff"}
|
||||
{"path":"packages/seat/src/session.mjs","sha256":"c37a6ef6f6d2b4e61443e77d800656bf31e38913bf7dbdc4ca955f4a83b13a41"}
|
||||
{"path":"packages/seat/src/proc.mjs","sha256":"382cbf7e0ff336911e288ce858bdbfbec693bc2b69879720d1f0b4c7d8455198"}
|
||||
{"path":"packages/seat/src/sandbox.mjs","sha256":"0868f393f6fb117d430428ec390e435359737eae0792b4a4d1f54797c7a6c1bf"}
|
||||
{"path":"packages/seat/src/seat.mjs","sha256":"eec970961a667c9e614d1474d33c31a019b2cf1b0bf931a51458d874bca13a15"}
|
||||
{"path":"packages/seat/src/compactions.mjs","sha256":"c5de99284b8fa61763b8dd30a58809bbc086529eeb10587586d52b0df2754774"}
|
||||
{"path":"packages/seat/src/working.mjs","sha256":"621f5c223811444336f0f5d6ad10bc7afce075491653c0527d6c26ca568b79c3"}
|
||||
{"path":"packages/plugins/src/loader.mjs","sha256":"2e99f9222424cf9503253701568f0bb5ef579a22930f9f224e5b63ad6b4f745f"}
|
||||
{"path":"packages/business/src/plugin-settings.mjs","sha256":"9d2c68dd21c6c9553af75f4b137c4f169e95761f32528767e0518d0313311f50"}
|
||||
{"path":"packages/model-proxy/src/client.mjs","sha256":"f5f86cad661034f223a76352d877fa8d7883bfa921a7a01282347a9a03272441"}
|
||||
{"path":"packages/model-proxy/src/common.mjs","sha256":"a6fb88352018b8f21593a0bb9311f87162c80d8b1e05e62b4d43b1e69af21b23"}
|
||||
{"path":"packages/bus/src/proxy-page.mjs","sha256":"af36aae674f46a4e5eacfe176fde8b58cd0b171a6d70e07ee6d479e0f558cce7"}
|
||||
{"path":"packages/model-proxy/src/settings.mjs","sha256":"1eac4b5741b360a077bb1c871c008b64f7c7119afc64be4d6e4a0dcdb3a313bb"}
|
||||
{"path":"packages/bus/src/model-keys.mjs","sha256":"b4e11975bd56db4c816ada297902f033b3db7754d4a05319f03d640e17374550"}
|
||||
{"path":"packages/business/src/instance-settings.mjs","sha256":"09f2bde85a6d7a8f0b1d1c60ac589b845b0c95e991b2f807758878416b13c6bd"}
|
||||
{"path":"packages/bus/src/credential-verbs.mjs","sha256":"86b4321dd436b97e389101873197dbab95b3d2202e5ef7da712c4978f4f9159f"}
|
||||
{"path":"packages/bus/src/business.mjs","sha256":"ff927da3cf22fbacc9ace77b2e8b803bffc2953fb58cf7ab4e5f6f6493732996"}
|
||||
{"path":"packages/bus/src/web.mjs","sha256":"68efa3c9d0a72095f503208ed5c2e660ef9bca68d3ea15f0fc2f1826a68e09cc"}
|
||||
{"path":"packages/discord/src/web.mjs","sha256":"e5a7b64720872b12b34223549537ace05ebf0ca8a29b2f844d2b7c5cc9ea41f7"}
|
||||
{"path":"packages/bus/src/host-run.mjs","sha256":"324c05b16253e0fcfc1a0299d1d8ab45850ea723fad1f67bcc07fc031f50d593"}
|
||||
{"path":"packages/bus/src/host-grant.mjs","sha256":"48337cdbc41d503f17962d3e3ad014183b1286165f97da6fd88b4faa50be3949"}
|
||||
{"path":"packages/business/src/hosts.mjs","sha256":"e08b11b70b54f13e3b18996dd903f841e04fd6c64791e96063df8b164c663882"}
|
||||
{"path":"packages/bus/src/gitea-grant.mjs","sha256":"27d7d5322c2f12641e350867d3ac6f838b33832951e69f057e3a7a28b8ac4d5b"}
|
||||
{"path":"packages/bus/src/principal.mjs","sha256":"2b1e18be825e8264b16506d6294863acbba812956cfdf8e056f21faaa94f7137"}
|
||||
{"path":"packages/bus/src/human.mjs","sha256":"bb13c146717cdc46d75d157177e400edac4d3e10f14fe511027a25fd44cec885"}
|
||||
{"path":"packages/bus/src/tester.mjs","sha256":"5e9e08ca8069e1de35232f26d48a77792388128dda659893909f2d34b5af2346"}
|
||||
{"path":"packages/business/src/access.mjs","sha256":"af028c999a6ab4d42b321c3f047e683b226c7ad232a2ae9cfc623b7dd5a4dd5f"}
|
||||
{"path":"packages/bus/src/usage.mjs","sha256":"4ae57d053c4b217e1c1a22ada3ed1c5d4a3f0e61b8d2798e9db37997cd071a29"}
|
||||
{"path":"packages/bus/src/proxy-usage.mjs","sha256":"5a6c3707e6a64304cfd37f1875eb378c6eb58bf438cc40365fe913eaec7cee59"}
|
||||
{"path":"packages/bus/src/limits.mjs","sha256":"18c1aacd280ebf0f200d5e6fc1dd1a7e098a3046c1cb8427140bb2198ac81cd3"}
|
||||
{"path":"packages/processing-control/src/coordinator.mjs","sha256":"ddc7318297abc4ec4dd03d425820b7323db609e554cfc5341cfdfa6934271e73"}
|
||||
{"path":"packages/discord/src/processing.mjs","sha256":"8fa9968862dff77fa6d8be5210c22d13712fd622a8cbc722d167be5be80d0783"}
|
||||
{"path":"packages/discord/src/binding.mjs","sha256":"5ab69c4111dd9589a197172ffe6968bf414f41c552b7910e5478a27c446cfaec"}
|
||||
{"path":"packages/discord/src/setspark.mjs","sha256":"ba09d286e707860afa53300f8802ac8e6193ab2d2e7abe9d2b07cbdef3822387"}
|
||||
{"path":"packages/discord/src/errors.mjs","sha256":"917b0e6c4f100e93f056b925e38d97eacdd8b2596e39fbd3f88c0b62b973d8ed"}
|
||||
{"path":"packages/discord/src/tools.mjs","sha256":"975503616245bb6051f06ecbf47436ce7d030f21af23042df7f3341062df967f"}
|
||||
{"path":"packages/discord/src/git.mjs","sha256":"c28e04a0055997ea0b34bea1ad2912adb248d5fd43713df1e6f5a661d87949b7"}
|
||||
{"path":"packages/discord/src/journal.mjs","sha256":"12684e926574c3fe7f693a03b60d1393df483f5feb4b47c9dd7c5a7ac050aec5"}
|
||||
{"path":"packages/processing-control/src/containers.mjs","sha256":"781973277c09133de15fc39be35b372a79066479097d46923c8ab7782f011dcd"}
|
||||
{"path":"packages/bus/schema.sql","sha256":"a2ba3a46f12e56139ecae9e55227d00847842aedec50c1d92aaae28844ca48e7"}
|
||||
{"path":"packages/bus/src/migrations/3b.sql","sha256":"179ffe356d4ff19a49b5ebad39b6c6bfd7771deb8e1b7c55b5e746f039d69e65"}
|
||||
{"path":"packages/bus/src/migrations/3b-3c.sql","sha256":"b753f630301bf125e9e286b4156d0736930dd8fb9cd8eb2ebf316688f9191a07"}
|
||||
{"path":"packages/bus/src/migrations/3c-3d.sql","sha256":"0423832d05aa68f9191d7362827bd19310001165b895fb2de40b962fe68f9d56"}
|
||||
{"path":"packages/bus/src/migrations/3d-3e.sql","sha256":"d9aacc974d5047790e65c30a90068259bb9396dc92d4904eae3b9c5dbbb2f077"}
|
||||
{"path":"packages/bus/src/migrations/3e-3f.sql","sha256":"bf0b72c606b1a56a1610f09619b0c1118f1f300c636824ea13fd51a4ca6ac4b3"}
|
||||
{"path":"packages/bus/src/migrations/3f-3g.sql","sha256":"82f54b264919e34282bc214e34e9849f701cd3723b9b2f0a0d107c16f939dc05"}
|
||||
{"path":"packages/bus/src/migrations/3g-3h.sql","sha256":"76168e4f9f6b427286ddb8402fd833acadb01d6325a85f60e9ccf8d42fe2d1d0"}
|
||||
{"path":"packages/bus/src/migrations/3h-3i.sql","sha256":"e058e6cea8da7b6e649f3e03f2b81dc5444ee940a64274d0e367124c93545035"}
|
||||
{"path":"packages/bus/src/migrations/3i-3j.sql","sha256":"5ad122ca950e43e066f3d9ed215e73353e6b26de6687b961a8818d69c9465031"}
|
||||
{"path":"packages/bus/src/migrations/3j-3k.sql","sha256":"2e2bb1fe70076f5e24406a18a923b9e55c4192178a0a704a1b9716032676f9d4"}
|
||||
{"path":"packages/bus/src/migrations/3k-3l.sql","sha256":"eb2822c73e527697399691ae520092277ddbd4d2a9a42a0731b3c81cc3569e58"}
|
||||
{"path":"packages/bus/src/migrations/3l-3m.sql","sha256":"791879f06a3e97d3cfbe6112e2fb6502457af30b3e0198e3da1192038906d156"}
|
||||
{"path":"packages/bus/src/migrations/3m-3n.sql","sha256":"b40bc6a7bedc459d6827cbf0414619e48fc5dce2febdeff70a647345f2281c3a"}
|
||||
{"path":"packages/project/schemas/project.schema.json","sha256":"f069c012e9660d5d0491a21f98e936b725f6818e1c3136dfec61b3c800bd58de"}
|
||||
{"path":"packages/project/schemas/requirement.schema.json","sha256":"79a1e7b567af7162bb88ca69861075fc579a858e8aec4e49824ccdc370b690c3"}
|
||||
{"path":"packages/project/schemas/decision.schema.json","sha256":"925bb03ac99e5845e4bfa20b4561a331f034f88e187db82213df6602a7ceee4b"}
|
||||
{"path":"packages/model-proxy/PIN","sha256":"889ac9589fadf7654d4dbb914f968cbafe4255ed215bd6a9ff3f331757c9017b"}
|
||||
{"path":"packages/business/tests/helpers.mjs","sha256":"a6a9971b42ddf176d9415caee3efc2eb16791dead5f0f0557d28449a550aefa1"}
|
||||
{"path":"packages/plugins/harness/claude-code/index.mjs","sha256":"a317ac544359d321bb91b67cd87fc6ef431b72df9ac9f7f2a9ff291ed1a9109a"}
|
||||
{"path":"packages/harness/src/gate.mjs","sha256":"a74ef2db4093c0c797ba9e7e28e4e4df0ceac9040385f00e60a273f39af9610b"}
|
||||
{"path":"packages/plugins/harness/pi/index.mjs","sha256":"39c225f157b8f66b416625bda689153505743ffcfdc32964bb1f3d2c6fcb73af"}
|
||||
{"path":"packages/plugins/harness/pi/compactions.mjs","sha256":"aabaf5c4602e28f025c18b2e2ddd6fa0d1648870101a5de0c4424d97b24472dd"}
|
||||
{"path":"packages/plugins/limit-check/token-limit/index.mjs","sha256":"4d0c6f5f87101f94608c02001a49d62cef113da48c539b2d2488dfbed1a4c524"}
|
||||
{"path":"packages/tasks/requirements.json","sha256":"80b58323994d70e8bb496d81225aeb3d2cdfda464654b68b3b082e9af1fac5c1"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/bus/tests/p5-key-context.test.mjs","sha256":"e37114eab9c5f21015ea8e429f0574d3ea34b06263f1e42b83b31b8d2df222a7"}
|
||||
{"path":"packages/bus/src/store.mjs","sha256":"dd7fce9706402efd1c5a5b81f7d0fa3793de203e7a6aef4e118e934aebdc7c84"}
|
||||
{"path":"packages/bus/src/broker.mjs","sha256":"c0144adade79c2cfc6b8247721393f0250b1d64f6c6c04d85738cb80939c42e5"}
|
||||
{"path":"packages/bus/src/proxy-page-vocabulary.mjs","sha256":"cec059ea4bef5ef62f6181123bfe64bca21d8985d5357471da8c0a3199a877f9"}
|
||||
{"path":"packages/model-proxy/src/validation.mjs","sha256":"e66453cf6662677cf28cbad1ae8f7509917d333e5b80404ab02c53f5cf75e9e1"}
|
||||
{"path":"packages/bus/src/address.mjs","sha256":"232a1c77c2f17011c53b55fc6052f70985598210769d41d7c2c0b535328aad23"}
|
||||
{"path":"packages/processing-control/src/state.mjs","sha256":"ed834770fed863cb0c15b75062de1fd63dea940f3b42020b769a7e62b319c8ed"}
|
||||
{"path":"packages/plugins/src/kinds.mjs","sha256":"eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78"}
|
||||
{"path":"packages/tasks/src/requirements.mjs","sha256":"38e7b85650247759f06c09fce205b2970b8368bc81491f51dc6b3c90ba2a846d"}
|
||||
{"path":"packages/bus/src/landing.mjs","sha256":"9919febc7679168e0a72c0ef51983120283e595fea290a5e8e948409bf5c911b"}
|
||||
{"path":"packages/business/src/vocabulary.mjs","sha256":"de1f04628e400084a46e77fd7e03c7a039f0f80c9e07bb486c9c012f187aa3eb"}
|
||||
{"path":"packages/bus/src/limits.mjs","sha256":"18c1aacd280ebf0f200d5e6fc1dd1a7e098a3046c1cb8427140bb2198ac81cd3"}
|
||||
{"path":"packages/plugins/src/loader.mjs","sha256":"2e99f9222424cf9503253701568f0bb5ef579a22930f9f224e5b63ad6b4f745f"}
|
||||
{"path":"packages/bus/src/usage.mjs","sha256":"4ae57d053c4b217e1c1a22ada3ed1c5d4a3f0e61b8d2798e9db37997cd071a29"}
|
||||
{"path":"packages/bus/schema.sql","sha256":"a2ba3a46f12e56139ecae9e55227d00847842aedec50c1d92aaae28844ca48e7"}
|
||||
{"path":"packages/bus/src/migrations/3b.sql","sha256":"179ffe356d4ff19a49b5ebad39b6c6bfd7771deb8e1b7c55b5e746f039d69e65"}
|
||||
{"path":"packages/bus/src/migrations/3b-3c.sql","sha256":"b753f630301bf125e9e286b4156d0736930dd8fb9cd8eb2ebf316688f9191a07"}
|
||||
{"path":"packages/bus/src/migrations/3c-3d.sql","sha256":"0423832d05aa68f9191d7362827bd19310001165b895fb2de40b962fe68f9d56"}
|
||||
{"path":"packages/bus/src/migrations/3d-3e.sql","sha256":"d9aacc974d5047790e65c30a90068259bb9396dc92d4904eae3b9c5dbbb2f077"}
|
||||
{"path":"packages/bus/src/migrations/3e-3f.sql","sha256":"bf0b72c606b1a56a1610f09619b0c1118f1f300c636824ea13fd51a4ca6ac4b3"}
|
||||
{"path":"packages/bus/src/migrations/3f-3g.sql","sha256":"82f54b264919e34282bc214e34e9849f701cd3723b9b2f0a0d107c16f939dc05"}
|
||||
{"path":"packages/bus/src/migrations/3g-3h.sql","sha256":"76168e4f9f6b427286ddb8402fd833acadb01d6325a85f60e9ccf8d42fe2d1d0"}
|
||||
{"path":"packages/bus/src/migrations/3h-3i.sql","sha256":"e058e6cea8da7b6e649f3e03f2b81dc5444ee940a64274d0e367124c93545035"}
|
||||
{"path":"packages/bus/src/migrations/3i-3j.sql","sha256":"5ad122ca950e43e066f3d9ed215e73353e6b26de6687b961a8818d69c9465031"}
|
||||
{"path":"packages/bus/src/migrations/3j-3k.sql","sha256":"2e2bb1fe70076f5e24406a18a923b9e55c4192178a0a704a1b9716032676f9d4"}
|
||||
{"path":"packages/bus/src/migrations/3k-3l.sql","sha256":"eb2822c73e527697399691ae520092277ddbd4d2a9a42a0731b3c81cc3569e58"}
|
||||
{"path":"packages/bus/src/migrations/3l-3m.sql","sha256":"791879f06a3e97d3cfbe6112e2fb6502457af30b3e0198e3da1192038906d156"}
|
||||
{"path":"packages/bus/src/migrations/3m-3n.sql","sha256":"b40bc6a7bedc459d6827cbf0414619e48fc5dce2febdeff70a647345f2281c3a"}
|
||||
{"path":"packages/tasks/requirements.json","sha256":"80b58323994d70e8bb496d81225aeb3d2cdfda464654b68b3b082e9af1fac5c1"}
|
||||
{"path":"packages/plugins/limit-check/token-limit/index.mjs","sha256":"4d0c6f5f87101f94608c02001a49d62cef113da48c539b2d2488dfbed1a4c524"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/bus/tests/p5-runtime.test.mjs","sha256":"241e779016ffd0b54c5646cb4fac7e21ea1167e77afbd652ff4e01f8d238f99c"}
|
||||
{"path":"packages/bus/src/runtime.mjs","sha256":"969d04eb06b97093c7f9f0dfa6b51084c781e967e2668814083bbba84a2af7b6"}
|
||||
{"path":"packages/bus/src/store.mjs","sha256":"dd7fce9706402efd1c5a5b81f7d0fa3793de203e7a6aef4e118e934aebdc7c84"}
|
||||
{"path":"packages/project/src/index.mjs","sha256":"3ab38cc40ce9ed1a714a59a1f2c336c3792a59431a6a9cc655ba6a2f47513899"}
|
||||
{"path":"packages/project/src/paths.mjs","sha256":"bd9debcf3f9bb92560e74f220a0b108dfe24154bc6d1fb03c5ec414356d451f9"}
|
||||
{"path":"packages/project/src/git.mjs","sha256":"af6865a4cace92ef27910098507ffedfc8dfe768cea088b1fee21d0876cc556e"}
|
||||
{"path":"packages/seat/src/checkout.mjs","sha256":"5aca02491fe8df51487968ce62c776d493d0fe693cc41478b84bef7b49c8948d"}
|
||||
{"path":"packages/processing-control/src/effects.mjs","sha256":"3bc600649267f011e21ed8266fb16927b0ad3a0e2c49e4b54062d34c544d0c17"}
|
||||
{"path":"packages/processing-control/src/state.mjs","sha256":"ed834770fed863cb0c15b75062de1fd63dea940f3b42020b769a7e62b319c8ed"}
|
||||
{"path":"packages/processing-control/src/runtimes.mjs","sha256":"7145420aa354180689a5c84423928fc60c8123476dcfed3364c9cf4542f8c7ea"}
|
||||
{"path":"packages/project/src/validate.mjs","sha256":"e49ab5e825f0706da2f3c8dfcf33c1331a38d77ca2d35b03359ee68ea74652c5"}
|
||||
{"path":"packages/project/src/read.mjs","sha256":"42113cd20eb8f04dd252f9963a6f1a84806af9cae7beb6808c4d584a2548220c"}
|
||||
{"path":"packages/library/src/index.mjs","sha256":"98c2c2877549c3e2c5963ec4e49d99ab3b6d6ad54fb3bfae86cf98542207157e"}
|
||||
{"path":"packages/library/src/problems.mjs","sha256":"0c8764b03dae0150c56af74bcb113cf583dcbe1fa0c6f7386ef2d48d59a6bd31"}
|
||||
{"path":"packages/library/src/mapping.mjs","sha256":"c83c626c7cdc2a00ba4217c34b889ca0517cd2022d1f8fc9e7d3a14a0293a802"}
|
||||
{"path":"packages/library/src/scope.mjs","sha256":"97e12255f52ad638eeacd152eb26822f9a2aa72cd30e2fed1193f51cd6e56192"}
|
||||
{"path":"packages/library/src/supporting.mjs","sha256":"6a3b4de2070e62b1cca1c0ab20f2883d3153fc61608d1bf7670cecea08765b4c"}
|
||||
{"path":"packages/library/src/links.mjs","sha256":"def32a176cb70c86248e45908edde22f9c4c5f88575a4af0a396a05f617358bc"}
|
||||
{"path":"packages/library/src/reader.mjs","sha256":"ea126533afb7e74b71419eb943febb6b242eb96fc6917d9df1019db3e7e6ce8d"}
|
||||
{"path":"packages/library/src/render.mjs","sha256":"bfc3de029d3c8f0dcc96c90fde30d6da58bbb5b72d8f13e3f536c0d735c73ca5"}
|
||||
{"path":"packages/library/src/survey.mjs","sha256":"016bfa5c80572c0baf90ced39cb3d3ec66d395f0be15c2727b9552a9dd849093"}
|
||||
{"path":"packages/library/src/mirror.mjs","sha256":"26b824d6885e5c6d1b8bd71e754a9fa333c26307693f7e6a0c6a8e6300ecb4ae"}
|
||||
{"path":"packages/library/src/sync.mjs","sha256":"a58f3aec5ed9b3530b363e2fdbd38bc9ded7635d261ab2fca3cb31c45dcd3dfa"}
|
||||
{"path":"packages/library/src/index-build.mjs","sha256":"70c1fe75cb2149c9a074d55a6301d5b66157c2dc2e777b92bac338cce09d89c7"}
|
||||
{"path":"packages/library/src/query.mjs","sha256":"bafe113bee70f17bd249876d6bdd1c08fa051223c2111955e5d5f275bd76bba0"}
|
||||
{"path":"packages/library/src/limits.mjs","sha256":"98ef45ed61144aaea44d8aea1ac43082b6d340297e46846d01772da38728e530"}
|
||||
{"path":"packages/library/src/guard.mjs","sha256":"f710d9600a17f6e2989a289cfe84e58f161d86c7306605946ce05fa71b364eb2"}
|
||||
{"path":"packages/library/src/reply-protocol.mjs","sha256":"7b46f47b5e9d6b554b5d39bce2cd95c4610f5f35b8ab8fdc5a2864b3214be809"}
|
||||
{"path":"packages/library/src/write.mjs","sha256":"a301b7c7e3f42f66cb69d88991220f4e236f25a6e5951c61e79ec4ef2b714198"}
|
||||
{"path":"packages/business/src/vocabulary.mjs","sha256":"de1f04628e400084a46e77fd7e03c7a039f0f80c9e07bb486c9c012f187aa3eb"}
|
||||
{"path":"packages/bus/src/broker.mjs","sha256":"c0144adade79c2cfc6b8247721393f0250b1d64f6c6c04d85738cb80939c42e5"}
|
||||
{"path":"packages/bus/src/proxy-page-vocabulary.mjs","sha256":"cec059ea4bef5ef62f6181123bfe64bca21d8985d5357471da8c0a3199a877f9"}
|
||||
{"path":"packages/model-proxy/src/validation.mjs","sha256":"e66453cf6662677cf28cbad1ae8f7509917d333e5b80404ab02c53f5cf75e9e1"}
|
||||
{"path":"packages/bus/src/address.mjs","sha256":"232a1c77c2f17011c53b55fc6052f70985598210769d41d7c2c0b535328aad23"}
|
||||
{"path":"packages/plugins/src/kinds.mjs","sha256":"eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78"}
|
||||
{"path":"packages/tasks/src/requirements.mjs","sha256":"38e7b85650247759f06c09fce205b2970b8368bc81491f51dc6b3c90ba2a846d"}
|
||||
{"path":"packages/bus/src/landing.mjs","sha256":"9919febc7679168e0a72c0ef51983120283e595fea290a5e8e948409bf5c911b"}
|
||||
{"path":"packages/bus/src/credentials.mjs","sha256":"10485afcf94c29ac9f3d5ba30b12248a2379efd69185ff9fb90e9fed25fe0678"}
|
||||
{"path":"packages/bus/src/server.mjs","sha256":"8318bed9168ac3f58c09de40a139b68aacefd684e6c117406e181e2ca5ab4ec7"}
|
||||
{"path":"packages/bus/src/interpreter.mjs","sha256":"56bfc8dcba476886d7de61a1e798aae8e3041c2434c62d44fc40a168d22bb3bd"}
|
||||
{"path":"packages/bus/src/peercred.mjs","sha256":"29c88655e8b9aed8db604573c9213fd9f3c40ef35ff04f4eda8fbe8f1b8a32d7"}
|
||||
{"path":"packages/business/src/launch-settings.mjs","sha256":"e14d73f719664499d809909962a6ecc16d4ffb9d824fcdee699e0778809d9e96"}
|
||||
{"path":"packages/business/src/organization.mjs","sha256":"fa4ba1ae878cd27287865fa12115f8a6c1175a2dfd1011d5f8aca11e46e669c7"}
|
||||
{"path":"packages/business/src/business.mjs","sha256":"aaa4578fd4133f64119de6c8786a14759240a8910677529fdeae57173058b7d9"}
|
||||
{"path":"packages/business/src/errors.mjs","sha256":"cd4eb5960c17ce32f26d1a49196866ce04efc42c1d90b18b046af5fda8b9ff0a"}
|
||||
{"path":"packages/business/src/launch.mjs","sha256":"0aa94dbd14acd379a4837cc3e70b9618b3fa797d74124314e7245a8a3070e98c"}
|
||||
{"path":"packages/business/src/util.mjs","sha256":"e1f0e70a4bbba8ae2ad6185ab61770b15acda403e90fc708e13027a1e9ec663c"}
|
||||
{"path":"packages/business/src/vars.mjs","sha256":"f6b15ee8dad2d985c0ae66b1f106ca46cb56ec86ac8cd5dec8a05c887596a421"}
|
||||
{"path":"packages/business/src/credentials.mjs","sha256":"c3422b1e144177f9dd3015ac036ee1d2cde02bd2b3be406364f3b3f45d8c9b73"}
|
||||
{"path":"packages/business/src/role.mjs","sha256":"b10af84d7422da4d0e8c0a4fea1064eebbc2fac6a838a1b3939b554e22dedfc9"}
|
||||
{"path":"packages/business/src/resolve.mjs","sha256":"712183465fee099606223d84423afc54e3386a0c8e468c68d5ac39c1e676d109"}
|
||||
{"path":"packages/business/src/project.mjs","sha256":"9472996134c520c31971e66006d1c1683709f6df4f76fe3445bdc97a18637eff"}
|
||||
{"path":"packages/seat/src/session.mjs","sha256":"c37a6ef6f6d2b4e61443e77d800656bf31e38913bf7dbdc4ca955f4a83b13a41"}
|
||||
{"path":"packages/seat/src/proc.mjs","sha256":"382cbf7e0ff336911e288ce858bdbfbec693bc2b69879720d1f0b4c7d8455198"}
|
||||
{"path":"packages/seat/src/sandbox.mjs","sha256":"0868f393f6fb117d430428ec390e435359737eae0792b4a4d1f54797c7a6c1bf"}
|
||||
{"path":"packages/seat/src/seat.mjs","sha256":"eec970961a667c9e614d1474d33c31a019b2cf1b0bf931a51458d874bca13a15"}
|
||||
{"path":"packages/seat/src/compactions.mjs","sha256":"c5de99284b8fa61763b8dd30a58809bbc086529eeb10587586d52b0df2754774"}
|
||||
{"path":"packages/seat/src/working.mjs","sha256":"621f5c223811444336f0f5d6ad10bc7afce075491653c0527d6c26ca568b79c3"}
|
||||
{"path":"packages/plugins/src/loader.mjs","sha256":"2e99f9222424cf9503253701568f0bb5ef579a22930f9f224e5b63ad6b4f745f"}
|
||||
{"path":"packages/business/src/plugin-settings.mjs","sha256":"9d2c68dd21c6c9553af75f4b137c4f169e95761f32528767e0518d0313311f50"}
|
||||
{"path":"packages/model-proxy/src/client.mjs","sha256":"f5f86cad661034f223a76352d877fa8d7883bfa921a7a01282347a9a03272441"}
|
||||
{"path":"packages/model-proxy/src/common.mjs","sha256":"a6fb88352018b8f21593a0bb9311f87162c80d8b1e05e62b4d43b1e69af21b23"}
|
||||
{"path":"packages/bus/src/proxy-page.mjs","sha256":"af36aae674f46a4e5eacfe176fde8b58cd0b171a6d70e07ee6d479e0f558cce7"}
|
||||
{"path":"packages/model-proxy/src/settings.mjs","sha256":"1eac4b5741b360a077bb1c871c008b64f7c7119afc64be4d6e4a0dcdb3a313bb"}
|
||||
{"path":"packages/bus/src/model-keys.mjs","sha256":"b4e11975bd56db4c816ada297902f033b3db7754d4a05319f03d640e17374550"}
|
||||
{"path":"packages/business/src/instance-settings.mjs","sha256":"09f2bde85a6d7a8f0b1d1c60ac589b845b0c95e991b2f807758878416b13c6bd"}
|
||||
{"path":"packages/bus/src/credential-verbs.mjs","sha256":"86b4321dd436b97e389101873197dbab95b3d2202e5ef7da712c4978f4f9159f"}
|
||||
{"path":"packages/bus/src/business.mjs","sha256":"ff927da3cf22fbacc9ace77b2e8b803bffc2953fb58cf7ab4e5f6f6493732996"}
|
||||
{"path":"packages/bus/src/web.mjs","sha256":"68efa3c9d0a72095f503208ed5c2e660ef9bca68d3ea15f0fc2f1826a68e09cc"}
|
||||
{"path":"packages/discord/src/web.mjs","sha256":"e5a7b64720872b12b34223549537ace05ebf0ca8a29b2f844d2b7c5cc9ea41f7"}
|
||||
{"path":"packages/bus/src/host-run.mjs","sha256":"324c05b16253e0fcfc1a0299d1d8ab45850ea723fad1f67bcc07fc031f50d593"}
|
||||
{"path":"packages/bus/src/host-grant.mjs","sha256":"48337cdbc41d503f17962d3e3ad014183b1286165f97da6fd88b4faa50be3949"}
|
||||
{"path":"packages/business/src/hosts.mjs","sha256":"e08b11b70b54f13e3b18996dd903f841e04fd6c64791e96063df8b164c663882"}
|
||||
{"path":"packages/bus/src/gitea-grant.mjs","sha256":"27d7d5322c2f12641e350867d3ac6f838b33832951e69f057e3a7a28b8ac4d5b"}
|
||||
{"path":"packages/bus/src/principal.mjs","sha256":"2b1e18be825e8264b16506d6294863acbba812956cfdf8e056f21faaa94f7137"}
|
||||
{"path":"packages/bus/src/human.mjs","sha256":"bb13c146717cdc46d75d157177e400edac4d3e10f14fe511027a25fd44cec885"}
|
||||
{"path":"packages/bus/src/tester.mjs","sha256":"5e9e08ca8069e1de35232f26d48a77792388128dda659893909f2d34b5af2346"}
|
||||
{"path":"packages/business/src/access.mjs","sha256":"af028c999a6ab4d42b321c3f047e683b226c7ad232a2ae9cfc623b7dd5a4dd5f"}
|
||||
{"path":"packages/bus/src/usage.mjs","sha256":"4ae57d053c4b217e1c1a22ada3ed1c5d4a3f0e61b8d2798e9db37997cd071a29"}
|
||||
{"path":"packages/bus/src/proxy-usage.mjs","sha256":"5a6c3707e6a64304cfd37f1875eb378c6eb58bf438cc40365fe913eaec7cee59"}
|
||||
{"path":"packages/bus/src/limits.mjs","sha256":"18c1aacd280ebf0f200d5e6fc1dd1a7e098a3046c1cb8427140bb2198ac81cd3"}
|
||||
{"path":"packages/processing-control/src/coordinator.mjs","sha256":"ddc7318297abc4ec4dd03d425820b7323db609e554cfc5341cfdfa6934271e73"}
|
||||
{"path":"packages/discord/src/processing.mjs","sha256":"8fa9968862dff77fa6d8be5210c22d13712fd622a8cbc722d167be5be80d0783"}
|
||||
{"path":"packages/discord/src/binding.mjs","sha256":"5ab69c4111dd9589a197172ffe6968bf414f41c552b7910e5478a27c446cfaec"}
|
||||
{"path":"packages/discord/src/setspark.mjs","sha256":"ba09d286e707860afa53300f8802ac8e6193ab2d2e7abe9d2b07cbdef3822387"}
|
||||
{"path":"packages/discord/src/errors.mjs","sha256":"917b0e6c4f100e93f056b925e38d97eacdd8b2596e39fbd3f88c0b62b973d8ed"}
|
||||
{"path":"packages/discord/src/tools.mjs","sha256":"975503616245bb6051f06ecbf47436ce7d030f21af23042df7f3341062df967f"}
|
||||
{"path":"packages/discord/src/git.mjs","sha256":"c28e04a0055997ea0b34bea1ad2912adb248d5fd43713df1e6f5a661d87949b7"}
|
||||
{"path":"packages/discord/src/journal.mjs","sha256":"12684e926574c3fe7f693a03b60d1393df483f5feb4b47c9dd7c5a7ac050aec5"}
|
||||
{"path":"packages/processing-control/src/containers.mjs","sha256":"781973277c09133de15fc39be35b372a79066479097d46923c8ab7782f011dcd"}
|
||||
{"path":"packages/business/tests/helpers.mjs","sha256":"a6a9971b42ddf176d9415caee3efc2eb16791dead5f0f0557d28449a550aefa1"}
|
||||
{"path":"packages/bus/schema.sql","sha256":"a2ba3a46f12e56139ecae9e55227d00847842aedec50c1d92aaae28844ca48e7"}
|
||||
{"path":"packages/bus/src/migrations/3b.sql","sha256":"179ffe356d4ff19a49b5ebad39b6c6bfd7771deb8e1b7c55b5e746f039d69e65"}
|
||||
{"path":"packages/bus/src/migrations/3b-3c.sql","sha256":"b753f630301bf125e9e286b4156d0736930dd8fb9cd8eb2ebf316688f9191a07"}
|
||||
{"path":"packages/bus/src/migrations/3c-3d.sql","sha256":"0423832d05aa68f9191d7362827bd19310001165b895fb2de40b962fe68f9d56"}
|
||||
{"path":"packages/bus/src/migrations/3d-3e.sql","sha256":"d9aacc974d5047790e65c30a90068259bb9396dc92d4904eae3b9c5dbbb2f077"}
|
||||
{"path":"packages/bus/src/migrations/3e-3f.sql","sha256":"bf0b72c606b1a56a1610f09619b0c1118f1f300c636824ea13fd51a4ca6ac4b3"}
|
||||
{"path":"packages/bus/src/migrations/3f-3g.sql","sha256":"82f54b264919e34282bc214e34e9849f701cd3723b9b2f0a0d107c16f939dc05"}
|
||||
{"path":"packages/bus/src/migrations/3g-3h.sql","sha256":"76168e4f9f6b427286ddb8402fd833acadb01d6325a85f60e9ccf8d42fe2d1d0"}
|
||||
{"path":"packages/bus/src/migrations/3h-3i.sql","sha256":"e058e6cea8da7b6e649f3e03f2b81dc5444ee940a64274d0e367124c93545035"}
|
||||
{"path":"packages/bus/src/migrations/3i-3j.sql","sha256":"5ad122ca950e43e066f3d9ed215e73353e6b26de6687b961a8818d69c9465031"}
|
||||
{"path":"packages/bus/src/migrations/3j-3k.sql","sha256":"2e2bb1fe70076f5e24406a18a923b9e55c4192178a0a704a1b9716032676f9d4"}
|
||||
{"path":"packages/bus/src/migrations/3k-3l.sql","sha256":"eb2822c73e527697399691ae520092277ddbd4d2a9a42a0731b3c81cc3569e58"}
|
||||
{"path":"packages/bus/src/migrations/3l-3m.sql","sha256":"791879f06a3e97d3cfbe6112e2fb6502457af30b3e0198e3da1192038906d156"}
|
||||
{"path":"packages/bus/src/migrations/3m-3n.sql","sha256":"b40bc6a7bedc459d6827cbf0414619e48fc5dce2febdeff70a647345f2281c3a"}
|
||||
{"path":"packages/project/schemas/project.schema.json","sha256":"f069c012e9660d5d0491a21f98e936b725f6818e1c3136dfec61b3c800bd58de"}
|
||||
{"path":"packages/project/schemas/requirement.schema.json","sha256":"79a1e7b567af7162bb88ca69861075fc579a858e8aec4e49824ccdc370b690c3"}
|
||||
{"path":"packages/project/schemas/decision.schema.json","sha256":"925bb03ac99e5845e4bfa20b4561a331f034f88e187db82213df6602a7ceee4b"}
|
||||
{"path":"packages/model-proxy/PIN","sha256":"889ac9589fadf7654d4dbb914f968cbafe4255ed215bd6a9ff3f331757c9017b"}
|
||||
{"path":"packages/plugins/harness/claude-code/index.mjs","sha256":"a317ac544359d321bb91b67cd87fc6ef431b72df9ac9f7f2a9ff291ed1a9109a"}
|
||||
{"path":"packages/harness/src/gate.mjs","sha256":"a74ef2db4093c0c797ba9e7e28e4e4df0ceac9040385f00e60a273f39af9610b"}
|
||||
{"path":"packages/plugins/harness/pi/index.mjs","sha256":"39c225f157b8f66b416625bda689153505743ffcfdc32964bb1f3d2c6fcb73af"}
|
||||
{"path":"packages/plugins/harness/pi/compactions.mjs","sha256":"aabaf5c4602e28f025c18b2e2ddd6fa0d1648870101a5de0c4424d97b24472dd"}
|
||||
{"path":"packages/plugins/usage-source/transcript/index.mjs","sha256":"d09ae19db3eb69477783163559bd6a8e5b59a6f5af0eafd62d0e2e3bd325065e"}
|
||||
{"path":"packages/plugins/limit-check/daily-quota/index.mjs","sha256":"3749b9f6dd681ef424ee7d7e4d80ccee87b3655df8cd8fe9ccd0d505dcaaee9b"}
|
||||
{"path":"packages/tasks/requirements.json","sha256":"80b58323994d70e8bb496d81225aeb3d2cdfda464654b68b3b082e9af1fac5c1"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/bus/tests/plugins-verb.test.mjs","sha256":"895ffddbcca1b38fdaa17eefdeca9092a9b9a934d3a54a3bf7857f42fe99fba7"}
|
||||
{"path":"packages/bus/src/store.mjs","sha256":"dd7fce9706402efd1c5a5b81f7d0fa3793de203e7a6aef4e118e934aebdc7c84"}
|
||||
{"path":"packages/bus/src/broker.mjs","sha256":"c0144adade79c2cfc6b8247721393f0250b1d64f6c6c04d85738cb80939c42e5"}
|
||||
{"path":"packages/bus/src/proxy-page-vocabulary.mjs","sha256":"cec059ea4bef5ef62f6181123bfe64bca21d8985d5357471da8c0a3199a877f9"}
|
||||
{"path":"packages/model-proxy/src/validation.mjs","sha256":"e66453cf6662677cf28cbad1ae8f7509917d333e5b80404ab02c53f5cf75e9e1"}
|
||||
{"path":"packages/bus/src/address.mjs","sha256":"232a1c77c2f17011c53b55fc6052f70985598210769d41d7c2c0b535328aad23"}
|
||||
{"path":"packages/processing-control/src/state.mjs","sha256":"ed834770fed863cb0c15b75062de1fd63dea940f3b42020b769a7e62b319c8ed"}
|
||||
{"path":"packages/plugins/src/kinds.mjs","sha256":"eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78"}
|
||||
{"path":"packages/tasks/src/requirements.mjs","sha256":"38e7b85650247759f06c09fce205b2970b8368bc81491f51dc6b3c90ba2a846d"}
|
||||
{"path":"packages/bus/src/landing.mjs","sha256":"9919febc7679168e0a72c0ef51983120283e595fea290a5e8e948409bf5c911b"}
|
||||
{"path":"packages/business/src/vocabulary.mjs","sha256":"de1f04628e400084a46e77fd7e03c7a039f0f80c9e07bb486c9c012f187aa3eb"}
|
||||
{"path":"packages/bus/schema.sql","sha256":"a2ba3a46f12e56139ecae9e55227d00847842aedec50c1d92aaae28844ca48e7"}
|
||||
{"path":"packages/bus/src/migrations/3b.sql","sha256":"179ffe356d4ff19a49b5ebad39b6c6bfd7771deb8e1b7c55b5e746f039d69e65"}
|
||||
{"path":"packages/bus/src/migrations/3b-3c.sql","sha256":"b753f630301bf125e9e286b4156d0736930dd8fb9cd8eb2ebf316688f9191a07"}
|
||||
{"path":"packages/bus/src/migrations/3c-3d.sql","sha256":"0423832d05aa68f9191d7362827bd19310001165b895fb2de40b962fe68f9d56"}
|
||||
{"path":"packages/bus/src/migrations/3d-3e.sql","sha256":"d9aacc974d5047790e65c30a90068259bb9396dc92d4904eae3b9c5dbbb2f077"}
|
||||
{"path":"packages/bus/src/migrations/3e-3f.sql","sha256":"bf0b72c606b1a56a1610f09619b0c1118f1f300c636824ea13fd51a4ca6ac4b3"}
|
||||
{"path":"packages/bus/src/migrations/3f-3g.sql","sha256":"82f54b264919e34282bc214e34e9849f701cd3723b9b2f0a0d107c16f939dc05"}
|
||||
{"path":"packages/bus/src/migrations/3g-3h.sql","sha256":"76168e4f9f6b427286ddb8402fd833acadb01d6325a85f60e9ccf8d42fe2d1d0"}
|
||||
{"path":"packages/bus/src/migrations/3h-3i.sql","sha256":"e058e6cea8da7b6e649f3e03f2b81dc5444ee940a64274d0e367124c93545035"}
|
||||
{"path":"packages/bus/src/migrations/3i-3j.sql","sha256":"5ad122ca950e43e066f3d9ed215e73353e6b26de6687b961a8818d69c9465031"}
|
||||
{"path":"packages/bus/src/migrations/3j-3k.sql","sha256":"2e2bb1fe70076f5e24406a18a923b9e55c4192178a0a704a1b9716032676f9d4"}
|
||||
{"path":"packages/bus/src/migrations/3k-3l.sql","sha256":"eb2822c73e527697399691ae520092277ddbd4d2a9a42a0731b3c81cc3569e58"}
|
||||
{"path":"packages/bus/src/migrations/3l-3m.sql","sha256":"791879f06a3e97d3cfbe6112e2fb6502457af30b3e0198e3da1192038906d156"}
|
||||
{"path":"packages/bus/src/migrations/3m-3n.sql","sha256":"b40bc6a7bedc459d6827cbf0414619e48fc5dce2febdeff70a647345f2281c3a"}
|
||||
{"path":"packages/tasks/requirements.json","sha256":"80b58323994d70e8bb496d81225aeb3d2cdfda464654b68b3b082e9af1fac5c1"}
|
||||
{"path":"packages/bus/src/runtime.mjs","sha256":"969d04eb06b97093c7f9f0dfa6b51084c781e967e2668814083bbba84a2af7b6"}
|
||||
{"path":"packages/project/src/index.mjs","sha256":"3ab38cc40ce9ed1a714a59a1f2c336c3792a59431a6a9cc655ba6a2f47513899"}
|
||||
{"path":"packages/project/src/paths.mjs","sha256":"bd9debcf3f9bb92560e74f220a0b108dfe24154bc6d1fb03c5ec414356d451f9"}
|
||||
{"path":"packages/project/src/git.mjs","sha256":"af6865a4cace92ef27910098507ffedfc8dfe768cea088b1fee21d0876cc556e"}
|
||||
{"path":"packages/seat/src/checkout.mjs","sha256":"5aca02491fe8df51487968ce62c776d493d0fe693cc41478b84bef7b49c8948d"}
|
||||
{"path":"packages/processing-control/src/effects.mjs","sha256":"3bc600649267f011e21ed8266fb16927b0ad3a0e2c49e4b54062d34c544d0c17"}
|
||||
{"path":"packages/processing-control/src/runtimes.mjs","sha256":"7145420aa354180689a5c84423928fc60c8123476dcfed3364c9cf4542f8c7ea"}
|
||||
{"path":"packages/project/src/validate.mjs","sha256":"e49ab5e825f0706da2f3c8dfcf33c1331a38d77ca2d35b03359ee68ea74652c5"}
|
||||
{"path":"packages/project/src/read.mjs","sha256":"42113cd20eb8f04dd252f9963a6f1a84806af9cae7beb6808c4d584a2548220c"}
|
||||
{"path":"packages/library/src/index.mjs","sha256":"98c2c2877549c3e2c5963ec4e49d99ab3b6d6ad54fb3bfae86cf98542207157e"}
|
||||
{"path":"packages/library/src/problems.mjs","sha256":"0c8764b03dae0150c56af74bcb113cf583dcbe1fa0c6f7386ef2d48d59a6bd31"}
|
||||
{"path":"packages/library/src/mapping.mjs","sha256":"c83c626c7cdc2a00ba4217c34b889ca0517cd2022d1f8fc9e7d3a14a0293a802"}
|
||||
{"path":"packages/library/src/scope.mjs","sha256":"97e12255f52ad638eeacd152eb26822f9a2aa72cd30e2fed1193f51cd6e56192"}
|
||||
{"path":"packages/library/src/supporting.mjs","sha256":"6a3b4de2070e62b1cca1c0ab20f2883d3153fc61608d1bf7670cecea08765b4c"}
|
||||
{"path":"packages/library/src/links.mjs","sha256":"def32a176cb70c86248e45908edde22f9c4c5f88575a4af0a396a05f617358bc"}
|
||||
{"path":"packages/library/src/reader.mjs","sha256":"ea126533afb7e74b71419eb943febb6b242eb96fc6917d9df1019db3e7e6ce8d"}
|
||||
{"path":"packages/library/src/render.mjs","sha256":"bfc3de029d3c8f0dcc96c90fde30d6da58bbb5b72d8f13e3f536c0d735c73ca5"}
|
||||
{"path":"packages/library/src/survey.mjs","sha256":"016bfa5c80572c0baf90ced39cb3d3ec66d395f0be15c2727b9552a9dd849093"}
|
||||
{"path":"packages/library/src/mirror.mjs","sha256":"26b824d6885e5c6d1b8bd71e754a9fa333c26307693f7e6a0c6a8e6300ecb4ae"}
|
||||
{"path":"packages/library/src/sync.mjs","sha256":"a58f3aec5ed9b3530b363e2fdbd38bc9ded7635d261ab2fca3cb31c45dcd3dfa"}
|
||||
{"path":"packages/library/src/index-build.mjs","sha256":"70c1fe75cb2149c9a074d55a6301d5b66157c2dc2e777b92bac338cce09d89c7"}
|
||||
{"path":"packages/library/src/query.mjs","sha256":"bafe113bee70f17bd249876d6bdd1c08fa051223c2111955e5d5f275bd76bba0"}
|
||||
{"path":"packages/library/src/limits.mjs","sha256":"98ef45ed61144aaea44d8aea1ac43082b6d340297e46846d01772da38728e530"}
|
||||
{"path":"packages/library/src/guard.mjs","sha256":"f710d9600a17f6e2989a289cfe84e58f161d86c7306605946ce05fa71b364eb2"}
|
||||
{"path":"packages/library/src/reply-protocol.mjs","sha256":"7b46f47b5e9d6b554b5d39bce2cd95c4610f5f35b8ab8fdc5a2864b3214be809"}
|
||||
{"path":"packages/library/src/write.mjs","sha256":"a301b7c7e3f42f66cb69d88991220f4e236f25a6e5951c61e79ec4ef2b714198"}
|
||||
{"path":"packages/bus/src/credentials.mjs","sha256":"10485afcf94c29ac9f3d5ba30b12248a2379efd69185ff9fb90e9fed25fe0678"}
|
||||
{"path":"packages/bus/src/server.mjs","sha256":"8318bed9168ac3f58c09de40a139b68aacefd684e6c117406e181e2ca5ab4ec7"}
|
||||
{"path":"packages/bus/src/interpreter.mjs","sha256":"56bfc8dcba476886d7de61a1e798aae8e3041c2434c62d44fc40a168d22bb3bd"}
|
||||
{"path":"packages/bus/src/peercred.mjs","sha256":"29c88655e8b9aed8db604573c9213fd9f3c40ef35ff04f4eda8fbe8f1b8a32d7"}
|
||||
{"path":"packages/business/src/launch-settings.mjs","sha256":"e14d73f719664499d809909962a6ecc16d4ffb9d824fcdee699e0778809d9e96"}
|
||||
{"path":"packages/business/src/organization.mjs","sha256":"fa4ba1ae878cd27287865fa12115f8a6c1175a2dfd1011d5f8aca11e46e669c7"}
|
||||
{"path":"packages/business/src/business.mjs","sha256":"aaa4578fd4133f64119de6c8786a14759240a8910677529fdeae57173058b7d9"}
|
||||
{"path":"packages/business/src/errors.mjs","sha256":"cd4eb5960c17ce32f26d1a49196866ce04efc42c1d90b18b046af5fda8b9ff0a"}
|
||||
{"path":"packages/business/src/launch.mjs","sha256":"0aa94dbd14acd379a4837cc3e70b9618b3fa797d74124314e7245a8a3070e98c"}
|
||||
{"path":"packages/business/src/util.mjs","sha256":"e1f0e70a4bbba8ae2ad6185ab61770b15acda403e90fc708e13027a1e9ec663c"}
|
||||
{"path":"packages/business/src/vars.mjs","sha256":"f6b15ee8dad2d985c0ae66b1f106ca46cb56ec86ac8cd5dec8a05c887596a421"}
|
||||
{"path":"packages/business/src/credentials.mjs","sha256":"c3422b1e144177f9dd3015ac036ee1d2cde02bd2b3be406364f3b3f45d8c9b73"}
|
||||
{"path":"packages/business/src/role.mjs","sha256":"b10af84d7422da4d0e8c0a4fea1064eebbc2fac6a838a1b3939b554e22dedfc9"}
|
||||
{"path":"packages/business/src/resolve.mjs","sha256":"712183465fee099606223d84423afc54e3386a0c8e468c68d5ac39c1e676d109"}
|
||||
{"path":"packages/business/src/project.mjs","sha256":"9472996134c520c31971e66006d1c1683709f6df4f76fe3445bdc97a18637eff"}
|
||||
{"path":"packages/seat/src/session.mjs","sha256":"c37a6ef6f6d2b4e61443e77d800656bf31e38913bf7dbdc4ca955f4a83b13a41"}
|
||||
{"path":"packages/seat/src/proc.mjs","sha256":"382cbf7e0ff336911e288ce858bdbfbec693bc2b69879720d1f0b4c7d8455198"}
|
||||
{"path":"packages/seat/src/sandbox.mjs","sha256":"0868f393f6fb117d430428ec390e435359737eae0792b4a4d1f54797c7a6c1bf"}
|
||||
{"path":"packages/seat/src/seat.mjs","sha256":"eec970961a667c9e614d1474d33c31a019b2cf1b0bf931a51458d874bca13a15"}
|
||||
{"path":"packages/seat/src/compactions.mjs","sha256":"c5de99284b8fa61763b8dd30a58809bbc086529eeb10587586d52b0df2754774"}
|
||||
{"path":"packages/seat/src/working.mjs","sha256":"621f5c223811444336f0f5d6ad10bc7afce075491653c0527d6c26ca568b79c3"}
|
||||
{"path":"packages/plugins/src/loader.mjs","sha256":"2e99f9222424cf9503253701568f0bb5ef579a22930f9f224e5b63ad6b4f745f"}
|
||||
{"path":"packages/business/src/plugin-settings.mjs","sha256":"9d2c68dd21c6c9553af75f4b137c4f169e95761f32528767e0518d0313311f50"}
|
||||
{"path":"packages/model-proxy/src/client.mjs","sha256":"f5f86cad661034f223a76352d877fa8d7883bfa921a7a01282347a9a03272441"}
|
||||
{"path":"packages/model-proxy/src/common.mjs","sha256":"a6fb88352018b8f21593a0bb9311f87162c80d8b1e05e62b4d43b1e69af21b23"}
|
||||
{"path":"packages/bus/src/proxy-page.mjs","sha256":"af36aae674f46a4e5eacfe176fde8b58cd0b171a6d70e07ee6d479e0f558cce7"}
|
||||
{"path":"packages/model-proxy/src/settings.mjs","sha256":"1eac4b5741b360a077bb1c871c008b64f7c7119afc64be4d6e4a0dcdb3a313bb"}
|
||||
{"path":"packages/bus/src/model-keys.mjs","sha256":"b4e11975bd56db4c816ada297902f033b3db7754d4a05319f03d640e17374550"}
|
||||
{"path":"packages/business/src/instance-settings.mjs","sha256":"09f2bde85a6d7a8f0b1d1c60ac589b845b0c95e991b2f807758878416b13c6bd"}
|
||||
{"path":"packages/bus/src/credential-verbs.mjs","sha256":"86b4321dd436b97e389101873197dbab95b3d2202e5ef7da712c4978f4f9159f"}
|
||||
{"path":"packages/bus/src/business.mjs","sha256":"ff927da3cf22fbacc9ace77b2e8b803bffc2953fb58cf7ab4e5f6f6493732996"}
|
||||
{"path":"packages/bus/src/web.mjs","sha256":"68efa3c9d0a72095f503208ed5c2e660ef9bca68d3ea15f0fc2f1826a68e09cc"}
|
||||
{"path":"packages/discord/src/web.mjs","sha256":"e5a7b64720872b12b34223549537ace05ebf0ca8a29b2f844d2b7c5cc9ea41f7"}
|
||||
{"path":"packages/bus/src/host-run.mjs","sha256":"324c05b16253e0fcfc1a0299d1d8ab45850ea723fad1f67bcc07fc031f50d593"}
|
||||
{"path":"packages/bus/src/host-grant.mjs","sha256":"48337cdbc41d503f17962d3e3ad014183b1286165f97da6fd88b4faa50be3949"}
|
||||
{"path":"packages/business/src/hosts.mjs","sha256":"e08b11b70b54f13e3b18996dd903f841e04fd6c64791e96063df8b164c663882"}
|
||||
{"path":"packages/bus/src/gitea-grant.mjs","sha256":"27d7d5322c2f12641e350867d3ac6f838b33832951e69f057e3a7a28b8ac4d5b"}
|
||||
{"path":"packages/bus/src/principal.mjs","sha256":"2b1e18be825e8264b16506d6294863acbba812956cfdf8e056f21faaa94f7137"}
|
||||
{"path":"packages/bus/src/human.mjs","sha256":"bb13c146717cdc46d75d157177e400edac4d3e10f14fe511027a25fd44cec885"}
|
||||
{"path":"packages/bus/src/tester.mjs","sha256":"5e9e08ca8069e1de35232f26d48a77792388128dda659893909f2d34b5af2346"}
|
||||
{"path":"packages/business/src/access.mjs","sha256":"af028c999a6ab4d42b321c3f047e683b226c7ad232a2ae9cfc623b7dd5a4dd5f"}
|
||||
{"path":"packages/bus/src/usage.mjs","sha256":"4ae57d053c4b217e1c1a22ada3ed1c5d4a3f0e61b8d2798e9db37997cd071a29"}
|
||||
{"path":"packages/bus/src/proxy-usage.mjs","sha256":"5a6c3707e6a64304cfd37f1875eb378c6eb58bf438cc40365fe913eaec7cee59"}
|
||||
{"path":"packages/bus/src/limits.mjs","sha256":"18c1aacd280ebf0f200d5e6fc1dd1a7e098a3046c1cb8427140bb2198ac81cd3"}
|
||||
{"path":"packages/processing-control/src/coordinator.mjs","sha256":"ddc7318297abc4ec4dd03d425820b7323db609e554cfc5341cfdfa6934271e73"}
|
||||
{"path":"packages/discord/src/processing.mjs","sha256":"8fa9968862dff77fa6d8be5210c22d13712fd622a8cbc722d167be5be80d0783"}
|
||||
{"path":"packages/discord/src/binding.mjs","sha256":"5ab69c4111dd9589a197172ffe6968bf414f41c552b7910e5478a27c446cfaec"}
|
||||
{"path":"packages/discord/src/setspark.mjs","sha256":"ba09d286e707860afa53300f8802ac8e6193ab2d2e7abe9d2b07cbdef3822387"}
|
||||
{"path":"packages/discord/src/errors.mjs","sha256":"917b0e6c4f100e93f056b925e38d97eacdd8b2596e39fbd3f88c0b62b973d8ed"}
|
||||
{"path":"packages/discord/src/tools.mjs","sha256":"975503616245bb6051f06ecbf47436ce7d030f21af23042df7f3341062df967f"}
|
||||
{"path":"packages/discord/src/git.mjs","sha256":"c28e04a0055997ea0b34bea1ad2912adb248d5fd43713df1e6f5a661d87949b7"}
|
||||
{"path":"packages/discord/src/journal.mjs","sha256":"12684e926574c3fe7f693a03b60d1393df483f5feb4b47c9dd7c5a7ac050aec5"}
|
||||
{"path":"packages/processing-control/src/containers.mjs","sha256":"781973277c09133de15fc39be35b372a79066479097d46923c8ab7782f011dcd"}
|
||||
{"path":"packages/project/schemas/project.schema.json","sha256":"f069c012e9660d5d0491a21f98e936b725f6818e1c3136dfec61b3c800bd58de"}
|
||||
{"path":"packages/project/schemas/requirement.schema.json","sha256":"79a1e7b567af7162bb88ca69861075fc579a858e8aec4e49824ccdc370b690c3"}
|
||||
{"path":"packages/project/schemas/decision.schema.json","sha256":"925bb03ac99e5845e4bfa20b4561a331f034f88e187db82213df6602a7ceee4b"}
|
||||
{"path":"packages/model-proxy/PIN","sha256":"889ac9589fadf7654d4dbb914f968cbafe4255ed215bd6a9ff3f331757c9017b"}
|
||||
{"path":"packages/business/tests/helpers.mjs","sha256":"a6a9971b42ddf176d9415caee3efc2eb16791dead5f0f0557d28449a550aefa1"}
|
||||
{"path":"packages/plugins/harness/claude-code/index.mjs","sha256":"a317ac544359d321bb91b67cd87fc6ef431b72df9ac9f7f2a9ff291ed1a9109a"}
|
||||
{"path":"packages/harness/src/gate.mjs","sha256":"a74ef2db4093c0c797ba9e7e28e4e4df0ceac9040385f00e60a273f39af9610b"}
|
||||
{"path":"packages/plugins/harness/pi/index.mjs","sha256":"39c225f157b8f66b416625bda689153505743ffcfdc32964bb1f3d2c6fcb73af"}
|
||||
{"path":"packages/plugins/harness/pi/compactions.mjs","sha256":"aabaf5c4602e28f025c18b2e2ddd6fa0d1648870101a5de0c4424d97b24472dd"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/bus/tests/proxy-usage.test.mjs","sha256":"84c8351029272b6ee05e7fd81b4cc4453553ceeb7a5127a1333dae63d1336ad5"}
|
||||
{"path":"packages/bus/src/store.mjs","sha256":"dd7fce9706402efd1c5a5b81f7d0fa3793de203e7a6aef4e118e934aebdc7c84"}
|
||||
{"path":"packages/bus/src/usage.mjs","sha256":"4ae57d053c4b217e1c1a22ada3ed1c5d4a3f0e61b8d2798e9db37997cd071a29"}
|
||||
{"path":"packages/plugins/src/loader.mjs","sha256":"2e99f9222424cf9503253701568f0bb5ef579a22930f9f224e5b63ad6b4f745f"}
|
||||
{"path":"packages/plugins/src/kinds.mjs","sha256":"eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78"}
|
||||
{"path":"packages/bus/src/limits.mjs","sha256":"18c1aacd280ebf0f200d5e6fc1dd1a7e098a3046c1cb8427140bb2198ac81cd3"}
|
||||
{"path":"packages/bus/src/proxy-usage.mjs","sha256":"5a6c3707e6a64304cfd37f1875eb378c6eb58bf438cc40365fe913eaec7cee59"}
|
||||
{"path":"packages/model-proxy/src/client.mjs","sha256":"f5f86cad661034f223a76352d877fa8d7883bfa921a7a01282347a9a03272441"}
|
||||
{"path":"packages/model-proxy/src/common.mjs","sha256":"a6fb88352018b8f21593a0bb9311f87162c80d8b1e05e62b4d43b1e69af21b23"}
|
||||
{"path":"packages/model-proxy/src/validation.mjs","sha256":"e66453cf6662677cf28cbad1ae8f7509917d333e5b80404ab02c53f5cf75e9e1"}
|
||||
{"path":"packages/bus/schema.sql","sha256":"a2ba3a46f12e56139ecae9e55227d00847842aedec50c1d92aaae28844ca48e7"}
|
||||
{"path":"packages/bus/src/migrations/3b.sql","sha256":"179ffe356d4ff19a49b5ebad39b6c6bfd7771deb8e1b7c55b5e746f039d69e65"}
|
||||
{"path":"packages/bus/src/migrations/3b-3c.sql","sha256":"b753f630301bf125e9e286b4156d0736930dd8fb9cd8eb2ebf316688f9191a07"}
|
||||
{"path":"packages/bus/src/migrations/3c-3d.sql","sha256":"0423832d05aa68f9191d7362827bd19310001165b895fb2de40b962fe68f9d56"}
|
||||
{"path":"packages/bus/src/migrations/3d-3e.sql","sha256":"d9aacc974d5047790e65c30a90068259bb9396dc92d4904eae3b9c5dbbb2f077"}
|
||||
{"path":"packages/bus/src/migrations/3e-3f.sql","sha256":"bf0b72c606b1a56a1610f09619b0c1118f1f300c636824ea13fd51a4ca6ac4b3"}
|
||||
{"path":"packages/bus/src/migrations/3f-3g.sql","sha256":"82f54b264919e34282bc214e34e9849f701cd3723b9b2f0a0d107c16f939dc05"}
|
||||
{"path":"packages/bus/src/migrations/3g-3h.sql","sha256":"76168e4f9f6b427286ddb8402fd833acadb01d6325a85f60e9ccf8d42fe2d1d0"}
|
||||
{"path":"packages/bus/src/migrations/3h-3i.sql","sha256":"e058e6cea8da7b6e649f3e03f2b81dc5444ee940a64274d0e367124c93545035"}
|
||||
{"path":"packages/bus/src/migrations/3i-3j.sql","sha256":"5ad122ca950e43e066f3d9ed215e73353e6b26de6687b961a8818d69c9465031"}
|
||||
{"path":"packages/bus/src/migrations/3j-3k.sql","sha256":"2e2bb1fe70076f5e24406a18a923b9e55c4192178a0a704a1b9716032676f9d4"}
|
||||
{"path":"packages/bus/src/migrations/3k-3l.sql","sha256":"eb2822c73e527697399691ae520092277ddbd4d2a9a42a0731b3c81cc3569e58"}
|
||||
{"path":"packages/bus/src/migrations/3l-3m.sql","sha256":"791879f06a3e97d3cfbe6112e2fb6502457af30b3e0198e3da1192038906d156"}
|
||||
{"path":"packages/bus/src/migrations/3m-3n.sql","sha256":"b40bc6a7bedc459d6827cbf0414619e48fc5dce2febdeff70a647345f2281c3a"}
|
||||
{"path":"packages/model-proxy/PIN","sha256":"889ac9589fadf7654d4dbb914f968cbafe4255ed215bd6a9ff3f331757c9017b"}
|
||||
{"path":"packages/plugins/usage/cliproxy-queue/index.mjs","sha256":"6096a577cd5d7e8bf84fd6b98ab284e2f47d5facebd027548e07e6aeec442f96"}
|
||||
{"path":"packages/plugins/limit-check/token-limit/index.mjs","sha256":"4d0c6f5f87101f94608c02001a49d62cef113da48c539b2d2488dfbed1a4c524"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/bus/tests/usage-broker.test.mjs","sha256":"4b2149ea4219f49db19669ada9f88931f7691cdd73dd27dceec6e8fe1f76dd0c"}
|
||||
{"path":"packages/bus/src/store.mjs","sha256":"dd7fce9706402efd1c5a5b81f7d0fa3793de203e7a6aef4e118e934aebdc7c84"}
|
||||
{"path":"packages/bus/src/broker.mjs","sha256":"c0144adade79c2cfc6b8247721393f0250b1d64f6c6c04d85738cb80939c42e5"}
|
||||
{"path":"packages/bus/src/proxy-page-vocabulary.mjs","sha256":"cec059ea4bef5ef62f6181123bfe64bca21d8985d5357471da8c0a3199a877f9"}
|
||||
{"path":"packages/model-proxy/src/validation.mjs","sha256":"e66453cf6662677cf28cbad1ae8f7509917d333e5b80404ab02c53f5cf75e9e1"}
|
||||
{"path":"packages/bus/src/address.mjs","sha256":"232a1c77c2f17011c53b55fc6052f70985598210769d41d7c2c0b535328aad23"}
|
||||
{"path":"packages/processing-control/src/state.mjs","sha256":"ed834770fed863cb0c15b75062de1fd63dea940f3b42020b769a7e62b319c8ed"}
|
||||
{"path":"packages/plugins/src/kinds.mjs","sha256":"eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78"}
|
||||
{"path":"packages/tasks/src/requirements.mjs","sha256":"38e7b85650247759f06c09fce205b2970b8368bc81491f51dc6b3c90ba2a846d"}
|
||||
{"path":"packages/bus/src/landing.mjs","sha256":"9919febc7679168e0a72c0ef51983120283e595fea290a5e8e948409bf5c911b"}
|
||||
{"path":"packages/business/src/vocabulary.mjs","sha256":"de1f04628e400084a46e77fd7e03c7a039f0f80c9e07bb486c9c012f187aa3eb"}
|
||||
{"path":"packages/bus/schema.sql","sha256":"a2ba3a46f12e56139ecae9e55227d00847842aedec50c1d92aaae28844ca48e7"}
|
||||
{"path":"packages/bus/src/migrations/3b.sql","sha256":"179ffe356d4ff19a49b5ebad39b6c6bfd7771deb8e1b7c55b5e746f039d69e65"}
|
||||
{"path":"packages/bus/src/migrations/3b-3c.sql","sha256":"b753f630301bf125e9e286b4156d0736930dd8fb9cd8eb2ebf316688f9191a07"}
|
||||
{"path":"packages/bus/src/migrations/3c-3d.sql","sha256":"0423832d05aa68f9191d7362827bd19310001165b895fb2de40b962fe68f9d56"}
|
||||
{"path":"packages/bus/src/migrations/3d-3e.sql","sha256":"d9aacc974d5047790e65c30a90068259bb9396dc92d4904eae3b9c5dbbb2f077"}
|
||||
{"path":"packages/bus/src/migrations/3e-3f.sql","sha256":"bf0b72c606b1a56a1610f09619b0c1118f1f300c636824ea13fd51a4ca6ac4b3"}
|
||||
{"path":"packages/bus/src/migrations/3f-3g.sql","sha256":"82f54b264919e34282bc214e34e9849f701cd3723b9b2f0a0d107c16f939dc05"}
|
||||
{"path":"packages/bus/src/migrations/3g-3h.sql","sha256":"76168e4f9f6b427286ddb8402fd833acadb01d6325a85f60e9ccf8d42fe2d1d0"}
|
||||
{"path":"packages/bus/src/migrations/3h-3i.sql","sha256":"e058e6cea8da7b6e649f3e03f2b81dc5444ee940a64274d0e367124c93545035"}
|
||||
{"path":"packages/bus/src/migrations/3i-3j.sql","sha256":"5ad122ca950e43e066f3d9ed215e73353e6b26de6687b961a8818d69c9465031"}
|
||||
{"path":"packages/bus/src/migrations/3j-3k.sql","sha256":"2e2bb1fe70076f5e24406a18a923b9e55c4192178a0a704a1b9716032676f9d4"}
|
||||
{"path":"packages/bus/src/migrations/3k-3l.sql","sha256":"eb2822c73e527697399691ae520092277ddbd4d2a9a42a0731b3c81cc3569e58"}
|
||||
{"path":"packages/bus/src/migrations/3l-3m.sql","sha256":"791879f06a3e97d3cfbe6112e2fb6502457af30b3e0198e3da1192038906d156"}
|
||||
{"path":"packages/bus/src/migrations/3m-3n.sql","sha256":"b40bc6a7bedc459d6827cbf0414619e48fc5dce2febdeff70a647345f2281c3a"}
|
||||
{"path":"packages/tasks/requirements.json","sha256":"80b58323994d70e8bb496d81225aeb3d2cdfda464654b68b3b082e9af1fac5c1"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/bus/tests/usage-runtime.test.mjs","sha256":"5abe93fca8442f06ff68760623e91262d863e1191fa35a3d0c87d7b0e6c0a4c6"}
|
||||
{"path":"packages/bus/src/runtime.mjs","sha256":"969d04eb06b97093c7f9f0dfa6b51084c781e967e2668814083bbba84a2af7b6"}
|
||||
{"path":"packages/bus/src/store.mjs","sha256":"dd7fce9706402efd1c5a5b81f7d0fa3793de203e7a6aef4e118e934aebdc7c84"}
|
||||
{"path":"packages/project/src/index.mjs","sha256":"3ab38cc40ce9ed1a714a59a1f2c336c3792a59431a6a9cc655ba6a2f47513899"}
|
||||
{"path":"packages/project/src/paths.mjs","sha256":"bd9debcf3f9bb92560e74f220a0b108dfe24154bc6d1fb03c5ec414356d451f9"}
|
||||
{"path":"packages/project/src/git.mjs","sha256":"af6865a4cace92ef27910098507ffedfc8dfe768cea088b1fee21d0876cc556e"}
|
||||
{"path":"packages/seat/src/checkout.mjs","sha256":"5aca02491fe8df51487968ce62c776d493d0fe693cc41478b84bef7b49c8948d"}
|
||||
{"path":"packages/processing-control/src/effects.mjs","sha256":"3bc600649267f011e21ed8266fb16927b0ad3a0e2c49e4b54062d34c544d0c17"}
|
||||
{"path":"packages/processing-control/src/state.mjs","sha256":"ed834770fed863cb0c15b75062de1fd63dea940f3b42020b769a7e62b319c8ed"}
|
||||
{"path":"packages/processing-control/src/runtimes.mjs","sha256":"7145420aa354180689a5c84423928fc60c8123476dcfed3364c9cf4542f8c7ea"}
|
||||
{"path":"packages/project/src/validate.mjs","sha256":"e49ab5e825f0706da2f3c8dfcf33c1331a38d77ca2d35b03359ee68ea74652c5"}
|
||||
{"path":"packages/project/src/read.mjs","sha256":"42113cd20eb8f04dd252f9963a6f1a84806af9cae7beb6808c4d584a2548220c"}
|
||||
{"path":"packages/library/src/index.mjs","sha256":"98c2c2877549c3e2c5963ec4e49d99ab3b6d6ad54fb3bfae86cf98542207157e"}
|
||||
{"path":"packages/library/src/problems.mjs","sha256":"0c8764b03dae0150c56af74bcb113cf583dcbe1fa0c6f7386ef2d48d59a6bd31"}
|
||||
{"path":"packages/library/src/mapping.mjs","sha256":"c83c626c7cdc2a00ba4217c34b889ca0517cd2022d1f8fc9e7d3a14a0293a802"}
|
||||
{"path":"packages/library/src/scope.mjs","sha256":"97e12255f52ad638eeacd152eb26822f9a2aa72cd30e2fed1193f51cd6e56192"}
|
||||
{"path":"packages/library/src/supporting.mjs","sha256":"6a3b4de2070e62b1cca1c0ab20f2883d3153fc61608d1bf7670cecea08765b4c"}
|
||||
{"path":"packages/library/src/links.mjs","sha256":"def32a176cb70c86248e45908edde22f9c4c5f88575a4af0a396a05f617358bc"}
|
||||
{"path":"packages/library/src/reader.mjs","sha256":"ea126533afb7e74b71419eb943febb6b242eb96fc6917d9df1019db3e7e6ce8d"}
|
||||
{"path":"packages/library/src/render.mjs","sha256":"bfc3de029d3c8f0dcc96c90fde30d6da58bbb5b72d8f13e3f536c0d735c73ca5"}
|
||||
{"path":"packages/library/src/survey.mjs","sha256":"016bfa5c80572c0baf90ced39cb3d3ec66d395f0be15c2727b9552a9dd849093"}
|
||||
{"path":"packages/library/src/mirror.mjs","sha256":"26b824d6885e5c6d1b8bd71e754a9fa333c26307693f7e6a0c6a8e6300ecb4ae"}
|
||||
{"path":"packages/library/src/sync.mjs","sha256":"a58f3aec5ed9b3530b363e2fdbd38bc9ded7635d261ab2fca3cb31c45dcd3dfa"}
|
||||
{"path":"packages/library/src/index-build.mjs","sha256":"70c1fe75cb2149c9a074d55a6301d5b66157c2dc2e777b92bac338cce09d89c7"}
|
||||
{"path":"packages/library/src/query.mjs","sha256":"bafe113bee70f17bd249876d6bdd1c08fa051223c2111955e5d5f275bd76bba0"}
|
||||
{"path":"packages/library/src/limits.mjs","sha256":"98ef45ed61144aaea44d8aea1ac43082b6d340297e46846d01772da38728e530"}
|
||||
{"path":"packages/library/src/guard.mjs","sha256":"f710d9600a17f6e2989a289cfe84e58f161d86c7306605946ce05fa71b364eb2"}
|
||||
{"path":"packages/library/src/reply-protocol.mjs","sha256":"7b46f47b5e9d6b554b5d39bce2cd95c4610f5f35b8ab8fdc5a2864b3214be809"}
|
||||
{"path":"packages/library/src/write.mjs","sha256":"a301b7c7e3f42f66cb69d88991220f4e236f25a6e5951c61e79ec4ef2b714198"}
|
||||
{"path":"packages/business/src/vocabulary.mjs","sha256":"de1f04628e400084a46e77fd7e03c7a039f0f80c9e07bb486c9c012f187aa3eb"}
|
||||
{"path":"packages/bus/src/broker.mjs","sha256":"c0144adade79c2cfc6b8247721393f0250b1d64f6c6c04d85738cb80939c42e5"}
|
||||
{"path":"packages/bus/src/proxy-page-vocabulary.mjs","sha256":"cec059ea4bef5ef62f6181123bfe64bca21d8985d5357471da8c0a3199a877f9"}
|
||||
{"path":"packages/model-proxy/src/validation.mjs","sha256":"e66453cf6662677cf28cbad1ae8f7509917d333e5b80404ab02c53f5cf75e9e1"}
|
||||
{"path":"packages/bus/src/address.mjs","sha256":"232a1c77c2f17011c53b55fc6052f70985598210769d41d7c2c0b535328aad23"}
|
||||
{"path":"packages/plugins/src/kinds.mjs","sha256":"eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78"}
|
||||
{"path":"packages/tasks/src/requirements.mjs","sha256":"38e7b85650247759f06c09fce205b2970b8368bc81491f51dc6b3c90ba2a846d"}
|
||||
{"path":"packages/bus/src/landing.mjs","sha256":"9919febc7679168e0a72c0ef51983120283e595fea290a5e8e948409bf5c911b"}
|
||||
{"path":"packages/bus/src/credentials.mjs","sha256":"10485afcf94c29ac9f3d5ba30b12248a2379efd69185ff9fb90e9fed25fe0678"}
|
||||
{"path":"packages/bus/src/server.mjs","sha256":"8318bed9168ac3f58c09de40a139b68aacefd684e6c117406e181e2ca5ab4ec7"}
|
||||
{"path":"packages/bus/src/interpreter.mjs","sha256":"56bfc8dcba476886d7de61a1e798aae8e3041c2434c62d44fc40a168d22bb3bd"}
|
||||
{"path":"packages/bus/src/peercred.mjs","sha256":"29c88655e8b9aed8db604573c9213fd9f3c40ef35ff04f4eda8fbe8f1b8a32d7"}
|
||||
{"path":"packages/business/src/launch-settings.mjs","sha256":"e14d73f719664499d809909962a6ecc16d4ffb9d824fcdee699e0778809d9e96"}
|
||||
{"path":"packages/business/src/organization.mjs","sha256":"fa4ba1ae878cd27287865fa12115f8a6c1175a2dfd1011d5f8aca11e46e669c7"}
|
||||
{"path":"packages/business/src/business.mjs","sha256":"aaa4578fd4133f64119de6c8786a14759240a8910677529fdeae57173058b7d9"}
|
||||
{"path":"packages/business/src/errors.mjs","sha256":"cd4eb5960c17ce32f26d1a49196866ce04efc42c1d90b18b046af5fda8b9ff0a"}
|
||||
{"path":"packages/business/src/launch.mjs","sha256":"0aa94dbd14acd379a4837cc3e70b9618b3fa797d74124314e7245a8a3070e98c"}
|
||||
{"path":"packages/business/src/util.mjs","sha256":"e1f0e70a4bbba8ae2ad6185ab61770b15acda403e90fc708e13027a1e9ec663c"}
|
||||
{"path":"packages/business/src/vars.mjs","sha256":"f6b15ee8dad2d985c0ae66b1f106ca46cb56ec86ac8cd5dec8a05c887596a421"}
|
||||
{"path":"packages/business/src/credentials.mjs","sha256":"c3422b1e144177f9dd3015ac036ee1d2cde02bd2b3be406364f3b3f45d8c9b73"}
|
||||
{"path":"packages/business/src/role.mjs","sha256":"b10af84d7422da4d0e8c0a4fea1064eebbc2fac6a838a1b3939b554e22dedfc9"}
|
||||
{"path":"packages/business/src/resolve.mjs","sha256":"712183465fee099606223d84423afc54e3386a0c8e468c68d5ac39c1e676d109"}
|
||||
{"path":"packages/business/src/project.mjs","sha256":"9472996134c520c31971e66006d1c1683709f6df4f76fe3445bdc97a18637eff"}
|
||||
{"path":"packages/seat/src/session.mjs","sha256":"c37a6ef6f6d2b4e61443e77d800656bf31e38913bf7dbdc4ca955f4a83b13a41"}
|
||||
{"path":"packages/seat/src/proc.mjs","sha256":"382cbf7e0ff336911e288ce858bdbfbec693bc2b69879720d1f0b4c7d8455198"}
|
||||
{"path":"packages/seat/src/sandbox.mjs","sha256":"0868f393f6fb117d430428ec390e435359737eae0792b4a4d1f54797c7a6c1bf"}
|
||||
{"path":"packages/seat/src/seat.mjs","sha256":"eec970961a667c9e614d1474d33c31a019b2cf1b0bf931a51458d874bca13a15"}
|
||||
{"path":"packages/seat/src/compactions.mjs","sha256":"c5de99284b8fa61763b8dd30a58809bbc086529eeb10587586d52b0df2754774"}
|
||||
{"path":"packages/seat/src/working.mjs","sha256":"621f5c223811444336f0f5d6ad10bc7afce075491653c0527d6c26ca568b79c3"}
|
||||
{"path":"packages/plugins/src/loader.mjs","sha256":"2e99f9222424cf9503253701568f0bb5ef579a22930f9f224e5b63ad6b4f745f"}
|
||||
{"path":"packages/business/src/plugin-settings.mjs","sha256":"9d2c68dd21c6c9553af75f4b137c4f169e95761f32528767e0518d0313311f50"}
|
||||
{"path":"packages/model-proxy/src/client.mjs","sha256":"f5f86cad661034f223a76352d877fa8d7883bfa921a7a01282347a9a03272441"}
|
||||
{"path":"packages/model-proxy/src/common.mjs","sha256":"a6fb88352018b8f21593a0bb9311f87162c80d8b1e05e62b4d43b1e69af21b23"}
|
||||
{"path":"packages/bus/src/proxy-page.mjs","sha256":"af36aae674f46a4e5eacfe176fde8b58cd0b171a6d70e07ee6d479e0f558cce7"}
|
||||
{"path":"packages/model-proxy/src/settings.mjs","sha256":"1eac4b5741b360a077bb1c871c008b64f7c7119afc64be4d6e4a0dcdb3a313bb"}
|
||||
{"path":"packages/bus/src/model-keys.mjs","sha256":"b4e11975bd56db4c816ada297902f033b3db7754d4a05319f03d640e17374550"}
|
||||
{"path":"packages/business/src/instance-settings.mjs","sha256":"09f2bde85a6d7a8f0b1d1c60ac589b845b0c95e991b2f807758878416b13c6bd"}
|
||||
{"path":"packages/bus/src/credential-verbs.mjs","sha256":"86b4321dd436b97e389101873197dbab95b3d2202e5ef7da712c4978f4f9159f"}
|
||||
{"path":"packages/bus/src/business.mjs","sha256":"ff927da3cf22fbacc9ace77b2e8b803bffc2953fb58cf7ab4e5f6f6493732996"}
|
||||
{"path":"packages/bus/src/web.mjs","sha256":"68efa3c9d0a72095f503208ed5c2e660ef9bca68d3ea15f0fc2f1826a68e09cc"}
|
||||
{"path":"packages/discord/src/web.mjs","sha256":"e5a7b64720872b12b34223549537ace05ebf0ca8a29b2f844d2b7c5cc9ea41f7"}
|
||||
{"path":"packages/bus/src/host-run.mjs","sha256":"324c05b16253e0fcfc1a0299d1d8ab45850ea723fad1f67bcc07fc031f50d593"}
|
||||
{"path":"packages/bus/src/host-grant.mjs","sha256":"48337cdbc41d503f17962d3e3ad014183b1286165f97da6fd88b4faa50be3949"}
|
||||
{"path":"packages/business/src/hosts.mjs","sha256":"e08b11b70b54f13e3b18996dd903f841e04fd6c64791e96063df8b164c663882"}
|
||||
{"path":"packages/bus/src/gitea-grant.mjs","sha256":"27d7d5322c2f12641e350867d3ac6f838b33832951e69f057e3a7a28b8ac4d5b"}
|
||||
{"path":"packages/bus/src/principal.mjs","sha256":"2b1e18be825e8264b16506d6294863acbba812956cfdf8e056f21faaa94f7137"}
|
||||
{"path":"packages/bus/src/human.mjs","sha256":"bb13c146717cdc46d75d157177e400edac4d3e10f14fe511027a25fd44cec885"}
|
||||
{"path":"packages/bus/src/tester.mjs","sha256":"5e9e08ca8069e1de35232f26d48a77792388128dda659893909f2d34b5af2346"}
|
||||
{"path":"packages/business/src/access.mjs","sha256":"af028c999a6ab4d42b321c3f047e683b226c7ad232a2ae9cfc623b7dd5a4dd5f"}
|
||||
{"path":"packages/bus/src/usage.mjs","sha256":"4ae57d053c4b217e1c1a22ada3ed1c5d4a3f0e61b8d2798e9db37997cd071a29"}
|
||||
{"path":"packages/bus/src/proxy-usage.mjs","sha256":"5a6c3707e6a64304cfd37f1875eb378c6eb58bf438cc40365fe913eaec7cee59"}
|
||||
{"path":"packages/bus/src/limits.mjs","sha256":"18c1aacd280ebf0f200d5e6fc1dd1a7e098a3046c1cb8427140bb2198ac81cd3"}
|
||||
{"path":"packages/processing-control/src/coordinator.mjs","sha256":"ddc7318297abc4ec4dd03d425820b7323db609e554cfc5341cfdfa6934271e73"}
|
||||
{"path":"packages/discord/src/processing.mjs","sha256":"8fa9968862dff77fa6d8be5210c22d13712fd622a8cbc722d167be5be80d0783"}
|
||||
{"path":"packages/discord/src/binding.mjs","sha256":"5ab69c4111dd9589a197172ffe6968bf414f41c552b7910e5478a27c446cfaec"}
|
||||
{"path":"packages/discord/src/setspark.mjs","sha256":"ba09d286e707860afa53300f8802ac8e6193ab2d2e7abe9d2b07cbdef3822387"}
|
||||
{"path":"packages/discord/src/errors.mjs","sha256":"917b0e6c4f100e93f056b925e38d97eacdd8b2596e39fbd3f88c0b62b973d8ed"}
|
||||
{"path":"packages/discord/src/tools.mjs","sha256":"975503616245bb6051f06ecbf47436ce7d030f21af23042df7f3341062df967f"}
|
||||
{"path":"packages/discord/src/git.mjs","sha256":"c28e04a0055997ea0b34bea1ad2912adb248d5fd43713df1e6f5a661d87949b7"}
|
||||
{"path":"packages/discord/src/journal.mjs","sha256":"12684e926574c3fe7f693a03b60d1393df483f5feb4b47c9dd7c5a7ac050aec5"}
|
||||
{"path":"packages/processing-control/src/containers.mjs","sha256":"781973277c09133de15fc39be35b372a79066479097d46923c8ab7782f011dcd"}
|
||||
{"path":"packages/bus/src/client.mjs","sha256":"f3d483f61a24cbc9cce235e1e92889f09b8cecf513fcaf90c741f316f62262e2"}
|
||||
{"path":"packages/bus/schema.sql","sha256":"a2ba3a46f12e56139ecae9e55227d00847842aedec50c1d92aaae28844ca48e7"}
|
||||
{"path":"packages/bus/src/migrations/3b.sql","sha256":"179ffe356d4ff19a49b5ebad39b6c6bfd7771deb8e1b7c55b5e746f039d69e65"}
|
||||
{"path":"packages/bus/src/migrations/3b-3c.sql","sha256":"b753f630301bf125e9e286b4156d0736930dd8fb9cd8eb2ebf316688f9191a07"}
|
||||
{"path":"packages/bus/src/migrations/3c-3d.sql","sha256":"0423832d05aa68f9191d7362827bd19310001165b895fb2de40b962fe68f9d56"}
|
||||
{"path":"packages/bus/src/migrations/3d-3e.sql","sha256":"d9aacc974d5047790e65c30a90068259bb9396dc92d4904eae3b9c5dbbb2f077"}
|
||||
{"path":"packages/bus/src/migrations/3e-3f.sql","sha256":"bf0b72c606b1a56a1610f09619b0c1118f1f300c636824ea13fd51a4ca6ac4b3"}
|
||||
{"path":"packages/bus/src/migrations/3f-3g.sql","sha256":"82f54b264919e34282bc214e34e9849f701cd3723b9b2f0a0d107c16f939dc05"}
|
||||
{"path":"packages/bus/src/migrations/3g-3h.sql","sha256":"76168e4f9f6b427286ddb8402fd833acadb01d6325a85f60e9ccf8d42fe2d1d0"}
|
||||
{"path":"packages/bus/src/migrations/3h-3i.sql","sha256":"e058e6cea8da7b6e649f3e03f2b81dc5444ee940a64274d0e367124c93545035"}
|
||||
{"path":"packages/bus/src/migrations/3i-3j.sql","sha256":"5ad122ca950e43e066f3d9ed215e73353e6b26de6687b961a8818d69c9465031"}
|
||||
{"path":"packages/bus/src/migrations/3j-3k.sql","sha256":"2e2bb1fe70076f5e24406a18a923b9e55c4192178a0a704a1b9716032676f9d4"}
|
||||
{"path":"packages/bus/src/migrations/3k-3l.sql","sha256":"eb2822c73e527697399691ae520092277ddbd4d2a9a42a0731b3c81cc3569e58"}
|
||||
{"path":"packages/bus/src/migrations/3l-3m.sql","sha256":"791879f06a3e97d3cfbe6112e2fb6502457af30b3e0198e3da1192038906d156"}
|
||||
{"path":"packages/bus/src/migrations/3m-3n.sql","sha256":"b40bc6a7bedc459d6827cbf0414619e48fc5dce2febdeff70a647345f2281c3a"}
|
||||
{"path":"packages/project/schemas/project.schema.json","sha256":"f069c012e9660d5d0491a21f98e936b725f6818e1c3136dfec61b3c800bd58de"}
|
||||
{"path":"packages/project/schemas/requirement.schema.json","sha256":"79a1e7b567af7162bb88ca69861075fc579a858e8aec4e49824ccdc370b690c3"}
|
||||
{"path":"packages/project/schemas/decision.schema.json","sha256":"925bb03ac99e5845e4bfa20b4561a331f034f88e187db82213df6602a7ceee4b"}
|
||||
{"path":"packages/model-proxy/PIN","sha256":"889ac9589fadf7654d4dbb914f968cbafe4255ed215bd6a9ff3f331757c9017b"}
|
||||
{"path":"packages/plugins/usage-source/transcript/index.mjs","sha256":"d09ae19db3eb69477783163559bd6a8e5b59a6f5af0eafd62d0e2e3bd325065e"}
|
||||
{"path":"packages/plugins/harness/pi/index.mjs","sha256":"39c225f157b8f66b416625bda689153505743ffcfdc32964bb1f3d2c6fcb73af"}
|
||||
{"path":"packages/plugins/harness/pi/compactions.mjs","sha256":"aabaf5c4602e28f025c18b2e2ddd6fa0d1648870101a5de0c4424d97b24472dd"}
|
||||
{"path":"packages/tasks/requirements.json","sha256":"80b58323994d70e8bb496d81225aeb3d2cdfda464654b68b3b082e9af1fac5c1"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/bus/tests/usage.test.mjs","sha256":"2613ba0561572a7d4f753066922fddc90cca812cb0ce2b3e0a9a4d249a15e340"}
|
||||
{"path":"packages/bus/src/store.mjs","sha256":"dd7fce9706402efd1c5a5b81f7d0fa3793de203e7a6aef4e118e934aebdc7c84"}
|
||||
{"path":"packages/bus/src/usage.mjs","sha256":"4ae57d053c4b217e1c1a22ada3ed1c5d4a3f0e61b8d2798e9db37997cd071a29"}
|
||||
{"path":"packages/plugins/src/loader.mjs","sha256":"2e99f9222424cf9503253701568f0bb5ef579a22930f9f224e5b63ad6b4f745f"}
|
||||
{"path":"packages/plugins/src/kinds.mjs","sha256":"eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78"}
|
||||
{"path":"packages/bus/schema.sql","sha256":"a2ba3a46f12e56139ecae9e55227d00847842aedec50c1d92aaae28844ca48e7"}
|
||||
{"path":"packages/bus/src/migrations/3b.sql","sha256":"179ffe356d4ff19a49b5ebad39b6c6bfd7771deb8e1b7c55b5e746f039d69e65"}
|
||||
{"path":"packages/bus/src/migrations/3b-3c.sql","sha256":"b753f630301bf125e9e286b4156d0736930dd8fb9cd8eb2ebf316688f9191a07"}
|
||||
{"path":"packages/bus/src/migrations/3c-3d.sql","sha256":"0423832d05aa68f9191d7362827bd19310001165b895fb2de40b962fe68f9d56"}
|
||||
{"path":"packages/bus/src/migrations/3d-3e.sql","sha256":"d9aacc974d5047790e65c30a90068259bb9396dc92d4904eae3b9c5dbbb2f077"}
|
||||
{"path":"packages/bus/src/migrations/3e-3f.sql","sha256":"bf0b72c606b1a56a1610f09619b0c1118f1f300c636824ea13fd51a4ca6ac4b3"}
|
||||
{"path":"packages/bus/src/migrations/3f-3g.sql","sha256":"82f54b264919e34282bc214e34e9849f701cd3723b9b2f0a0d107c16f939dc05"}
|
||||
{"path":"packages/bus/src/migrations/3g-3h.sql","sha256":"76168e4f9f6b427286ddb8402fd833acadb01d6325a85f60e9ccf8d42fe2d1d0"}
|
||||
{"path":"packages/bus/src/migrations/3h-3i.sql","sha256":"e058e6cea8da7b6e649f3e03f2b81dc5444ee940a64274d0e367124c93545035"}
|
||||
{"path":"packages/bus/src/migrations/3i-3j.sql","sha256":"5ad122ca950e43e066f3d9ed215e73353e6b26de6687b961a8818d69c9465031"}
|
||||
{"path":"packages/bus/src/migrations/3j-3k.sql","sha256":"2e2bb1fe70076f5e24406a18a923b9e55c4192178a0a704a1b9716032676f9d4"}
|
||||
{"path":"packages/bus/src/migrations/3k-3l.sql","sha256":"eb2822c73e527697399691ae520092277ddbd4d2a9a42a0731b3c81cc3569e58"}
|
||||
{"path":"packages/bus/src/migrations/3l-3m.sql","sha256":"791879f06a3e97d3cfbe6112e2fb6502457af30b3e0198e3da1192038906d156"}
|
||||
{"path":"packages/bus/src/migrations/3m-3n.sql","sha256":"b40bc6a7bedc459d6827cbf0414619e48fc5dce2febdeff70a647345f2281c3a"}
|
||||
{"path":"packages/plugins/usage-source/transcript/index.mjs","sha256":"d09ae19db3eb69477783163559bd6a8e5b59a6f5af0eafd62d0e2e3bd325065e"}
|
||||
{"path":"packages/plugins/tests/helpers.mjs","sha256":"5d5e5dccdae3f94b8540d187a8899ec36f9c9933cae3933249c2d8c400c75aa2"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/business/tests/plugin-settings.test.mjs","sha256":"f0dfe004905dce31317d85d89a05802db878c3472e765e85dc9f1e04166e1df6"}
|
||||
{"path":"packages/business/tests/helpers.mjs","sha256":"a6a9971b42ddf176d9415caee3efc2eb16791dead5f0f0557d28449a550aefa1"}
|
||||
{"path":"packages/business/src/business.mjs","sha256":"aaa4578fd4133f64119de6c8786a14759240a8910677529fdeae57173058b7d9"}
|
||||
{"path":"packages/business/src/errors.mjs","sha256":"cd4eb5960c17ce32f26d1a49196866ce04efc42c1d90b18b046af5fda8b9ff0a"}
|
||||
{"path":"packages/business/src/launch.mjs","sha256":"0aa94dbd14acd379a4837cc3e70b9618b3fa797d74124314e7245a8a3070e98c"}
|
||||
{"path":"packages/business/src/util.mjs","sha256":"e1f0e70a4bbba8ae2ad6185ab61770b15acda403e90fc708e13027a1e9ec663c"}
|
||||
{"path":"packages/business/src/vocabulary.mjs","sha256":"de1f04628e400084a46e77fd7e03c7a039f0f80c9e07bb486c9c012f187aa3eb"}
|
||||
{"path":"packages/business/src/vars.mjs","sha256":"f6b15ee8dad2d985c0ae66b1f106ca46cb56ec86ac8cd5dec8a05c887596a421"}
|
||||
{"path":"packages/plugins/src/kinds.mjs","sha256":"eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78"}
|
||||
{"path":"packages/business/src/credentials.mjs","sha256":"c3422b1e144177f9dd3015ac036ee1d2cde02bd2b3be406364f3b3f45d8c9b73"}
|
||||
{"path":"packages/business/src/role.mjs","sha256":"b10af84d7422da4d0e8c0a4fea1064eebbc2fac6a838a1b3939b554e22dedfc9"}
|
||||
{"path":"packages/library/src/mapping.mjs","sha256":"c83c626c7cdc2a00ba4217c34b889ca0517cd2022d1f8fc9e7d3a14a0293a802"}
|
||||
{"path":"packages/library/src/problems.mjs","sha256":"0c8764b03dae0150c56af74bcb113cf583dcbe1fa0c6f7386ef2d48d59a6bd31"}
|
||||
{"path":"packages/business/src/plugin-settings.mjs","sha256":"9d2c68dd21c6c9553af75f4b137c4f169e95761f32528767e0518d0313311f50"}
|
||||
{"path":"packages/business/src/organization.mjs","sha256":"fa4ba1ae878cd27287865fa12115f8a6c1175a2dfd1011d5f8aca11e46e669c7"}
|
||||
{"path":"packages/library/src/limits.mjs","sha256":"98ef45ed61144aaea44d8aea1ac43082b6d340297e46846d01772da38728e530"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/business/tests/token-limit-settings.test.mjs","sha256":"bc6b3a31e8918d70aced7151b91ac4b39afec4081054024b162acb0e8f8fae07"}
|
||||
{"path":"packages/business/tests/helpers.mjs","sha256":"a6a9971b42ddf176d9415caee3efc2eb16791dead5f0f0557d28449a550aefa1"}
|
||||
{"path":"packages/business/src/business.mjs","sha256":"aaa4578fd4133f64119de6c8786a14759240a8910677529fdeae57173058b7d9"}
|
||||
{"path":"packages/business/src/errors.mjs","sha256":"cd4eb5960c17ce32f26d1a49196866ce04efc42c1d90b18b046af5fda8b9ff0a"}
|
||||
{"path":"packages/business/src/launch.mjs","sha256":"0aa94dbd14acd379a4837cc3e70b9618b3fa797d74124314e7245a8a3070e98c"}
|
||||
{"path":"packages/business/src/util.mjs","sha256":"e1f0e70a4bbba8ae2ad6185ab61770b15acda403e90fc708e13027a1e9ec663c"}
|
||||
{"path":"packages/business/src/vocabulary.mjs","sha256":"de1f04628e400084a46e77fd7e03c7a039f0f80c9e07bb486c9c012f187aa3eb"}
|
||||
{"path":"packages/business/src/vars.mjs","sha256":"f6b15ee8dad2d985c0ae66b1f106ca46cb56ec86ac8cd5dec8a05c887596a421"}
|
||||
{"path":"packages/plugins/src/kinds.mjs","sha256":"eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78"}
|
||||
{"path":"packages/business/src/credentials.mjs","sha256":"c3422b1e144177f9dd3015ac036ee1d2cde02bd2b3be406364f3b3f45d8c9b73"}
|
||||
{"path":"packages/business/src/role.mjs","sha256":"b10af84d7422da4d0e8c0a4fea1064eebbc2fac6a838a1b3939b554e22dedfc9"}
|
||||
{"path":"packages/library/src/mapping.mjs","sha256":"c83c626c7cdc2a00ba4217c34b889ca0517cd2022d1f8fc9e7d3a14a0293a802"}
|
||||
{"path":"packages/library/src/problems.mjs","sha256":"0c8764b03dae0150c56af74bcb113cf583dcbe1fa0c6f7386ef2d48d59a6bd31"}
|
||||
{"path":"packages/business/src/launch-settings.mjs","sha256":"e14d73f719664499d809909962a6ecc16d4ffb9d824fcdee699e0778809d9e96"}
|
||||
{"path":"packages/business/src/organization.mjs","sha256":"fa4ba1ae878cd27287865fa12115f8a6c1175a2dfd1011d5f8aca11e46e669c7"}
|
||||
{"path":"packages/library/src/limits.mjs","sha256":"98ef45ed61144aaea44d8aea1ac43082b6d340297e46846d01772da38728e530"}
|
||||
{"path":"packages/business/src/resolve.mjs","sha256":"712183465fee099606223d84423afc54e3386a0c8e468c68d5ac39c1e676d109"}
|
||||
{"path":"packages/business/src/project.mjs","sha256":"9472996134c520c31971e66006d1c1683709f6df4f76fe3445bdc97a18637eff"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/model-proxy/tests/client-probe.test.mjs","sha256":"77327681d6eb51f25d7aeffcc532b7e8269c1dc59139cb03adb4a3a1409f63e9"}
|
||||
{"path":"packages/model-proxy/src/client.mjs","sha256":"f5f86cad661034f223a76352d877fa8d7883bfa921a7a01282347a9a03272441"}
|
||||
{"path":"packages/model-proxy/src/common.mjs","sha256":"a6fb88352018b8f21593a0bb9311f87162c80d8b1e05e62b4d43b1e69af21b23"}
|
||||
{"path":"packages/model-proxy/src/validation.mjs","sha256":"e66453cf6662677cf28cbad1ae8f7509917d333e5b80404ab02c53f5cf75e9e1"}
|
||||
{"path":"packages/model-proxy/PIN","sha256":"889ac9589fadf7654d4dbb914f968cbafe4255ed215bd6a9ff3f331757c9017b"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/model-proxy/tests/client.test.mjs","sha256":"790c6a50ec030a8b27a28fac7fd129bd9eabe79774adf11d6620c00df9b6ae86"}
|
||||
{"path":"packages/model-proxy/src/client.mjs","sha256":"f5f86cad661034f223a76352d877fa8d7883bfa921a7a01282347a9a03272441"}
|
||||
{"path":"packages/model-proxy/src/common.mjs","sha256":"a6fb88352018b8f21593a0bb9311f87162c80d8b1e05e62b4d43b1e69af21b23"}
|
||||
{"path":"packages/model-proxy/src/validation.mjs","sha256":"e66453cf6662677cf28cbad1ae8f7509917d333e5b80404ab02c53f5cf75e9e1"}
|
||||
{"path":"packages/model-proxy/PIN","sha256":"889ac9589fadf7654d4dbb914f968cbafe4255ed215bd6a9ff3f331757c9017b"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/model-proxy/tests/management-key-encoding.test.mjs","sha256":"95e39a519f7ac8b9592876e6157191169f9b14d002163867a6ff6ab808e42c14"}
|
||||
{"path":"packages/model-proxy/src/common.mjs","sha256":"a6fb88352018b8f21593a0bb9311f87162c80d8b1e05e62b4d43b1e69af21b23"}
|
||||
{"path":"packages/model-proxy/src/validation.mjs","sha256":"e66453cf6662677cf28cbad1ae8f7509917d333e5b80404ab02c53f5cf75e9e1"}
|
||||
{"path":"packages/model-proxy/src/settings.mjs","sha256":"1eac4b5741b360a077bb1c871c008b64f7c7119afc64be4d6e4a0dcdb3a313bb"}
|
||||
{"path":"packages/model-proxy/src/client.mjs","sha256":"f5f86cad661034f223a76352d877fa8d7883bfa921a7a01282347a9a03272441"}
|
||||
{"path":"packages/model-proxy/PIN","sha256":"889ac9589fadf7654d4dbb914f968cbafe4255ed215bd6a9ff3f331757c9017b"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/model-proxy/tests/page-client.test.mjs","sha256":"f24e1d121a340cbcaa3f6cd6390eeb7d4b05f778dd498d76ba099cba5a719dea"}
|
||||
{"path":"packages/model-proxy/src/client.mjs","sha256":"f5f86cad661034f223a76352d877fa8d7883bfa921a7a01282347a9a03272441"}
|
||||
{"path":"packages/model-proxy/src/common.mjs","sha256":"a6fb88352018b8f21593a0bb9311f87162c80d8b1e05e62b4d43b1e69af21b23"}
|
||||
{"path":"packages/model-proxy/src/validation.mjs","sha256":"e66453cf6662677cf28cbad1ae8f7509917d333e5b80404ab02c53f5cf75e9e1"}
|
||||
{"path":"packages/model-proxy/PIN","sha256":"889ac9589fadf7654d4dbb914f968cbafe4255ed215bd6a9ff3f331757c9017b"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/model-proxy/tests/usage-client.test.mjs","sha256":"1ad66d56800a31cfbd387939e640653bc72150f4e73822d9e3c777b3bffbf1e1"}
|
||||
{"path":"packages/model-proxy/src/client.mjs","sha256":"f5f86cad661034f223a76352d877fa8d7883bfa921a7a01282347a9a03272441"}
|
||||
{"path":"packages/model-proxy/src/common.mjs","sha256":"a6fb88352018b8f21593a0bb9311f87162c80d8b1e05e62b4d43b1e69af21b23"}
|
||||
{"path":"packages/model-proxy/src/validation.mjs","sha256":"e66453cf6662677cf28cbad1ae8f7509917d333e5b80404ab02c53f5cf75e9e1"}
|
||||
{"path":"packages/model-proxy/PIN","sha256":"889ac9589fadf7654d4dbb914f968cbafe4255ed215bd6a9ff3f331757c9017b"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/plugins/tests/daily-quota.test.mjs","sha256":"3d4fab56fea4c45c6a317ef41121aa5b6da0502a6ef614b7931f91cafdfc1f71"}
|
||||
{"path":"packages/plugins/limit-check/daily-quota/index.mjs","sha256":"3749b9f6dd681ef424ee7d7e4d80ccee87b3655df8cd8fe9ccd0d505dcaaee9b"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/plugins/tests/kinds.test.mjs","sha256":"f3081e1dbdac20ade2246c743bcbb3934be686f79f378af21c365cd1451893ba"}
|
||||
{"path":"packages/plugins/src/kinds.mjs","sha256":"eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/plugins/tests/loader.test.mjs","sha256":"8588ad7eee0c9ce5de3b53e3b88562812a155a3d791a2bd3413bb1754655d78b"}
|
||||
{"path":"packages/plugins/tests/helpers.mjs","sha256":"5d5e5dccdae3f94b8540d187a8899ec36f9c9933cae3933249c2d8c400c75aa2"}
|
||||
{"path":"packages/business/tests/helpers.mjs","sha256":"a6a9971b42ddf176d9415caee3efc2eb16791dead5f0f0557d28449a550aefa1"}
|
||||
{"path":"packages/business/src/business.mjs","sha256":"aaa4578fd4133f64119de6c8786a14759240a8910677529fdeae57173058b7d9"}
|
||||
{"path":"packages/business/src/errors.mjs","sha256":"cd4eb5960c17ce32f26d1a49196866ce04efc42c1d90b18b046af5fda8b9ff0a"}
|
||||
{"path":"packages/business/src/launch.mjs","sha256":"0aa94dbd14acd379a4837cc3e70b9618b3fa797d74124314e7245a8a3070e98c"}
|
||||
{"path":"packages/business/src/util.mjs","sha256":"e1f0e70a4bbba8ae2ad6185ab61770b15acda403e90fc708e13027a1e9ec663c"}
|
||||
{"path":"packages/business/src/vocabulary.mjs","sha256":"de1f04628e400084a46e77fd7e03c7a039f0f80c9e07bb486c9c012f187aa3eb"}
|
||||
{"path":"packages/business/src/vars.mjs","sha256":"f6b15ee8dad2d985c0ae66b1f106ca46cb56ec86ac8cd5dec8a05c887596a421"}
|
||||
{"path":"packages/plugins/src/kinds.mjs","sha256":"eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78"}
|
||||
{"path":"packages/business/src/credentials.mjs","sha256":"c3422b1e144177f9dd3015ac036ee1d2cde02bd2b3be406364f3b3f45d8c9b73"}
|
||||
{"path":"packages/business/src/role.mjs","sha256":"b10af84d7422da4d0e8c0a4fea1064eebbc2fac6a838a1b3939b554e22dedfc9"}
|
||||
{"path":"packages/library/src/mapping.mjs","sha256":"c83c626c7cdc2a00ba4217c34b889ca0517cd2022d1f8fc9e7d3a14a0293a802"}
|
||||
{"path":"packages/library/src/problems.mjs","sha256":"0c8764b03dae0150c56af74bcb113cf583dcbe1fa0c6f7386ef2d48d59a6bd31"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/plugins/tests/token-limit.test.mjs","sha256":"6e96bb96278ec754ca1816a24f49ef677771615ab5cf186ae41969fc2f93d8cc"}
|
||||
{"path":"packages/plugins/limit-check/token-limit/index.mjs","sha256":"4d0c6f5f87101f94608c02001a49d62cef113da48c539b2d2488dfbed1a4c524"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/webui/tests/usage-render.test.mjs","sha256":"39f50991578b98594183390a00efbca84fda90ef61617eea4215e2c75f90b82c"}
|
||||
{"path":"packages/webui/src/public/bus.js","sha256":"3c7a35e25b4c1cfda19ac9466d4b2fbc86c880761a1d04ad3ece8bc485f60f93"}
|
||||
{"path":"agents/codex/work/queue-333/trace-inputs.mjs","sha256":"06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1"}
|
||||
{"path":"packages/webui/tests/usage.test.mjs","sha256":"f96d06974bc83051c0d5c9000e38161ea0cc231997410bcc6c42ed7f55718dfd"}
|
||||
{"path":"packages/webui/src/serve.mjs","sha256":"7b7bee91604b7bd973027b177de83205db9aed366e694072fc6343b46465b5ba"}
|
||||
{"path":"packages/webui/src/proxy-http.mjs","sha256":"a09028cd5ca57367f597d0681e84926ca871fd4626769e9947927d949c2b6ab7"}
|
||||
{"path":"packages/webui/src/tester-socket.mjs","sha256":"1c1fe0c795adac97f28502564a75f26d5666d9be5ae51169f7dd5bb7741fad16"}
|
||||
{"path":"packages/webui/src/bus.mjs","sha256":"4ebf6c2b5d71c23d85cbde83f69aa671058dc2195c9ae4bdda624f6940729d1b"}
|
||||
{"path":"packages/cli/src/transport.mjs","sha256":"662642a8ce739fcb6c188ad07125a94e008c8a305eced127c8041d472c56e55b"}
|
||||
{"path":"packages/cli/src/errors.mjs","sha256":"c7bdd98a3ddeeb9bc4415d907b92555d723c566eba314075d91486da9b5e85dc"}
|
||||
{"path":"packages/cli/src/host.mjs","sha256":"a0936aee783ff47dd58fc907fefd86f63e571809a3ce5b0d6d931f71e756b15e"}
|
||||
{"path":"packages/seat/src/proc.mjs","sha256":"382cbf7e0ff336911e288ce858bdbfbec693bc2b69879720d1f0b4c7d8455198"}
|
||||
{"path":"packages/bus/src/views.mjs","sha256":"1f31aefa71984fba90c5390df5cc595d929681965f57485ad4972143d5c4b15f"}
|
||||
{"path":"packages/bus/src/broker.mjs","sha256":"c0144adade79c2cfc6b8247721393f0250b1d64f6c6c04d85738cb80939c42e5"}
|
||||
{"path":"packages/bus/src/proxy-page-vocabulary.mjs","sha256":"cec059ea4bef5ef62f6181123bfe64bca21d8985d5357471da8c0a3199a877f9"}
|
||||
{"path":"packages/model-proxy/src/validation.mjs","sha256":"e66453cf6662677cf28cbad1ae8f7509917d333e5b80404ab02c53f5cf75e9e1"}
|
||||
{"path":"packages/bus/src/address.mjs","sha256":"232a1c77c2f17011c53b55fc6052f70985598210769d41d7c2c0b535328aad23"}
|
||||
{"path":"packages/processing-control/src/state.mjs","sha256":"ed834770fed863cb0c15b75062de1fd63dea940f3b42020b769a7e62b319c8ed"}
|
||||
{"path":"packages/plugins/src/kinds.mjs","sha256":"eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78"}
|
||||
{"path":"packages/tasks/src/requirements.mjs","sha256":"38e7b85650247759f06c09fce205b2970b8368bc81491f51dc6b3c90ba2a846d"}
|
||||
{"path":"packages/bus/src/landing.mjs","sha256":"9919febc7679168e0a72c0ef51983120283e595fea290a5e8e948409bf5c911b"}
|
||||
{"path":"packages/business/src/vocabulary.mjs","sha256":"de1f04628e400084a46e77fd7e03c7a039f0f80c9e07bb486c9c012f187aa3eb"}
|
||||
{"path":"packages/webui/src/reads.mjs","sha256":"46defeb3b4be0e1a22e4b89445872ad6b15cdee182076e9e6222219ae29997f4"}
|
||||
{"path":"packages/business/src/index.mjs","sha256":"a386ce5bd1d41d86f7b90641a423a2b651b491c8989d5085412c7d202ac1cb30"}
|
||||
{"path":"packages/business/src/errors.mjs","sha256":"cd4eb5960c17ce32f26d1a49196866ce04efc42c1d90b18b046af5fda8b9ff0a"}
|
||||
{"path":"packages/business/src/role.mjs","sha256":"b10af84d7422da4d0e8c0a4fea1064eebbc2fac6a838a1b3939b554e22dedfc9"}
|
||||
{"path":"packages/business/src/util.mjs","sha256":"e1f0e70a4bbba8ae2ad6185ab61770b15acda403e90fc708e13027a1e9ec663c"}
|
||||
{"path":"packages/business/src/vars.mjs","sha256":"f6b15ee8dad2d985c0ae66b1f106ca46cb56ec86ac8cd5dec8a05c887596a421"}
|
||||
{"path":"packages/business/src/credentials.mjs","sha256":"c3422b1e144177f9dd3015ac036ee1d2cde02bd2b3be406364f3b3f45d8c9b73"}
|
||||
{"path":"packages/business/src/business.mjs","sha256":"aaa4578fd4133f64119de6c8786a14759240a8910677529fdeae57173058b7d9"}
|
||||
{"path":"packages/business/src/launch.mjs","sha256":"0aa94dbd14acd379a4837cc3e70b9618b3fa797d74124314e7245a8a3070e98c"}
|
||||
{"path":"packages/library/src/mapping.mjs","sha256":"c83c626c7cdc2a00ba4217c34b889ca0517cd2022d1f8fc9e7d3a14a0293a802"}
|
||||
{"path":"packages/library/src/problems.mjs","sha256":"0c8764b03dae0150c56af74bcb113cf583dcbe1fa0c6f7386ef2d48d59a6bd31"}
|
||||
{"path":"packages/business/src/access.mjs","sha256":"af028c999a6ab4d42b321c3f047e683b226c7ad232a2ae9cfc623b7dd5a4dd5f"}
|
||||
{"path":"packages/business/src/project.mjs","sha256":"9472996134c520c31971e66006d1c1683709f6df4f76fe3445bdc97a18637eff"}
|
||||
{"path":"packages/business/src/resolve.mjs","sha256":"712183465fee099606223d84423afc54e3386a0c8e468c68d5ac39c1e676d109"}
|
||||
{"path":"packages/business/src/library-seats.mjs","sha256":"93a7fddac9a08b5f740a0a277b29b8a3459e6f5a4fd33a37212437cb456b9b62"}
|
||||
{"path":"packages/business/src/launch-settings.mjs","sha256":"e14d73f719664499d809909962a6ecc16d4ffb9d824fcdee699e0778809d9e96"}
|
||||
{"path":"packages/business/src/organization.mjs","sha256":"fa4ba1ae878cd27287865fa12115f8a6c1175a2dfd1011d5f8aca11e46e669c7"}
|
||||
{"path":"packages/library/src/limits.mjs","sha256":"98ef45ed61144aaea44d8aea1ac43082b6d340297e46846d01772da38728e530"}
|
||||
{"path":"packages/seat/src/session.mjs","sha256":"c37a6ef6f6d2b4e61443e77d800656bf31e38913bf7dbdc4ca955f4a83b13a41"}
|
||||
{"path":"packages/seat/src/sandbox.mjs","sha256":"0868f393f6fb117d430428ec390e435359737eae0792b4a4d1f54797c7a6c1bf"}
|
||||
{"path":"packages/seat/src/seat.mjs","sha256":"eec970961a667c9e614d1474d33c31a019b2cf1b0bf931a51458d874bca13a15"}
|
||||
{"path":"packages/cli/src/boot-status.mjs","sha256":"147a17bbdcbc34efe20a88a4cabe796c101cb63dce621d28103f4de29def4cc2"}
|
||||
{"path":"packages/cli/src/cli.mjs","sha256":"1e663b175e18e39ff68c9ac3a65ff71fc777a6c37ebca035fce6a2783d0aaac3"}
|
||||
{"path":"packages/discord/src/binding.mjs","sha256":"5ab69c4111dd9589a197172ffe6968bf414f41c552b7910e5478a27c446cfaec"}
|
||||
{"path":"packages/discord/src/web.mjs","sha256":"e5a7b64720872b12b34223549537ace05ebf0ca8a29b2f844d2b7c5cc9ea41f7"}
|
||||
{"path":"packages/discord/src/setspark.mjs","sha256":"ba09d286e707860afa53300f8802ac8e6193ab2d2e7abe9d2b07cbdef3822387"}
|
||||
{"path":"packages/discord/src/errors.mjs","sha256":"917b0e6c4f100e93f056b925e38d97eacdd8b2596e39fbd3f88c0b62b973d8ed"}
|
||||
{"path":"packages/discord/src/tools.mjs","sha256":"975503616245bb6051f06ecbf47436ce7d030f21af23042df7f3341062df967f"}
|
||||
{"path":"packages/discord/src/git.mjs","sha256":"c28e04a0055997ea0b34bea1ad2912adb248d5fd43713df1e6f5a661d87949b7"}
|
||||
{"path":"packages/cli/src/project.mjs","sha256":"6cfe7fd5086ddb59c5666060c6f8044c2852e0f3d5755b1fa206f7521173f300"}
|
||||
{"path":"packages/project/src/index.mjs","sha256":"3ab38cc40ce9ed1a714a59a1f2c336c3792a59431a6a9cc655ba6a2f47513899"}
|
||||
{"path":"packages/project/src/paths.mjs","sha256":"bd9debcf3f9bb92560e74f220a0b108dfe24154bc6d1fb03c5ec414356d451f9"}
|
||||
{"path":"packages/project/src/git.mjs","sha256":"af6865a4cace92ef27910098507ffedfc8dfe768cea088b1fee21d0876cc556e"}
|
||||
{"path":"packages/seat/src/checkout.mjs","sha256":"5aca02491fe8df51487968ce62c776d493d0fe693cc41478b84bef7b49c8948d"}
|
||||
{"path":"packages/processing-control/src/effects.mjs","sha256":"3bc600649267f011e21ed8266fb16927b0ad3a0e2c49e4b54062d34c544d0c17"}
|
||||
{"path":"packages/processing-control/src/runtimes.mjs","sha256":"7145420aa354180689a5c84423928fc60c8123476dcfed3364c9cf4542f8c7ea"}
|
||||
{"path":"packages/project/src/validate.mjs","sha256":"e49ab5e825f0706da2f3c8dfcf33c1331a38d77ca2d35b03359ee68ea74652c5"}
|
||||
{"path":"packages/project/src/read.mjs","sha256":"42113cd20eb8f04dd252f9963a6f1a84806af9cae7beb6808c4d584a2548220c"}
|
||||
{"path":"packages/cli/src/config.mjs","sha256":"d960c2a9df3f7c84deff22dad1f0ab120f95ee365984e390de98eba7292b65a1"}
|
||||
{"path":"packages/bus/src/business.mjs","sha256":"ff927da3cf22fbacc9ace77b2e8b803bffc2953fb58cf7ab4e5f6f6493732996"}
|
||||
{"path":"packages/cli/src/access.mjs","sha256":"c4949a16173d11f9d32d10d3ddd58a181631848b259bef1998820a78f5694808"}
|
||||
{"path":"packages/cli/src/format.mjs","sha256":"481d9956698df7765ca8556d57164fb78f131708a09900d5a55b9048b5638f5f"}
|
||||
{"path":"packages/cli/src/thread.mjs","sha256":"58888b7731f8009d4c3f8be2caf4445f13dd8f534e1633f6e2720b259fcc3f92"}
|
||||
{"path":"packages/cli/src/session.mjs","sha256":"1a30048032f5bb64419ae9716a1692978bc1a137220a094d1900298aca6ba1d7"}
|
||||
{"path":"packages/cli/src/limits.mjs","sha256":"2f291a71f490f2741edada7a3e3788500f8976a08eb8ab1411f6c5982f778260"}
|
||||
{"path":"packages/business/src/migrate-launch.mjs","sha256":"44fa089c9024934a2f9fb5ef99552eb18d616842210cbc0fc860ea32ce0b1524"}
|
||||
{"path":"packages/cli/src/plugins.mjs","sha256":"f8d9fc24ccd71494fb2914914949cb08948ae93fb3180b9531eb807c921a6f53"}
|
||||
{"path":"packages/cli/src/model-proxy.mjs","sha256":"9a043f122e1d49103bab64716d0eb80cfc09da3c91f7e2eb014b0d8ff0b02f3d"}
|
||||
{"path":"packages/model-proxy/src/fetch.mjs","sha256":"00378d2ea95ac4945899696462f8ff4c70dc020cc58d93663d731d2f2f333783"}
|
||||
{"path":"packages/model-proxy/src/common.mjs","sha256":"a6fb88352018b8f21593a0bb9311f87162c80d8b1e05e62b4d43b1e69af21b23"}
|
||||
{"path":"packages/model-proxy/src/settings.mjs","sha256":"1eac4b5741b360a077bb1c871c008b64f7c7119afc64be4d6e4a0dcdb3a313bb"}
|
||||
{"path":"packages/cli/src/credentials.mjs","sha256":"19755f7bb002d8455990c5dc7c458e64aeb95252ec7231a2ed2fd9c638fcb511"}
|
||||
{"path":"packages/cli/src/hosts.mjs","sha256":"60419503898f5e7f3046df5e749098728fbdfea76eb5c53b5dc9b909329abe2e"}
|
||||
{"path":"packages/cli/src/grants.mjs","sha256":"b586907ca8f351f60dc19ec2683df75d2d70ddb12955d09fb14560c9d3bed3dc"}
|
||||
{"path":"packages/cli/src/instances.mjs","sha256":"8d6dab8da62b4458477572ca1956adad57bc0b0d308df6eae57477175c345d7a"}
|
||||
{"path":"packages/plugins/src/channel.mjs","sha256":"5fcecf8336ee247e8ac2f626b21e4c79b1edc49082eadfd536cd23016c6bb756"}
|
||||
{"path":"packages/plugins/src/loader.mjs","sha256":"2e99f9222424cf9503253701568f0bb5ef579a22930f9f224e5b63ad6b4f745f"}
|
||||
{"path":"packages/cli/src/launcher.mjs","sha256":"373d4c028dfa6d85c748d56f56359789fe2b81987f522ac23747fd37bb5478ed"}
|
||||
{"path":"packages/cli/src/model-stall.mjs","sha256":"0bdc91dcaa096bd3dc9d08a1dea59893a21f6505c843e698ad9c8daa4b74364b"}
|
||||
{"path":"packages/harness/src/bundle.mjs","sha256":"e944a4c7a26d1fe55e13ac1eca31dd86c302dc7c868224b8b000b27255976153"}
|
||||
{"path":"packages/harness/src/tools.mjs","sha256":"38fe84040a78c3f8a8dcde4339d88db3b5df9ef669d605ad1d92ff3e8b646b40"}
|
||||
{"path":"packages/seat/src/compactions.mjs","sha256":"c5de99284b8fa61763b8dd30a58809bbc086529eeb10587586d52b0df2754774"}
|
||||
{"path":"packages/cli/src/git-socket.mjs","sha256":"3076a53b9891d4d0e084306567b88ded12c4de53a943c029646a424bf59d8e49"}
|
||||
{"path":"packages/seat/src/landing.mjs","sha256":"6f7c938a32b349ee49ce95b89ad499e599f6016e5e9d7efd79a9ea4177b4d175"}
|
||||
{"path":"packages/seat/src/working.mjs","sha256":"621f5c223811444336f0f5d6ad10bc7afce075491653c0527d6c26ca568b79c3"}
|
||||
{"path":"packages/cli/src/app.mjs","sha256":"15a8ee212fc37cea28e389f60ddb8916f9e1509cdcfb2e522acfe548702a16dc"}
|
||||
{"path":"packages/cli/src/screens.mjs","sha256":"9d03335628ae62e85c5fbc08c2e739ed0bd43b10d486faf397129a56a1b343e0"}
|
||||
{"path":"packages/conversation/src/terminal.mjs","sha256":"c24d28a073659640b8b027eb12ad150ba895c3001091b892ecef2ec1da40d5cd"}
|
||||
{"path":"packages/conversation/src/client.mjs","sha256":"a45beb82438bb42d97d1e322010e175e785767664e548b90c4125e98b7660003"}
|
||||
{"path":"packages/conversation/src/framing.mjs","sha256":"eaf0772b60bb17fbf9548267c9cfeb0104f92f5cbafdfcb60c1633883eec6432"}
|
||||
{"path":"packages/conversation/src/records.mjs","sha256":"96f7b64c2e2c3493e270224542818fd14f042e3cf0ac14788b3f881010bc25b1"}
|
||||
{"path":"packages/conversation/src/parts.mjs","sha256":"da336ed2a2a149ff56ac12af2440a8353d4573c33e9069381be60f1a0ca70151"}
|
||||
{"path":"packages/conversation/src/transcript.mjs","sha256":"f834ee740e7149e7d2ed976112d0719ce0660270e3b61cf93e1774d112c992a2"}
|
||||
{"path":"packages/cli/src/usage.mjs","sha256":"f9e0c69849633ae36a7a6aa22729a690dc40292178ac3db43accbb131fd7b4ca"}
|
||||
{"path":"packages/tasks/src/fields.mjs","sha256":"c9a883e9a1649277edce97adca40bca2874df7b5312c70e4ac6f6d4a1c860841"}
|
||||
{"path":"packages/webui/src/chat-http.mjs","sha256":"3a5321a5f492a98d342e4ddcc1e9da3522cfff89a4f9bc3f51d2ab1426d3de1b"}
|
||||
{"path":"packages/webui/src/processing-http.mjs","sha256":"c3825a02c3b4f4e5537db4a945439d707e177e74c3e8b1fc2cb777515e610b64"}
|
||||
{"path":"packages/webui/src/decision-http.mjs","sha256":"93d4d0c36d0b74eaace24bce4c3e7179b7418377eb4df6d0f6a9ca89d5eb8e39"}
|
||||
{"path":"packages/webui/tests/fixture.mjs","sha256":"b35d3f3471d6d83ef2d19d6102eaecce2ddec9330f337d7194f1d7be03cbd216"}
|
||||
{"path":"packages/control-board/src/serve.mjs","sha256":"2eb25c46e85ddadd3bdbdbe605db54a6e09845155384a209622554d78307e583"}
|
||||
{"path":"packages/control-board/src/scan.mjs","sha256":"6d74b131af360268be748a1f8f7f2b3f5a9180365e7279426640883fc295a676"}
|
||||
{"path":"packages/control-board/src/discord.mjs","sha256":"8966f1f98ea81b4525345fc4889db5e0e5263ca41b5132ac8dd9bd99a2c88522"}
|
||||
{"path":"packages/discord/src/journal.mjs","sha256":"12684e926574c3fe7f693a03b60d1393df483f5feb4b47c9dd7c5a7ac050aec5"}
|
||||
{"path":"packages/conversation/src/reader.mjs","sha256":"75d0cc982c36b0a81ff23f0da9da1b56906c496250a043f91d3a3b18ffa8e51b"}
|
||||
{"path":"packages/conversation/src/safe-fs.mjs","sha256":"62b0f7e9f798f584fcc0e4ead0522e44fd113bd0803f2bad92ffa480cadb7527"}
|
||||
{"path":"packages/conversation/src/pi.mjs","sha256":"20e781240846298fa65f9a8226b5e1ee1e81338b81229334666d845c17c99ac1"}
|
||||
{"path":"packages/project/schemas/project.schema.json","sha256":"f069c012e9660d5d0491a21f98e936b725f6818e1c3136dfec61b3c800bd58de"}
|
||||
{"path":"packages/project/schemas/requirement.schema.json","sha256":"79a1e7b567af7162bb88ca69861075fc579a858e8aec4e49824ccdc370b690c3"}
|
||||
{"path":"packages/project/schemas/decision.schema.json","sha256":"925bb03ac99e5845e4bfa20b4561a331f034f88e187db82213df6602a7ceee4b"}
|
||||
{"path":"packages/model-proxy/PIN","sha256":"889ac9589fadf7654d4dbb914f968cbafe4255ed215bd6a9ff3f331757c9017b"}
|
||||
@@ -0,0 +1,202 @@
|
||||
06794536ac746e9cf02ca698838cd5355987b29fd6a18a8fb3b51464c41f10c1 agents/codex/work/queue-333/trace-inputs.mjs
|
||||
a2ba3a46f12e56139ecae9e55227d00847842aedec50c1d92aaae28844ca48e7 packages/bus/schema.sql
|
||||
232a1c77c2f17011c53b55fc6052f70985598210769d41d7c2c0b535328aad23 packages/bus/src/address.mjs
|
||||
c0144adade79c2cfc6b8247721393f0250b1d64f6c6c04d85738cb80939c42e5 packages/bus/src/broker.mjs
|
||||
ff927da3cf22fbacc9ace77b2e8b803bffc2953fb58cf7ab4e5f6f6493732996 packages/bus/src/business.mjs
|
||||
f3d483f61a24cbc9cce235e1e92889f09b8cecf513fcaf90c741f316f62262e2 packages/bus/src/client.mjs
|
||||
86b4321dd436b97e389101873197dbab95b3d2202e5ef7da712c4978f4f9159f packages/bus/src/credential-verbs.mjs
|
||||
10485afcf94c29ac9f3d5ba30b12248a2379efd69185ff9fb90e9fed25fe0678 packages/bus/src/credentials.mjs
|
||||
27d7d5322c2f12641e350867d3ac6f838b33832951e69f057e3a7a28b8ac4d5b packages/bus/src/gitea-grant.mjs
|
||||
48337cdbc41d503f17962d3e3ad014183b1286165f97da6fd88b4faa50be3949 packages/bus/src/host-grant.mjs
|
||||
324c05b16253e0fcfc1a0299d1d8ab45850ea723fad1f67bcc07fc031f50d593 packages/bus/src/host-run.mjs
|
||||
bb13c146717cdc46d75d157177e400edac4d3e10f14fe511027a25fd44cec885 packages/bus/src/human.mjs
|
||||
56bfc8dcba476886d7de61a1e798aae8e3041c2434c62d44fc40a168d22bb3bd packages/bus/src/interpreter.mjs
|
||||
9919febc7679168e0a72c0ef51983120283e595fea290a5e8e948409bf5c911b packages/bus/src/landing.mjs
|
||||
18c1aacd280ebf0f200d5e6fc1dd1a7e098a3046c1cb8427140bb2198ac81cd3 packages/bus/src/limits.mjs
|
||||
b753f630301bf125e9e286b4156d0736930dd8fb9cd8eb2ebf316688f9191a07 packages/bus/src/migrations/3b-3c.sql
|
||||
179ffe356d4ff19a49b5ebad39b6c6bfd7771deb8e1b7c55b5e746f039d69e65 packages/bus/src/migrations/3b.sql
|
||||
0423832d05aa68f9191d7362827bd19310001165b895fb2de40b962fe68f9d56 packages/bus/src/migrations/3c-3d.sql
|
||||
d9aacc974d5047790e65c30a90068259bb9396dc92d4904eae3b9c5dbbb2f077 packages/bus/src/migrations/3d-3e.sql
|
||||
bf0b72c606b1a56a1610f09619b0c1118f1f300c636824ea13fd51a4ca6ac4b3 packages/bus/src/migrations/3e-3f.sql
|
||||
82f54b264919e34282bc214e34e9849f701cd3723b9b2f0a0d107c16f939dc05 packages/bus/src/migrations/3f-3g.sql
|
||||
76168e4f9f6b427286ddb8402fd833acadb01d6325a85f60e9ccf8d42fe2d1d0 packages/bus/src/migrations/3g-3h.sql
|
||||
e058e6cea8da7b6e649f3e03f2b81dc5444ee940a64274d0e367124c93545035 packages/bus/src/migrations/3h-3i.sql
|
||||
5ad122ca950e43e066f3d9ed215e73353e6b26de6687b961a8818d69c9465031 packages/bus/src/migrations/3i-3j.sql
|
||||
2e2bb1fe70076f5e24406a18a923b9e55c4192178a0a704a1b9716032676f9d4 packages/bus/src/migrations/3j-3k.sql
|
||||
eb2822c73e527697399691ae520092277ddbd4d2a9a42a0731b3c81cc3569e58 packages/bus/src/migrations/3k-3l.sql
|
||||
791879f06a3e97d3cfbe6112e2fb6502457af30b3e0198e3da1192038906d156 packages/bus/src/migrations/3l-3m.sql
|
||||
b40bc6a7bedc459d6827cbf0414619e48fc5dce2febdeff70a647345f2281c3a packages/bus/src/migrations/3m-3n.sql
|
||||
b4e11975bd56db4c816ada297902f033b3db7754d4a05319f03d640e17374550 packages/bus/src/model-keys.mjs
|
||||
29c88655e8b9aed8db604573c9213fd9f3c40ef35ff04f4eda8fbe8f1b8a32d7 packages/bus/src/peercred.mjs
|
||||
2b1e18be825e8264b16506d6294863acbba812956cfdf8e056f21faaa94f7137 packages/bus/src/principal.mjs
|
||||
ed13afdce6359df31d35a79496ebb4afdefef82030a8326a76b2a25b37e98d9d packages/bus/src/process.mjs
|
||||
cec059ea4bef5ef62f6181123bfe64bca21d8985d5357471da8c0a3199a877f9 packages/bus/src/proxy-page-vocabulary.mjs
|
||||
af36aae674f46a4e5eacfe176fde8b58cd0b171a6d70e07ee6d479e0f558cce7 packages/bus/src/proxy-page.mjs
|
||||
5a6c3707e6a64304cfd37f1875eb378c6eb58bf438cc40365fe913eaec7cee59 packages/bus/src/proxy-usage.mjs
|
||||
969d04eb06b97093c7f9f0dfa6b51084c781e967e2668814083bbba84a2af7b6 packages/bus/src/runtime.mjs
|
||||
8318bed9168ac3f58c09de40a139b68aacefd684e6c117406e181e2ca5ab4ec7 packages/bus/src/server.mjs
|
||||
dd7fce9706402efd1c5a5b81f7d0fa3793de203e7a6aef4e118e934aebdc7c84 packages/bus/src/store.mjs
|
||||
5e9e08ca8069e1de35232f26d48a77792388128dda659893909f2d34b5af2346 packages/bus/src/tester.mjs
|
||||
4ae57d053c4b217e1c1a22ada3ed1c5d4a3f0e61b8d2798e9db37997cd071a29 packages/bus/src/usage.mjs
|
||||
1f31aefa71984fba90c5390df5cc595d929681965f57485ad4972143d5c4b15f packages/bus/src/views.mjs
|
||||
68efa3c9d0a72095f503208ed5c2e660ef9bca68d3ea15f0fc2f1826a68e09cc packages/bus/src/web.mjs
|
||||
dbbfa80b4082fd44e2f08539b5455653fac062321b8f2106f638e2d8161fa3eb packages/bus/tests/daily-quota-runtime.test.mjs
|
||||
45870a4903d1996915c0086a6beb4d0a4c75b38386b7c5e6d98b5bc811c3b541 packages/bus/tests/limit-checks.test.mjs
|
||||
561d0950b788d08ad9a79ccd6572ad6976ba4b2e2b1c79d1e4d06827a84c131b packages/bus/tests/limit-stop.test.mjs
|
||||
a2e553025edbe6e930c9d03b48289c53b51b153ac9ae49bb21bf721b725f1913 packages/bus/tests/limits-runtime.test.mjs
|
||||
e37114eab9c5f21015ea8e429f0574d3ea34b06263f1e42b83b31b8d2df222a7 packages/bus/tests/p5-key-context.test.mjs
|
||||
241e779016ffd0b54c5646cb4fac7e21ea1167e77afbd652ff4e01f8d238f99c packages/bus/tests/p5-runtime.test.mjs
|
||||
895ffddbcca1b38fdaa17eefdeca9092a9b9a934d3a54a3bf7857f42fe99fba7 packages/bus/tests/plugins-verb.test.mjs
|
||||
84c8351029272b6ee05e7fd81b4cc4453553ceeb7a5127a1333dae63d1336ad5 packages/bus/tests/proxy-usage.test.mjs
|
||||
4b2149ea4219f49db19669ada9f88931f7691cdd73dd27dceec6e8fe1f76dd0c packages/bus/tests/usage-broker.test.mjs
|
||||
5abe93fca8442f06ff68760623e91262d863e1191fa35a3d0c87d7b0e6c0a4c6 packages/bus/tests/usage-runtime.test.mjs
|
||||
2613ba0561572a7d4f753066922fddc90cca812cb0ce2b3e0a9a4d249a15e340 packages/bus/tests/usage.test.mjs
|
||||
af028c999a6ab4d42b321c3f047e683b226c7ad232a2ae9cfc623b7dd5a4dd5f packages/business/src/access.mjs
|
||||
aaa4578fd4133f64119de6c8786a14759240a8910677529fdeae57173058b7d9 packages/business/src/business.mjs
|
||||
c3422b1e144177f9dd3015ac036ee1d2cde02bd2b3be406364f3b3f45d8c9b73 packages/business/src/credentials.mjs
|
||||
cd4eb5960c17ce32f26d1a49196866ce04efc42c1d90b18b046af5fda8b9ff0a packages/business/src/errors.mjs
|
||||
e08b11b70b54f13e3b18996dd903f841e04fd6c64791e96063df8b164c663882 packages/business/src/hosts.mjs
|
||||
a386ce5bd1d41d86f7b90641a423a2b651b491c8989d5085412c7d202ac1cb30 packages/business/src/index.mjs
|
||||
09f2bde85a6d7a8f0b1d1c60ac589b845b0c95e991b2f807758878416b13c6bd packages/business/src/instance-settings.mjs
|
||||
e14d73f719664499d809909962a6ecc16d4ffb9d824fcdee699e0778809d9e96 packages/business/src/launch-settings.mjs
|
||||
0aa94dbd14acd379a4837cc3e70b9618b3fa797d74124314e7245a8a3070e98c packages/business/src/launch.mjs
|
||||
93a7fddac9a08b5f740a0a277b29b8a3459e6f5a4fd33a37212437cb456b9b62 packages/business/src/library-seats.mjs
|
||||
44fa089c9024934a2f9fb5ef99552eb18d616842210cbc0fc860ea32ce0b1524 packages/business/src/migrate-launch.mjs
|
||||
fa4ba1ae878cd27287865fa12115f8a6c1175a2dfd1011d5f8aca11e46e669c7 packages/business/src/organization.mjs
|
||||
9d2c68dd21c6c9553af75f4b137c4f169e95761f32528767e0518d0313311f50 packages/business/src/plugin-settings.mjs
|
||||
9472996134c520c31971e66006d1c1683709f6df4f76fe3445bdc97a18637eff packages/business/src/project.mjs
|
||||
712183465fee099606223d84423afc54e3386a0c8e468c68d5ac39c1e676d109 packages/business/src/resolve.mjs
|
||||
b10af84d7422da4d0e8c0a4fea1064eebbc2fac6a838a1b3939b554e22dedfc9 packages/business/src/role.mjs
|
||||
e1f0e70a4bbba8ae2ad6185ab61770b15acda403e90fc708e13027a1e9ec663c packages/business/src/util.mjs
|
||||
f6b15ee8dad2d985c0ae66b1f106ca46cb56ec86ac8cd5dec8a05c887596a421 packages/business/src/vars.mjs
|
||||
de1f04628e400084a46e77fd7e03c7a039f0f80c9e07bb486c9c012f187aa3eb packages/business/src/vocabulary.mjs
|
||||
a6a9971b42ddf176d9415caee3efc2eb16791dead5f0f0557d28449a550aefa1 packages/business/tests/helpers.mjs
|
||||
f0dfe004905dce31317d85d89a05802db878c3472e765e85dc9f1e04166e1df6 packages/business/tests/plugin-settings.test.mjs
|
||||
bc6b3a31e8918d70aced7151b91ac4b39afec4081054024b162acb0e8f8fae07 packages/business/tests/token-limit-settings.test.mjs
|
||||
c4949a16173d11f9d32d10d3ddd58a181631848b259bef1998820a78f5694808 packages/cli/src/access.mjs
|
||||
15a8ee212fc37cea28e389f60ddb8916f9e1509cdcfb2e522acfe548702a16dc packages/cli/src/app.mjs
|
||||
147a17bbdcbc34efe20a88a4cabe796c101cb63dce621d28103f4de29def4cc2 packages/cli/src/boot-status.mjs
|
||||
1e663b175e18e39ff68c9ac3a65ff71fc777a6c37ebca035fce6a2783d0aaac3 packages/cli/src/cli.mjs
|
||||
d960c2a9df3f7c84deff22dad1f0ab120f95ee365984e390de98eba7292b65a1 packages/cli/src/config.mjs
|
||||
19755f7bb002d8455990c5dc7c458e64aeb95252ec7231a2ed2fd9c638fcb511 packages/cli/src/credentials.mjs
|
||||
c7bdd98a3ddeeb9bc4415d907b92555d723c566eba314075d91486da9b5e85dc packages/cli/src/errors.mjs
|
||||
481d9956698df7765ca8556d57164fb78f131708a09900d5a55b9048b5638f5f packages/cli/src/format.mjs
|
||||
3076a53b9891d4d0e084306567b88ded12c4de53a943c029646a424bf59d8e49 packages/cli/src/git-socket.mjs
|
||||
b586907ca8f351f60dc19ec2683df75d2d70ddb12955d09fb14560c9d3bed3dc packages/cli/src/grants.mjs
|
||||
a0936aee783ff47dd58fc907fefd86f63e571809a3ce5b0d6d931f71e756b15e packages/cli/src/host.mjs
|
||||
60419503898f5e7f3046df5e749098728fbdfea76eb5c53b5dc9b909329abe2e packages/cli/src/hosts.mjs
|
||||
8d6dab8da62b4458477572ca1956adad57bc0b0d308df6eae57477175c345d7a packages/cli/src/instances.mjs
|
||||
373d4c028dfa6d85c748d56f56359789fe2b81987f522ac23747fd37bb5478ed packages/cli/src/launcher.mjs
|
||||
2f291a71f490f2741edada7a3e3788500f8976a08eb8ab1411f6c5982f778260 packages/cli/src/limits.mjs
|
||||
9a043f122e1d49103bab64716d0eb80cfc09da3c91f7e2eb014b0d8ff0b02f3d packages/cli/src/model-proxy.mjs
|
||||
0bdc91dcaa096bd3dc9d08a1dea59893a21f6505c843e698ad9c8daa4b74364b packages/cli/src/model-stall.mjs
|
||||
f8d9fc24ccd71494fb2914914949cb08948ae93fb3180b9531eb807c921a6f53 packages/cli/src/plugins.mjs
|
||||
6cfe7fd5086ddb59c5666060c6f8044c2852e0f3d5755b1fa206f7521173f300 packages/cli/src/project.mjs
|
||||
9d03335628ae62e85c5fbc08c2e739ed0bd43b10d486faf397129a56a1b343e0 packages/cli/src/screens.mjs
|
||||
1a30048032f5bb64419ae9716a1692978bc1a137220a094d1900298aca6ba1d7 packages/cli/src/session.mjs
|
||||
58888b7731f8009d4c3f8be2caf4445f13dd8f534e1633f6e2720b259fcc3f92 packages/cli/src/thread.mjs
|
||||
662642a8ce739fcb6c188ad07125a94e008c8a305eced127c8041d472c56e55b packages/cli/src/transport.mjs
|
||||
f9e0c69849633ae36a7a6aa22729a690dc40292178ac3db43accbb131fd7b4ca packages/cli/src/usage.mjs
|
||||
8966f1f98ea81b4525345fc4889db5e0e5263ca41b5132ac8dd9bd99a2c88522 packages/control-board/src/discord.mjs
|
||||
6d74b131af360268be748a1f8f7f2b3f5a9180365e7279426640883fc295a676 packages/control-board/src/scan.mjs
|
||||
2eb25c46e85ddadd3bdbdbe605db54a6e09845155384a209622554d78307e583 packages/control-board/src/serve.mjs
|
||||
a45beb82438bb42d97d1e322010e175e785767664e548b90c4125e98b7660003 packages/conversation/src/client.mjs
|
||||
eaf0772b60bb17fbf9548267c9cfeb0104f92f5cbafdfcb60c1633883eec6432 packages/conversation/src/framing.mjs
|
||||
da336ed2a2a149ff56ac12af2440a8353d4573c33e9069381be60f1a0ca70151 packages/conversation/src/parts.mjs
|
||||
20e781240846298fa65f9a8226b5e1ee1e81338b81229334666d845c17c99ac1 packages/conversation/src/pi.mjs
|
||||
75d0cc982c36b0a81ff23f0da9da1b56906c496250a043f91d3a3b18ffa8e51b packages/conversation/src/reader.mjs
|
||||
96f7b64c2e2c3493e270224542818fd14f042e3cf0ac14788b3f881010bc25b1 packages/conversation/src/records.mjs
|
||||
62b0f7e9f798f584fcc0e4ead0522e44fd113bd0803f2bad92ffa480cadb7527 packages/conversation/src/safe-fs.mjs
|
||||
c24d28a073659640b8b027eb12ad150ba895c3001091b892ecef2ec1da40d5cd packages/conversation/src/terminal.mjs
|
||||
f834ee740e7149e7d2ed976112d0719ce0660270e3b61cf93e1774d112c992a2 packages/conversation/src/transcript.mjs
|
||||
5ab69c4111dd9589a197172ffe6968bf414f41c552b7910e5478a27c446cfaec packages/discord/src/binding.mjs
|
||||
917b0e6c4f100e93f056b925e38d97eacdd8b2596e39fbd3f88c0b62b973d8ed packages/discord/src/errors.mjs
|
||||
c28e04a0055997ea0b34bea1ad2912adb248d5fd43713df1e6f5a661d87949b7 packages/discord/src/git.mjs
|
||||
12684e926574c3fe7f693a03b60d1393df483f5feb4b47c9dd7c5a7ac050aec5 packages/discord/src/journal.mjs
|
||||
8fa9968862dff77fa6d8be5210c22d13712fd622a8cbc722d167be5be80d0783 packages/discord/src/processing.mjs
|
||||
ba09d286e707860afa53300f8802ac8e6193ab2d2e7abe9d2b07cbdef3822387 packages/discord/src/setspark.mjs
|
||||
975503616245bb6051f06ecbf47436ce7d030f21af23042df7f3341062df967f packages/discord/src/tools.mjs
|
||||
e5a7b64720872b12b34223549537ace05ebf0ca8a29b2f844d2b7c5cc9ea41f7 packages/discord/src/web.mjs
|
||||
e944a4c7a26d1fe55e13ac1eca31dd86c302dc7c868224b8b000b27255976153 packages/harness/src/bundle.mjs
|
||||
a74ef2db4093c0c797ba9e7e28e4e4df0ceac9040385f00e60a273f39af9610b packages/harness/src/gate.mjs
|
||||
38fe84040a78c3f8a8dcde4339d88db3b5df9ef669d605ad1d92ff3e8b646b40 packages/harness/src/tools.mjs
|
||||
f710d9600a17f6e2989a289cfe84e58f161d86c7306605946ce05fa71b364eb2 packages/library/src/guard.mjs
|
||||
70c1fe75cb2149c9a074d55a6301d5b66157c2dc2e777b92bac338cce09d89c7 packages/library/src/index-build.mjs
|
||||
98c2c2877549c3e2c5963ec4e49d99ab3b6d6ad54fb3bfae86cf98542207157e packages/library/src/index.mjs
|
||||
98ef45ed61144aaea44d8aea1ac43082b6d340297e46846d01772da38728e530 packages/library/src/limits.mjs
|
||||
def32a176cb70c86248e45908edde22f9c4c5f88575a4af0a396a05f617358bc packages/library/src/links.mjs
|
||||
c83c626c7cdc2a00ba4217c34b889ca0517cd2022d1f8fc9e7d3a14a0293a802 packages/library/src/mapping.mjs
|
||||
26b824d6885e5c6d1b8bd71e754a9fa333c26307693f7e6a0c6a8e6300ecb4ae packages/library/src/mirror.mjs
|
||||
0c8764b03dae0150c56af74bcb113cf583dcbe1fa0c6f7386ef2d48d59a6bd31 packages/library/src/problems.mjs
|
||||
bafe113bee70f17bd249876d6bdd1c08fa051223c2111955e5d5f275bd76bba0 packages/library/src/query.mjs
|
||||
ea126533afb7e74b71419eb943febb6b242eb96fc6917d9df1019db3e7e6ce8d packages/library/src/reader.mjs
|
||||
bfc3de029d3c8f0dcc96c90fde30d6da58bbb5b72d8f13e3f536c0d735c73ca5 packages/library/src/render.mjs
|
||||
7b46f47b5e9d6b554b5d39bce2cd95c4610f5f35b8ab8fdc5a2864b3214be809 packages/library/src/reply-protocol.mjs
|
||||
97e12255f52ad638eeacd152eb26822f9a2aa72cd30e2fed1193f51cd6e56192 packages/library/src/scope.mjs
|
||||
6a3b4de2070e62b1cca1c0ab20f2883d3153fc61608d1bf7670cecea08765b4c packages/library/src/supporting.mjs
|
||||
016bfa5c80572c0baf90ced39cb3d3ec66d395f0be15c2727b9552a9dd849093 packages/library/src/survey.mjs
|
||||
a58f3aec5ed9b3530b363e2fdbd38bc9ded7635d261ab2fca3cb31c45dcd3dfa packages/library/src/sync.mjs
|
||||
a301b7c7e3f42f66cb69d88991220f4e236f25a6e5951c61e79ec4ef2b714198 packages/library/src/write.mjs
|
||||
889ac9589fadf7654d4dbb914f968cbafe4255ed215bd6a9ff3f331757c9017b packages/model-proxy/PIN
|
||||
f5f86cad661034f223a76352d877fa8d7883bfa921a7a01282347a9a03272441 packages/model-proxy/src/client.mjs
|
||||
a6fb88352018b8f21593a0bb9311f87162c80d8b1e05e62b4d43b1e69af21b23 packages/model-proxy/src/common.mjs
|
||||
00378d2ea95ac4945899696462f8ff4c70dc020cc58d93663d731d2f2f333783 packages/model-proxy/src/fetch.mjs
|
||||
1eac4b5741b360a077bb1c871c008b64f7c7119afc64be4d6e4a0dcdb3a313bb packages/model-proxy/src/settings.mjs
|
||||
e66453cf6662677cf28cbad1ae8f7509917d333e5b80404ab02c53f5cf75e9e1 packages/model-proxy/src/validation.mjs
|
||||
77327681d6eb51f25d7aeffcc532b7e8269c1dc59139cb03adb4a3a1409f63e9 packages/model-proxy/tests/client-probe.test.mjs
|
||||
790c6a50ec030a8b27a28fac7fd129bd9eabe79774adf11d6620c00df9b6ae86 packages/model-proxy/tests/client.test.mjs
|
||||
95e39a519f7ac8b9592876e6157191169f9b14d002163867a6ff6ab808e42c14 packages/model-proxy/tests/management-key-encoding.test.mjs
|
||||
f24e1d121a340cbcaa3f6cd6390eeb7d4b05f778dd498d76ba099cba5a719dea packages/model-proxy/tests/page-client.test.mjs
|
||||
1ad66d56800a31cfbd387939e640653bc72150f4e73822d9e3c777b3bffbf1e1 packages/model-proxy/tests/usage-client.test.mjs
|
||||
a317ac544359d321bb91b67cd87fc6ef431b72df9ac9f7f2a9ff291ed1a9109a packages/plugins/harness/claude-code/index.mjs
|
||||
aabaf5c4602e28f025c18b2e2ddd6fa0d1648870101a5de0c4424d97b24472dd packages/plugins/harness/pi/compactions.mjs
|
||||
39c225f157b8f66b416625bda689153505743ffcfdc32964bb1f3d2c6fcb73af packages/plugins/harness/pi/index.mjs
|
||||
3749b9f6dd681ef424ee7d7e4d80ccee87b3655df8cd8fe9ccd0d505dcaaee9b packages/plugins/limit-check/daily-quota/index.mjs
|
||||
4d0c6f5f87101f94608c02001a49d62cef113da48c539b2d2488dfbed1a4c524 packages/plugins/limit-check/token-limit/index.mjs
|
||||
5fcecf8336ee247e8ac2f626b21e4c79b1edc49082eadfd536cd23016c6bb756 packages/plugins/src/channel.mjs
|
||||
eaa258a1aadadb5a75450fa73fdbcea0b53636adb50ed9a508193d29d564ca78 packages/plugins/src/kinds.mjs
|
||||
2e99f9222424cf9503253701568f0bb5ef579a22930f9f224e5b63ad6b4f745f packages/plugins/src/loader.mjs
|
||||
3d4fab56fea4c45c6a317ef41121aa5b6da0502a6ef614b7931f91cafdfc1f71 packages/plugins/tests/daily-quota.test.mjs
|
||||
5d5e5dccdae3f94b8540d187a8899ec36f9c9933cae3933249c2d8c400c75aa2 packages/plugins/tests/helpers.mjs
|
||||
f3081e1dbdac20ade2246c743bcbb3934be686f79f378af21c365cd1451893ba packages/plugins/tests/kinds.test.mjs
|
||||
8588ad7eee0c9ce5de3b53e3b88562812a155a3d791a2bd3413bb1754655d78b packages/plugins/tests/loader.test.mjs
|
||||
6e96bb96278ec754ca1816a24f49ef677771615ab5cf186ae41969fc2f93d8cc packages/plugins/tests/token-limit.test.mjs
|
||||
d09ae19db3eb69477783163559bd6a8e5b59a6f5af0eafd62d0e2e3bd325065e packages/plugins/usage-source/transcript/index.mjs
|
||||
6096a577cd5d7e8bf84fd6b98ab284e2f47d5facebd027548e07e6aeec442f96 packages/plugins/usage/cliproxy-queue/index.mjs
|
||||
781973277c09133de15fc39be35b372a79066479097d46923c8ab7782f011dcd packages/processing-control/src/containers.mjs
|
||||
ddc7318297abc4ec4dd03d425820b7323db609e554cfc5341cfdfa6934271e73 packages/processing-control/src/coordinator.mjs
|
||||
3bc600649267f011e21ed8266fb16927b0ad3a0e2c49e4b54062d34c544d0c17 packages/processing-control/src/effects.mjs
|
||||
7145420aa354180689a5c84423928fc60c8123476dcfed3364c9cf4542f8c7ea packages/processing-control/src/runtimes.mjs
|
||||
ed834770fed863cb0c15b75062de1fd63dea940f3b42020b769a7e62b319c8ed packages/processing-control/src/state.mjs
|
||||
925bb03ac99e5845e4bfa20b4561a331f034f88e187db82213df6602a7ceee4b packages/project/schemas/decision.schema.json
|
||||
f069c012e9660d5d0491a21f98e936b725f6818e1c3136dfec61b3c800bd58de packages/project/schemas/project.schema.json
|
||||
79a1e7b567af7162bb88ca69861075fc579a858e8aec4e49824ccdc370b690c3 packages/project/schemas/requirement.schema.json
|
||||
af6865a4cace92ef27910098507ffedfc8dfe768cea088b1fee21d0876cc556e packages/project/src/git.mjs
|
||||
3ab38cc40ce9ed1a714a59a1f2c336c3792a59431a6a9cc655ba6a2f47513899 packages/project/src/index.mjs
|
||||
bd9debcf3f9bb92560e74f220a0b108dfe24154bc6d1fb03c5ec414356d451f9 packages/project/src/paths.mjs
|
||||
42113cd20eb8f04dd252f9963a6f1a84806af9cae7beb6808c4d584a2548220c packages/project/src/read.mjs
|
||||
e49ab5e825f0706da2f3c8dfcf33c1331a38d77ca2d35b03359ee68ea74652c5 packages/project/src/validate.mjs
|
||||
5aca02491fe8df51487968ce62c776d493d0fe693cc41478b84bef7b49c8948d packages/seat/src/checkout.mjs
|
||||
c5de99284b8fa61763b8dd30a58809bbc086529eeb10587586d52b0df2754774 packages/seat/src/compactions.mjs
|
||||
6f7c938a32b349ee49ce95b89ad499e599f6016e5e9d7efd79a9ea4177b4d175 packages/seat/src/landing.mjs
|
||||
382cbf7e0ff336911e288ce858bdbfbec693bc2b69879720d1f0b4c7d8455198 packages/seat/src/proc.mjs
|
||||
0868f393f6fb117d430428ec390e435359737eae0792b4a4d1f54797c7a6c1bf packages/seat/src/sandbox.mjs
|
||||
eec970961a667c9e614d1474d33c31a019b2cf1b0bf931a51458d874bca13a15 packages/seat/src/seat.mjs
|
||||
c37a6ef6f6d2b4e61443e77d800656bf31e38913bf7dbdc4ca955f4a83b13a41 packages/seat/src/session.mjs
|
||||
621f5c223811444336f0f5d6ad10bc7afce075491653c0527d6c26ca568b79c3 packages/seat/src/working.mjs
|
||||
80b58323994d70e8bb496d81225aeb3d2cdfda464654b68b3b082e9af1fac5c1 packages/tasks/requirements.json
|
||||
c9a883e9a1649277edce97adca40bca2874df7b5312c70e4ac6f6d4a1c860841 packages/tasks/src/fields.mjs
|
||||
38e7b85650247759f06c09fce205b2970b8368bc81491f51dc6b3c90ba2a846d packages/tasks/src/requirements.mjs
|
||||
4ebf6c2b5d71c23d85cbde83f69aa671058dc2195c9ae4bdda624f6940729d1b packages/webui/src/bus.mjs
|
||||
3a5321a5f492a98d342e4ddcc1e9da3522cfff89a4f9bc3f51d2ab1426d3de1b packages/webui/src/chat-http.mjs
|
||||
93d4d0c36d0b74eaace24bce4c3e7179b7418377eb4df6d0f6a9ca89d5eb8e39 packages/webui/src/decision-http.mjs
|
||||
c3825a02c3b4f4e5537db4a945439d707e177e74c3e8b1fc2cb777515e610b64 packages/webui/src/processing-http.mjs
|
||||
a09028cd5ca57367f597d0681e84926ca871fd4626769e9947927d949c2b6ab7 packages/webui/src/proxy-http.mjs
|
||||
3c7a35e25b4c1cfda19ac9466d4b2fbc86c880761a1d04ad3ece8bc485f60f93 packages/webui/src/public/bus.js
|
||||
46defeb3b4be0e1a22e4b89445872ad6b15cdee182076e9e6222219ae29997f4 packages/webui/src/reads.mjs
|
||||
7b7bee91604b7bd973027b177de83205db9aed366e694072fc6343b46465b5ba packages/webui/src/serve.mjs
|
||||
1c1fe0c795adac97f28502564a75f26d5666d9be5ae51169f7dd5bb7741fad16 packages/webui/src/tester-socket.mjs
|
||||
b35d3f3471d6d83ef2d19d6102eaecce2ddec9330f337d7194f1d7be03cbd216 packages/webui/tests/fixture.mjs
|
||||
39f50991578b98594183390a00efbca84fda90ef61617eea4215e2c75f90b82c packages/webui/tests/usage-render.test.mjs
|
||||
f96d06974bc83051c0d5c9000e38161ea0cc231997410bcc6c42ed7f55718dfd packages/webui/tests/usage.test.mjs
|
||||
5f63ff52aaccf06a0f2415ffdd9d1903c202679cf953bef5266a6841b5e39ab7 roles/assistant.json
|
||||
@@ -0,0 +1,202 @@
|
||||
agents/codex/work/queue-333/trace-inputs.mjs: OK
|
||||
packages/bus/schema.sql: OK
|
||||
packages/bus/src/address.mjs: OK
|
||||
packages/bus/src/broker.mjs: OK
|
||||
packages/bus/src/business.mjs: OK
|
||||
packages/bus/src/client.mjs: OK
|
||||
packages/bus/src/credential-verbs.mjs: OK
|
||||
packages/bus/src/credentials.mjs: OK
|
||||
packages/bus/src/gitea-grant.mjs: OK
|
||||
packages/bus/src/host-grant.mjs: OK
|
||||
packages/bus/src/host-run.mjs: OK
|
||||
packages/bus/src/human.mjs: OK
|
||||
packages/bus/src/interpreter.mjs: OK
|
||||
packages/bus/src/landing.mjs: OK
|
||||
packages/bus/src/limits.mjs: OK
|
||||
packages/bus/src/migrations/3b-3c.sql: OK
|
||||
packages/bus/src/migrations/3b.sql: OK
|
||||
packages/bus/src/migrations/3c-3d.sql: OK
|
||||
packages/bus/src/migrations/3d-3e.sql: OK
|
||||
packages/bus/src/migrations/3e-3f.sql: OK
|
||||
packages/bus/src/migrations/3f-3g.sql: OK
|
||||
packages/bus/src/migrations/3g-3h.sql: OK
|
||||
packages/bus/src/migrations/3h-3i.sql: OK
|
||||
packages/bus/src/migrations/3i-3j.sql: OK
|
||||
packages/bus/src/migrations/3j-3k.sql: OK
|
||||
packages/bus/src/migrations/3k-3l.sql: OK
|
||||
packages/bus/src/migrations/3l-3m.sql: OK
|
||||
packages/bus/src/migrations/3m-3n.sql: OK
|
||||
packages/bus/src/model-keys.mjs: OK
|
||||
packages/bus/src/peercred.mjs: OK
|
||||
packages/bus/src/principal.mjs: OK
|
||||
packages/bus/src/process.mjs: OK
|
||||
packages/bus/src/proxy-page-vocabulary.mjs: OK
|
||||
packages/bus/src/proxy-page.mjs: OK
|
||||
packages/bus/src/proxy-usage.mjs: OK
|
||||
packages/bus/src/runtime.mjs: OK
|
||||
packages/bus/src/server.mjs: OK
|
||||
packages/bus/src/store.mjs: OK
|
||||
packages/bus/src/tester.mjs: OK
|
||||
packages/bus/src/usage.mjs: OK
|
||||
packages/bus/src/views.mjs: OK
|
||||
packages/bus/src/web.mjs: OK
|
||||
packages/bus/tests/daily-quota-runtime.test.mjs: OK
|
||||
packages/bus/tests/limit-checks.test.mjs: OK
|
||||
packages/bus/tests/limit-stop.test.mjs: OK
|
||||
packages/bus/tests/limits-runtime.test.mjs: OK
|
||||
packages/bus/tests/p5-key-context.test.mjs: OK
|
||||
packages/bus/tests/p5-runtime.test.mjs: OK
|
||||
packages/bus/tests/plugins-verb.test.mjs: OK
|
||||
packages/bus/tests/proxy-usage.test.mjs: OK
|
||||
packages/bus/tests/usage-broker.test.mjs: OK
|
||||
packages/bus/tests/usage-runtime.test.mjs: OK
|
||||
packages/bus/tests/usage.test.mjs: OK
|
||||
packages/business/src/access.mjs: OK
|
||||
packages/business/src/business.mjs: OK
|
||||
packages/business/src/credentials.mjs: OK
|
||||
packages/business/src/errors.mjs: OK
|
||||
packages/business/src/hosts.mjs: OK
|
||||
packages/business/src/index.mjs: OK
|
||||
packages/business/src/instance-settings.mjs: OK
|
||||
packages/business/src/launch-settings.mjs: OK
|
||||
packages/business/src/launch.mjs: OK
|
||||
packages/business/src/library-seats.mjs: OK
|
||||
packages/business/src/migrate-launch.mjs: OK
|
||||
packages/business/src/organization.mjs: OK
|
||||
packages/business/src/plugin-settings.mjs: OK
|
||||
packages/business/src/project.mjs: OK
|
||||
packages/business/src/resolve.mjs: OK
|
||||
packages/business/src/role.mjs: OK
|
||||
packages/business/src/util.mjs: OK
|
||||
packages/business/src/vars.mjs: OK
|
||||
packages/business/src/vocabulary.mjs: OK
|
||||
packages/business/tests/helpers.mjs: OK
|
||||
packages/business/tests/plugin-settings.test.mjs: OK
|
||||
packages/business/tests/token-limit-settings.test.mjs: OK
|
||||
packages/cli/src/access.mjs: OK
|
||||
packages/cli/src/app.mjs: OK
|
||||
packages/cli/src/boot-status.mjs: OK
|
||||
packages/cli/src/cli.mjs: OK
|
||||
packages/cli/src/config.mjs: OK
|
||||
packages/cli/src/credentials.mjs: OK
|
||||
packages/cli/src/errors.mjs: OK
|
||||
packages/cli/src/format.mjs: OK
|
||||
packages/cli/src/git-socket.mjs: OK
|
||||
packages/cli/src/grants.mjs: OK
|
||||
packages/cli/src/host.mjs: OK
|
||||
packages/cli/src/hosts.mjs: OK
|
||||
packages/cli/src/instances.mjs: OK
|
||||
packages/cli/src/launcher.mjs: OK
|
||||
packages/cli/src/limits.mjs: OK
|
||||
packages/cli/src/model-proxy.mjs: OK
|
||||
packages/cli/src/model-stall.mjs: OK
|
||||
packages/cli/src/plugins.mjs: OK
|
||||
packages/cli/src/project.mjs: OK
|
||||
packages/cli/src/screens.mjs: OK
|
||||
packages/cli/src/session.mjs: OK
|
||||
packages/cli/src/thread.mjs: OK
|
||||
packages/cli/src/transport.mjs: OK
|
||||
packages/cli/src/usage.mjs: OK
|
||||
packages/control-board/src/discord.mjs: OK
|
||||
packages/control-board/src/scan.mjs: OK
|
||||
packages/control-board/src/serve.mjs: OK
|
||||
packages/conversation/src/client.mjs: OK
|
||||
packages/conversation/src/framing.mjs: OK
|
||||
packages/conversation/src/parts.mjs: OK
|
||||
packages/conversation/src/pi.mjs: OK
|
||||
packages/conversation/src/reader.mjs: OK
|
||||
packages/conversation/src/records.mjs: OK
|
||||
packages/conversation/src/safe-fs.mjs: OK
|
||||
packages/conversation/src/terminal.mjs: OK
|
||||
packages/conversation/src/transcript.mjs: OK
|
||||
packages/discord/src/binding.mjs: OK
|
||||
packages/discord/src/errors.mjs: OK
|
||||
packages/discord/src/git.mjs: OK
|
||||
packages/discord/src/journal.mjs: OK
|
||||
packages/discord/src/processing.mjs: OK
|
||||
packages/discord/src/setspark.mjs: OK
|
||||
packages/discord/src/tools.mjs: OK
|
||||
packages/discord/src/web.mjs: OK
|
||||
packages/harness/src/bundle.mjs: OK
|
||||
packages/harness/src/gate.mjs: OK
|
||||
packages/harness/src/tools.mjs: OK
|
||||
packages/library/src/guard.mjs: OK
|
||||
packages/library/src/index-build.mjs: OK
|
||||
packages/library/src/index.mjs: OK
|
||||
packages/library/src/limits.mjs: OK
|
||||
packages/library/src/links.mjs: OK
|
||||
packages/library/src/mapping.mjs: OK
|
||||
packages/library/src/mirror.mjs: OK
|
||||
packages/library/src/problems.mjs: OK
|
||||
packages/library/src/query.mjs: OK
|
||||
packages/library/src/reader.mjs: OK
|
||||
packages/library/src/render.mjs: OK
|
||||
packages/library/src/reply-protocol.mjs: OK
|
||||
packages/library/src/scope.mjs: OK
|
||||
packages/library/src/supporting.mjs: OK
|
||||
packages/library/src/survey.mjs: OK
|
||||
packages/library/src/sync.mjs: OK
|
||||
packages/library/src/write.mjs: OK
|
||||
packages/model-proxy/PIN: OK
|
||||
packages/model-proxy/src/client.mjs: OK
|
||||
packages/model-proxy/src/common.mjs: OK
|
||||
packages/model-proxy/src/fetch.mjs: OK
|
||||
packages/model-proxy/src/settings.mjs: OK
|
||||
packages/model-proxy/src/validation.mjs: OK
|
||||
packages/model-proxy/tests/client-probe.test.mjs: OK
|
||||
packages/model-proxy/tests/client.test.mjs: OK
|
||||
packages/model-proxy/tests/management-key-encoding.test.mjs: OK
|
||||
packages/model-proxy/tests/page-client.test.mjs: OK
|
||||
packages/model-proxy/tests/usage-client.test.mjs: OK
|
||||
packages/plugins/harness/claude-code/index.mjs: OK
|
||||
packages/plugins/harness/pi/compactions.mjs: OK
|
||||
packages/plugins/harness/pi/index.mjs: OK
|
||||
packages/plugins/limit-check/daily-quota/index.mjs: OK
|
||||
packages/plugins/limit-check/token-limit/index.mjs: OK
|
||||
packages/plugins/src/channel.mjs: OK
|
||||
packages/plugins/src/kinds.mjs: OK
|
||||
packages/plugins/src/loader.mjs: OK
|
||||
packages/plugins/tests/daily-quota.test.mjs: OK
|
||||
packages/plugins/tests/helpers.mjs: OK
|
||||
packages/plugins/tests/kinds.test.mjs: OK
|
||||
packages/plugins/tests/loader.test.mjs: OK
|
||||
packages/plugins/tests/token-limit.test.mjs: OK
|
||||
packages/plugins/usage-source/transcript/index.mjs: OK
|
||||
packages/plugins/usage/cliproxy-queue/index.mjs: OK
|
||||
packages/processing-control/src/containers.mjs: OK
|
||||
packages/processing-control/src/coordinator.mjs: OK
|
||||
packages/processing-control/src/effects.mjs: OK
|
||||
packages/processing-control/src/runtimes.mjs: OK
|
||||
packages/processing-control/src/state.mjs: OK
|
||||
packages/project/schemas/decision.schema.json: OK
|
||||
packages/project/schemas/project.schema.json: OK
|
||||
packages/project/schemas/requirement.schema.json: OK
|
||||
packages/project/src/git.mjs: OK
|
||||
packages/project/src/index.mjs: OK
|
||||
packages/project/src/paths.mjs: OK
|
||||
packages/project/src/read.mjs: OK
|
||||
packages/project/src/validate.mjs: OK
|
||||
packages/seat/src/checkout.mjs: OK
|
||||
packages/seat/src/compactions.mjs: OK
|
||||
packages/seat/src/landing.mjs: OK
|
||||
packages/seat/src/proc.mjs: OK
|
||||
packages/seat/src/sandbox.mjs: OK
|
||||
packages/seat/src/seat.mjs: OK
|
||||
packages/seat/src/session.mjs: OK
|
||||
packages/seat/src/working.mjs: OK
|
||||
packages/tasks/requirements.json: OK
|
||||
packages/tasks/src/fields.mjs: OK
|
||||
packages/tasks/src/requirements.mjs: OK
|
||||
packages/webui/src/bus.mjs: OK
|
||||
packages/webui/src/chat-http.mjs: OK
|
||||
packages/webui/src/decision-http.mjs: OK
|
||||
packages/webui/src/processing-http.mjs: OK
|
||||
packages/webui/src/proxy-http.mjs: OK
|
||||
packages/webui/src/public/bus.js: OK
|
||||
packages/webui/src/reads.mjs: OK
|
||||
packages/webui/src/serve.mjs: OK
|
||||
packages/webui/src/tester-socket.mjs: OK
|
||||
packages/webui/tests/fixture.mjs: OK
|
||||
packages/webui/tests/usage-render.test.mjs: OK
|
||||
packages/webui/tests/usage.test.mjs: OK
|
||||
roles/assistant.json: OK
|
||||
@@ -0,0 +1,26 @@
|
||||
// Final scoped verification only: records paths/hashes, never file contents.
|
||||
import fs from 'node:fs';
|
||||
import { createHash } from 'node:crypto';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { resolve, relative, isAbsolute } from 'node:path';
|
||||
import { registerHooks, syncBuiltinESMExports } from 'node:module';
|
||||
const root = process.env.P5_SOURCE_ROOT;
|
||||
const target = process.env.P5_INPUT_TRACE;
|
||||
const read = fs.readFileSync.bind(fs), append = fs.appendFileSync.bind(fs);
|
||||
const seen = new Set();
|
||||
function record(path) {
|
||||
try {
|
||||
if (path instanceof URL) path = fileURLToPath(path);
|
||||
if (typeof path !== 'string') return;
|
||||
path = resolve(path);
|
||||
const rel = relative(root, path);
|
||||
if (rel.startsWith('..') || isAbsolute(rel) || rel.startsWith('agents/codex/work/queue-333/receipts/') || rel === relative(root,target)) return;
|
||||
const sha256 = createHash('sha256').update(read(path)).digest('hex');
|
||||
const key = rel + ':' + sha256;
|
||||
if (!seen.has(key)) { seen.add(key); append(target,JSON.stringify({path:rel,sha256})+'\n'); }
|
||||
} catch {}
|
||||
}
|
||||
fs.readFileSync = function(path,...args) { const answer=read(path,...args);record(path);return answer; };
|
||||
syncBuiltinESMExports();
|
||||
registerHooks({ load(url,context,next) { const answer=next(url,context);if(url.startsWith('file:'))record(fileURLToPath(url));return answer; } });
|
||||
record(fileURLToPath(import.meta.url));
|
||||
@@ -0,0 +1,35 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
# Run from the repository root. Explicit current whole files; no package/full gate.
|
||||
p5root=$(mktemp -d /tmp/p5-scoped-XXXXXX)
|
||||
trap 'rm -rf "$p5root"' EXIT
|
||||
mkdir "$p5root/home" "$p5root/config" "$p5root/tmp"
|
||||
export HOME="$p5root/home" XDG_CONFIG_HOME="$p5root/config" TMPDIR="$p5root/tmp" MOSAIC_CONFIG="$p5root/config/absent.json"
|
||||
export P5_SOURCE_ROOT="$PWD" P5_INPUT_TRACE="$PWD/agents/codex/work/queue-333/receipts/source-inputs.raw.jsonl"
|
||||
: > "$P5_INPUT_TRACE"
|
||||
printf '%s\n' 'serial nice19; private HOME/XDG_CONFIG_HOME/TMPDIR/MOSAIC_CONFIG; unchanged whole-file budgets'
|
||||
nice -n 19 node --import ./agents/codex/work/queue-333/trace-inputs.mjs --test --test-concurrency=1 \
|
||||
packages/model-proxy/tests/usage-client.test.mjs \
|
||||
packages/model-proxy/tests/client.test.mjs \
|
||||
packages/model-proxy/tests/client-probe.test.mjs \
|
||||
packages/model-proxy/tests/page-client.test.mjs \
|
||||
packages/model-proxy/tests/management-key-encoding.test.mjs \
|
||||
packages/plugins/tests/kinds.test.mjs \
|
||||
packages/plugins/tests/loader.test.mjs \
|
||||
packages/plugins/tests/token-limit.test.mjs \
|
||||
packages/plugins/tests/daily-quota.test.mjs \
|
||||
packages/business/tests/plugin-settings.test.mjs \
|
||||
packages/business/tests/token-limit-settings.test.mjs \
|
||||
packages/bus/tests/usage.test.mjs \
|
||||
packages/bus/tests/proxy-usage.test.mjs \
|
||||
packages/bus/tests/p5-runtime.test.mjs \
|
||||
packages/bus/tests/p5-key-context.test.mjs \
|
||||
packages/bus/tests/limit-checks.test.mjs \
|
||||
packages/bus/tests/usage-runtime.test.mjs \
|
||||
packages/bus/tests/usage-broker.test.mjs \
|
||||
packages/bus/tests/daily-quota-runtime.test.mjs \
|
||||
packages/bus/tests/limits-runtime.test.mjs \
|
||||
packages/bus/tests/limit-stop.test.mjs \
|
||||
packages/bus/tests/plugins-verb.test.mjs \
|
||||
packages/webui/tests/usage.test.mjs \
|
||||
packages/webui/tests/usage-render.test.mjs
|
||||
@@ -0,0 +1,884 @@
|
||||
# Row 137 (#1631): agents land approved merges into the business working repository
|
||||
|
||||
Brief: `docs/plans/2026-10-15_q167-rows-r3.md`, section "Agents land approved
|
||||
merges into the business working repository". I designed against blob
|
||||
`f5ef29a2` (commit `c07c87fc2`, rev 1532). The row is now pinned to blob
|
||||
`6805904555dc` (rev 1564). The section differs from `f5ef29a2` in one
|
||||
paragraph, the read.mjs rule from sage-0505 and sage-0511, which this
|
||||
candidate already follows (see "Arbiter path and `gated` refusal"
|
||||
below). Owner Darkwing; reviewers Dewey and Filbert. Base `7a2987cf5` for
|
||||
rounds 1 and 2; round 3 is rebased onto `63c82f1c4`, row 139's landing.
|
||||
|
||||
The design comes first, then "As built", the docs, the test map, and the
|
||||
checks with the candidate.
|
||||
|
||||
## What lands where
|
||||
|
||||
A landing moves `refs/heads/main` in the business working repository,
|
||||
`<dataRoot>/working/<business>/<project>.git`. Nothing writes the project
|
||||
root, and canonical `refactor` is never a target. `scripts/land-work.sh`
|
||||
keeps working as it does today.
|
||||
|
||||
## The seed (working.mjs)
|
||||
|
||||
Today `seed()` fetches the project root's HEAD as `+HEAD:refs/heads/main`,
|
||||
forced, on every push and review. A landed main would be thrown away on the
|
||||
next push. The new seed:
|
||||
|
||||
1. Fetch the root's HEAD as `+HEAD:refs/heads/root`, forced. A failure
|
||||
refuses `root-unreadable`, as now.
|
||||
2. If main doesn't exist, create it at root's tip (`update-ref main <tip> ""`,
|
||||
which fails if another process created it first).
|
||||
3. If main exists, isn't root's tip, and is an ancestor of root, fast-forward
|
||||
it with `update-ref main <tip> <old>` (compare and swap).
|
||||
4. Otherwise leave main alone. It is never forced.
|
||||
|
||||
push, review and land all seed under the repository lock. Working
|
||||
repositories that exist today need no migration: the first seed after the
|
||||
change creates `refs/heads/root`, and main is already an ancestor of it.
|
||||
|
||||
### The push and fetch behaviour change
|
||||
|
||||
The brief asks for this to be named. After the first landing, main and root
|
||||
diverge until the owner brings main into the root.
|
||||
|
||||
- push's unrelated-history check still compares against main. A push whose
|
||||
commit shares no history with main refuses `unrelated-history`. If the
|
||||
owner rewrites the root's history, main keeps the old one, and pushes
|
||||
built on the rewrite refuse until main is reconciled by hand.
|
||||
- Coders clone from the project root, so a later task's branch doesn't have
|
||||
earlier landings. Its merge base with main is then the root commit it
|
||||
started from, and the reviewed diff `MB..C` is the task's own change, as
|
||||
before. Landing it on a main that has moved on can refuse `base-conflict`
|
||||
where the two touch the same lines.
|
||||
- The reviewer's fetch now also has `refs/heads/root` in the repository, so
|
||||
its `have` negotiation knows the root's commits. What the reviewer gets is
|
||||
unchanged.
|
||||
- When the owner merges main into the root, the next seed fast-forwards main
|
||||
and the two agree again.
|
||||
|
||||
## Who may land (broker)
|
||||
|
||||
The run that holds an approved `git.merge.protected` decision asks for the
|
||||
landing. Row 136 lets a later run of the same instance use it.
|
||||
|
||||
**Target rule.** The raise's `context.target` must equal the task ref named
|
||||
by the question's work ref (`vikunja:<project>/<task>` for
|
||||
`work/vikunja-<project>-<task>`). Then `#consumeAuthority` writes the record
|
||||
with that task ref as its subject, so the landing sits on the task's trail
|
||||
and `task-subject-required` can't fire. `refactor` never matches a task ref,
|
||||
so canonical refactor can't be a target, and land-work's decisions (target
|
||||
`refactor`) and agent landings (target a task ref) can't be used for each
|
||||
other.
|
||||
|
||||
**Shared checks.** `readLanding` moves from `scripts/land-work/read.mjs` to
|
||||
`packages/bus/src/landing.mjs` and takes `{ into }`:
|
||||
|
||||
- `into: 'refactor'` (land-work): the raise targets `refactor`, and read.mjs
|
||||
still checks its `--base` is `refactor`.
|
||||
- `into: 'main'` (agent landing): the raise targets the task ref.
|
||||
- Anything else refuses `target-branch`.
|
||||
|
||||
It runs over a small query adapter (`get`, `all`), so read.mjs passes its
|
||||
read-only `DatabaseSync` and the broker passes its Store. read.mjs keeps its
|
||||
CLI and its own schema check.
|
||||
|
||||
The human check (`res.by === business.human`, `via === 'cli'`, one human
|
||||
answer with no role or run) is in the shared `readLanding`. Under b2a2d741c
|
||||
(sage-0517) land-work's check never changes: canonical `refactor` stays the
|
||||
lead's landing. Only the host land op's call accepts a decision its arbiter
|
||||
resolved (REQ-DEC-2). Row 139 landed first, so round 3 adds that with the
|
||||
`arbiter` option only the broker passes, and the test that an
|
||||
arbiter-resolved merge decision raised by merge-gate lands through the host
|
||||
op. See "Round 3".
|
||||
|
||||
**New broker methods** (trusted, through the launch socket ops):
|
||||
|
||||
- `checkLand(cap, { task_ref, decision })`: the session's agent and task,
|
||||
`#checkAuthority(s, 'git.merge.protected', { decision, target: task_ref })`,
|
||||
decision not already consumed, then `readLanding` with `into: 'main'`. The
|
||||
project is the task's latest push; no push refuses `ref-moved`. A decision
|
||||
that names another project refuses `work-ref`.
|
||||
- `recordLand(cap, land)`: reruns the checks inside the transaction (the
|
||||
verdict is still the latest and approving, nothing supersedes the
|
||||
decision), then `#consumeAuthority` writes the `action.allowed` with the
|
||||
landed commit, the old main, the reviewed commit, the verdict and the
|
||||
patch-id. The decision is spent.
|
||||
- `recordEvent` reserves `action.allowed` for `git.merge.protected`, as it
|
||||
already does for `git.push.working`, so no run can write a fake landing.
|
||||
- `landHeld({ business, role, thread })`: whether that role and thread hold
|
||||
a resolved, unconsumed merge decision with the approval option. The
|
||||
launcher asks it at launch.
|
||||
|
||||
### REQ-LAND-1 and the gated path (sage-0505)
|
||||
|
||||
PRD 1.5 round 2 (row 135) says only a role whose role file grants
|
||||
`git.merge.protected` as a cross-role action may land, and an approval of a
|
||||
gated-class merge decision never lands. Row 139 takes `git.merge.protected`
|
||||
out of GATED_ONLY.
|
||||
|
||||
This row takes the current gated path. A test role file can't hold the
|
||||
grant: `role.mjs` refuses any GATED_ONLY action under `withinRole` or
|
||||
`crossRole`, and the broker's `GATED` set classifies `git.merge.protected` as
|
||||
`gated` before it reads the role file. So `checkLand` goes through
|
||||
`#checkAuthority` with class `gated`, and the tests raise gated decisions.
|
||||
|
||||
The refusal of class `gated` belongs in `checkLand` and `recordLand`, right
|
||||
after the authority check returns. The brief (c07c87fc2) says whichever of
|
||||
rows 137 and 139 lands second carries it with its test, and Sage checks
|
||||
that at each landing. Row 139 landed first as `63c82f1c4`, so round 3 adds
|
||||
the refusal, the arbiter path and both tests, and `landHeld` asks for a
|
||||
cross-role decision so the launcher binds the op only for a role that could
|
||||
land. The paragraphs above describe the rounds 1 and 2 base; "Round 3" has
|
||||
what changed.
|
||||
|
||||
## The land op (git socket)
|
||||
|
||||
The socket takes a third op, `land`, with `{ cap, task_ref, decision }`.
|
||||
The launcher binds the git socket for a run whose role and thread hold a
|
||||
merge decision (`landHeld`), as well as for the push and verdict roles it
|
||||
binds today. The bundle shows a `land_work` tool only then. The broker
|
||||
rechecks everything at request time, so binding grants nothing by itself.
|
||||
A decision resolved while a run is going can only be landed from the next
|
||||
run, because the bundle is fixed at launch.
|
||||
|
||||
### Asynchronous outcome (a choice, flagged for Sage)
|
||||
|
||||
A full gate takes longer than every timeout between the agent and the host:
|
||||
the tool call's 60 s default (`callTool`), the runner's 900 s turn and the
|
||||
git client's 300 s socket timeout. The op can't wait for it.
|
||||
|
||||
So `land` answers as soon as the gate has started:
|
||||
`{ landing: "started", base, reviewed, patch_id }`. Every check that can
|
||||
refuse before the gate answers synchronously as a refusal, as push does.
|
||||
The host finishes in the background. The outcome is two records:
|
||||
|
||||
- the `action.allowed` (landed) or `action.refused` (`gate-failed`,
|
||||
`base-moved`, `host-closing`, ...) on the task's trail, and
|
||||
- a RESULT message from the bus (`_bus`, run `bus`, as `#notice` sends) to
|
||||
the role in the decision's thread, saying what landed or why not. RESULT
|
||||
makes the runner take a turn and send no automatic reply.
|
||||
|
||||
That message is a broker change beyond "the authority check for the new op
|
||||
only". The alternative is a run that polls the trail, which needs a read op
|
||||
agents don't have. I took the message. If Sage wants the narrower scope, the
|
||||
fallback is the records alone and the role learns the outcome from its next
|
||||
launch.
|
||||
|
||||
The git socket runs one landing at a time. A second request while one is
|
||||
running refuses `land-busy`. Two full gates at once would also fight over
|
||||
Docker.
|
||||
|
||||
If the host closes during a gate, the gate's process group is killed and the
|
||||
landing is refused `host-closing`; nothing moves. If the host dies outright,
|
||||
nothing is recorded and the decision is still unspent, so the run can ask
|
||||
again.
|
||||
|
||||
### The steps
|
||||
|
||||
In order, matching land-work's refusal order and codes:
|
||||
|
||||
1. Broker `checkLand`: `decision-not-found`, `not-a-merge`, `not-resolved`,
|
||||
`not-human`, `not-merge-option`, `work-ref`, `target-branch`,
|
||||
`superseded`, `no-verdict`, `not-approved`, plus `decision-consumed`.
|
||||
2. Under the repository lock: seed; the work ref's tip must be the
|
||||
verdict's commit (`ref-moved`); OLD is main; `MB = merge-base(OLD, C)`,
|
||||
none refuses `base-conflict`; the reviewed patch is `MB..C` in land-work's
|
||||
fixed diff format, empty refuses `base-conflict`; its patch-id is taken.
|
||||
3. Root file: an added top-level file, an added top-level directory OLD
|
||||
doesn't have, or anything under `src/` or `v1/` refuses `root-file`.
|
||||
4. The squash, in a temporary index on OLD's tree: the patch is applied
|
||||
with `apply --cached`; failure refuses `base-conflict`; the patch-id of
|
||||
`OLD..tree` must equal the reviewed one (`patch-drift`). The commit is
|
||||
made with `commit-tree`, no ref, author and committer "Mosaic bus host"
|
||||
`<[email protected]>`, and land-work's message with
|
||||
`Applied-under: git socket land (bus host)`. The commit is fixed before
|
||||
the gate, so nothing the gate does can change what lands.
|
||||
5. Gate check: the project root is a mosaic-stack checkout (below) with a
|
||||
`node_modules`; otherwise `gate-missing`. This is the last synchronous
|
||||
refusal; the op answers "started" here.
|
||||
6. The gate, outside the lock, in a detached worktree of the new commit
|
||||
with the root's `node_modules` linked. A failing step refuses
|
||||
`gate-failed` with the step and its log.
|
||||
7. Under the lock: `update-ref main NEW OLD`; failure refuses `base-moved`.
|
||||
Then `recordLand`. If recording throws, main goes back with
|
||||
`update-ref main OLD NEW`; if that fails too, the refusal is
|
||||
`rollback-failed` and names both commits.
|
||||
|
||||
The worktree, its `node_modules` link and the Docker network
|
||||
`<name>_default` are removed on every path. Logs stay under
|
||||
`<dataRoot>/bus-host/land/<id>/`.
|
||||
|
||||
### The exact mosaic-stack check
|
||||
|
||||
`git -C <root> merge-base --is-ancestor c2365ae5190aee751bfbd0a3d47105a706adb5e7 HEAD`.
|
||||
c2365ae5 is the new foundation's root commit ("chore: baseline container POC
|
||||
and atomic foundation plan", 2026-09-02, tag `poc-container-hello-v0`). The
|
||||
repository has three root commits (c2365ae5, e7f338e3, ecde7443); a project
|
||||
without c2365ae5 in its history isn't this one. The root must also have a
|
||||
`node_modules` directory, which the gate links.
|
||||
|
||||
### The gate
|
||||
|
||||
One definition, in `packages/seat/src/landing.mjs`, used by the host and by
|
||||
land-work.sh: every `packages/<p>/tests/*.test.mjs` suite except queue's
|
||||
(`scripts/test-queue.sh` runs those), then every `scripts/test-*.sh`, each
|
||||
step logged to `<step>.log` and summarised in `gate.log` with land-work's
|
||||
line format, ending `GATE_PASSED`. land-work.sh calls it through node and
|
||||
keeps its own worktree, refusal messages and Docker cleanup. The root-file
|
||||
rule moves to the same module.
|
||||
|
||||
The gate runs reviewed, agent-authored code on the host, outside a sandbox,
|
||||
with the host's environment. land-work.sh does the same today under the
|
||||
conductor. Here a human-resolved decision and an approving review are what
|
||||
authorize it.
|
||||
|
||||
## Harness
|
||||
|
||||
- `land_work` tool, verb `working.land`, in `tools.mjs`, shown when the
|
||||
launcher says the session may land.
|
||||
- `landWork()` client in `git-tools.mjs`.
|
||||
- runner local handler for `working.land` over the session's git socket.
|
||||
|
||||
## Out of scope
|
||||
|
||||
Routing and GATED_ONLY (row 139), the merge-gate role (row 149), any push
|
||||
to a remote, force-push or history rewrite.
|
||||
|
||||
## As built: where the candidate differs from the design above
|
||||
|
||||
- **The squash is made in a worktree, not a temporary index.** prepareLand
|
||||
adds a detached worktree of the bare repository at main under
|
||||
`bus-host/land/<id>/<id>` and applies the reviewed patch there with
|
||||
`git apply --index`. The applied diff (`--cached` against OLD) must have
|
||||
the reviewed patch-id. `write-tree`, `commit-tree` with OLD as the one
|
||||
parent, then `reset --soft` to the squash, so the gate runs in the tree
|
||||
that lands. The worktree goes on every refusal and at the end
|
||||
(`dropLand`, which removes the `node_modules` symlink first).
|
||||
- **Patches are written by git.** Both diffs go through
|
||||
`git diff --output=<file>` with fixed prefixes, no textconv and no
|
||||
external diff, and patch-id reads the file. A file that isn't UTF-8
|
||||
keeps its patch-id.
|
||||
- **Order.** The root-file check runs before the worktree is added, so a
|
||||
root-file refusal never touches the object store beyond reading.
|
||||
gate-missing comes after prepareLand, so the squash exists when the
|
||||
host answers `started`.
|
||||
- **The `started` answer carries `commit`**, the squash, besides `base`,
|
||||
`reviewed` and `patch_id`. An agent can say what will land.
|
||||
- **Tickets.** checkLand returns a ticket the host passes to recordLand
|
||||
and landRefused. A ticket outlives the run that asked, since the gate
|
||||
may end after the run did. An unknown ticket refuses `land-unknown`.
|
||||
recordLand checks authority with `#authorityFor` (the holder check is
|
||||
left out for that reason) and reruns the landing checks in the
|
||||
transaction; it writes the `action.allowed` itself rather than through
|
||||
`#consumeAuthority`, which would ask for the claim again.
|
||||
- **`no-subject`.** land-work refuses a landing with no subject and no
|
||||
`--subject`. An agent has no `--subject`, so checkLand refuses a merge
|
||||
option with no first line `no-subject`.
|
||||
- **`decision-consumed`** is checked in checkLand and again in recordLand.
|
||||
- **The gate's environment.** The host runs the gate with `gateEnv`: PATH,
|
||||
HOME, USER, LOGNAME, SHELL, LANG, LC_ALL, TZ, TERM, TMPDIR,
|
||||
XDG_RUNTIME_DIR and DOCKER_HOST only. This replaces "with the host's
|
||||
environment" in the gate section. land-work.sh keeps the conductor's.
|
||||
- **isMosaicStack is async** and runs git through `runGit` with only the
|
||||
environment's PATH, hooks at /dev/null and fsmonitor off.
|
||||
- **The gate is injectable.** `createGitSocket({gate})` takes `LAND_GATE`'s
|
||||
shape, `{classify, run, dropNetwork}`, so the socket tests run a fake
|
||||
gate. A test checks that `LAND_GATE` holds the real `isMosaicStack` and
|
||||
`runGate`, and the refusals test runs the real classifier on a fixture
|
||||
project for gate-missing.
|
||||
- **Harness.** `land_work` has no clone requirement and sits between
|
||||
`push_working` and `request_review`. The prompt line (round 3 wording):
|
||||
"Landing: once your merge decision is approved, land_work it with the task. The
|
||||
reply only says the landing started; the gate's outcome comes later as a
|
||||
RESULT from the bus. Don't land again while one is running." The
|
||||
launcher asks `landHeld` with the run's role instance and thread and
|
||||
binds the git socket when it answers true.
|
||||
- **The runner's `working.land` route has no test of its own.** Neither do
|
||||
`working.push` and `working.fetch`. `landWork` is tested in
|
||||
git-tools.test.mjs against a fake host socket, and the launcher test
|
||||
checks the bundle and `session.json`.
|
||||
- **Arbiter path and `gated` refusal** (sage-0511, sage-0517, sage-0565):
|
||||
rounds 1 and 2 left both out, since row 139 hadn't landed, and both
|
||||
callers of `readLanding` required a human/cli resolution. Row 139 landed
|
||||
first, so round 3 adds them (see "Round 3"). land-work's check in
|
||||
`scripts/land-work/read.mjs` is unchanged in effect in every round.
|
||||
- **The raise is found by its body, not its subject.** read.mjs looked
|
||||
for the decision.raise `action.allowed` with `subject` equal to the
|
||||
decision id. The broker files a raise under its task ref when it has
|
||||
one (`a.task_ref ?? target-if-task-ref ?? id`), so every decision raised
|
||||
for a task, which is every one the host op lands, came back
|
||||
decision-not-found. The first gate run caught it (six land.test
|
||||
failures). `readLanding` now matches the business, the kind, the
|
||||
operation and `body.decision`, as the broker's own raise lookups do.
|
||||
For land-work this changes one thing: a refactor decision raised with a
|
||||
`task_ref` used to refuse decision-not-found and now reaches the checks
|
||||
after it, where a `task_ref` that disagrees with the question refuses
|
||||
work-ref. That branch existed in read.mjs but no real raise could reach
|
||||
it; the fixture in test-land-work.sh files every raise under the
|
||||
decision id, so its cases are unchanged. The human-only check is
|
||||
untouched. `recordEvent` refuses an `action.allowed` whose action is
|
||||
`git.merge.protected`, so an adapter can't add a second raise that
|
||||
passes.
|
||||
- **landing.mjs is a runner file.** The broker imports it, so it joins
|
||||
`RUNNER_FILES` in packages/seat/src/sandbox.mjs, and the bus import
|
||||
closure test (project-runtime.test.mjs, row 138) lists the new import
|
||||
and checks that landing.mjs imports nothing.
|
||||
- **thread-launch.test.mjs's host answers landHeld.** Its in-process host
|
||||
lists the launch ops it serves, and every launch now asks `landHeld`, so
|
||||
five of its tests failed with "invalid-host-request" until the op was
|
||||
added beside `threadIdle`.
|
||||
|
||||
## Docs
|
||||
|
||||
Only the landing paragraphs the brief names:
|
||||
|
||||
- `packages/seat/README.md`: push step 2 and the review paragraph now
|
||||
describe the root seed; "No other ref moves" names the seed's refs; a new
|
||||
"Landing on main (#1631)" subsection covers prepareLand, finishLand,
|
||||
dropLand and `src/landing.mjs`; the sandbox bind list adds `landHeld`.
|
||||
- `packages/cli/README.md`, "Git socket": the bind rule, a `land` row in
|
||||
the op table, `checkLand` in the check order, a landing paragraph (steps,
|
||||
land-busy, landRefused, the RESULT outcome, logs, `LAND_GATE`), and
|
||||
close() stopping a gate.
|
||||
- `packages/bus/README.md`: the four row 137 ops and the ticket.
|
||||
- `packages/harness/README.md`: the `land_work` paragraph, runner step 3,
|
||||
the git socket bind rule.
|
||||
- `docs/TOOLS.md`: one paragraph after land-work's on the shared modules.
|
||||
|
||||
Each passes `tools/unslop-hook/unslop-check.js`.
|
||||
|
||||
## Tests, against the brief's list
|
||||
|
||||
| Brief | Test |
|
||||
|---|---|
|
||||
| A reseed moves root and leaves a landed main | working.test "a reseed moves root but leaves a landed main, and main forwards once root contains it" |
|
||||
| main fast-forwards to root when it's an ancestor, stays put when it isn't | the same test, and "after a landing, a push built on the root still lands and main stays where the landing put it" |
|
||||
| push's unrelated-history check against main | working.test "a branch with no history in common with main refuses unrelated-history", where main and root are the same commit, and (round 2) "once the root shares no history with a landed main, a push is checked against main, not the root", where they share nothing: a push built on main lands and one built on the root refuses |
|
||||
| A mosaic-stack checkout runs the gate | landing.test "isMosaicStack: ... node_modules; nothing else" (true on a child of the root commit) and the runGate tests; git-socket.test "land: the squash runs the gate in its own worktree, then main moves and the broker records it" with a classifier that says yes |
|
||||
| Another project refuses gate-missing | git-socket.test "land: refusals before the gate ..." with the real `isMosaicStack` on the fixture project |
|
||||
| Each land-work refusal code | On the shared module: `scripts/test-land-work.sh` runs every `readLanding` code through land-work (`into: 'refactor'`), unchanged from row 116. On the host side: land.test "checkLand refuses on the decision and the review" (the broker's decision-not-found, decision-not-approved, decision-mismatch, no-verdict, ref-moved), "checkLand refuses with land-work's codes past the authority check..." (work-ref twice, target-branch, superseded, not-approved, and a `refactor` decision refused decision-mismatch), "no-subject", and decision-consumed in the first test; working.test ref-moved, base-conflict, root-file, base-moved, rollback-failed, and (round 2) patch-drift, with a git first on the PATH that adds a line to what `apply --index` staged, as test-land-work.sh does; git-socket.test gate-missing, gate-failed, land-busy, host-closing, unknown-project and a broker refusal at record |
|
||||
|
||||
On the host side, `#checkAuthority` runs first, so `not-a-merge`,
|
||||
`not-resolved` and `not-merge-option` reach the role as the broker's
|
||||
`decision-mismatch` or `decision-not-approved`. In rounds 1 and 2,
|
||||
`not-human` couldn't happen there, since only the human resolved a gated
|
||||
decision. In round 3 it still can't reach checkLand: a gated decision
|
||||
refuses `not-authorized` first, and the broker resolves a cross-role one
|
||||
only through its route, the arbiter or the human. The round 3 test checks
|
||||
`not-human` on `readLanding` directly instead (see "Round 3").
|
||||
|
||||
Also new: landing.test (rootHits, gateEnv, gateSteps, runGate pass, fail
|
||||
and abort, the CLI), land.test (ticket, landRefused, landHeld, the
|
||||
reserved event), the launcher test for `landHeld` binding, and the
|
||||
harness tests for the tool, the prompt line and `landWork`.
|
||||
`scripts/test-land-work.sh` is unchanged and runs land-work through the
|
||||
shared gate and root-file CLI.
|
||||
|
||||
## Candidate
|
||||
|
||||
`r1/build.patch` against BASE `7a2987cf5`
|
||||
(sha256 `49d5048f6bb53e1b546a6b2dbdec14ef4a9bfe5087f20e218018a62481266611`).
|
||||
`r1/candidate-manifest.sha256` lists the 31 files: 27 changed and 4 new.
|
||||
The new ones are packages/bus/src/landing.mjs, packages/bus/tests/land.test.mjs,
|
||||
packages/seat/src/landing.mjs and packages/seat/tests/landing.test.mjs.
|
||||
I applied the patch to a fresh worktree at BASE, `sha256sum -c` passed on
|
||||
every line, and I removed that worktree. Canonical HEAD was `b71268b8e` at
|
||||
18:56Z. `git diff 7a2987cf5 b71268b8e` on the 27 changed paths is empty, and
|
||||
none of the 4 new paths exists at HEAD.
|
||||
|
||||
## Checks
|
||||
|
||||
The slot was mine from 18:37Z (sage-0519) until 18:55:30Z. `r1/gate.sh`
|
||||
runs `node --test tests/*.test.mjs` in every package with a tests/
|
||||
directory except queue (test-queue.sh runs that suite), then every
|
||||
`scripts/test-*.sh`. The suites run one after another, each teed to its own
|
||||
log, and the script stops at the first failure. TMPDIR was
|
||||
`~/darkwing-scratch/r137/tmp`. cli's launcher.test ran on its own under the
|
||||
session's inherited TMPDIR, because the bwrap runner fails "did not start"
|
||||
under an override. DOCKER_HOST was unset, Docker 29.7.2 was up, and
|
||||
COMPOSE_PROJECT_NAME was `darkwing-r137`. An EXIT trap removes
|
||||
`darkwing-r137_default` only when it has 0 containers.
|
||||
|
||||
Round 5, the candidate, ran from 18:49:43 to 18:55:25 UTC and ended
|
||||
GATE_PASSED (`r1/gate-run.log`, step logs in `r1/gate/`):
|
||||
|
||||
| Step | Pass | Fail |
|
||||
|---|---|---|
|
||||
| bus | 302 | 0 |
|
||||
| business | 109 | 0 |
|
||||
| cli (all but launcher) | 202 | 0 |
|
||||
| cli launcher.test, inherited TMPDIR | 19 | 0 |
|
||||
| control-board | 124 | 0 |
|
||||
| conversation | 182 | 0 |
|
||||
| discord | 183 | 0 |
|
||||
| harness | 108 | 0 |
|
||||
| ledger | 86 | 0 |
|
||||
| mosaic | 69 | 0 |
|
||||
| plugins | 28 | 0 |
|
||||
| project | 30 | 0 |
|
||||
| runs | 43 | 0 |
|
||||
| seat | 148 | 0 |
|
||||
| tasks | 97 | 0 |
|
||||
| webui | 113 | 0 |
|
||||
| test-auth | 15 | 0 |
|
||||
| test-conductor | 17 | 0 |
|
||||
| test-config | 24 | 0 |
|
||||
| test-discord | 78 | 0 |
|
||||
| test-extension-package | 18 | 0 |
|
||||
| test-foundation | 44 | 0 |
|
||||
| test-land-work | 84 | 0 |
|
||||
| test-queue | 156 node, 28 suite | 0 |
|
||||
| test-release | 14 | 0 |
|
||||
| test-task | 98 | 0 |
|
||||
|
||||
The trap printed "network darkwing-r137_default removed". Afterwards no
|
||||
Docker network created today remained, no container carried the
|
||||
darkwing-r137 project label, and no node or docker process of mine had a
|
||||
cwd under my r137 scratch.
|
||||
|
||||
Rounds 1 to 4 each stopped on a fault in the candidate or its tests. None
|
||||
was load or timing (sage-0527). Each fix was rerun singly before the next
|
||||
round. The round summaries, the failing step logs and the reruns I logged
|
||||
are in `r1/earlier/`. The git-socket rerun in round 2 has no saved log;
|
||||
round 5 covers it.
|
||||
|
||||
1. Round 1, bus, 295 pass, 7 fail. Six land.test tests refused
|
||||
decision-not-found, the raise lookup described in "As built". The
|
||||
project-runtime import closure test didn't list the broker's new import.
|
||||
After both fixes, land.test and project-runtime.test passed 11 of 11.
|
||||
2. Round 2, cli, 196 pass, 6 fail. git-socket.test expected a newline
|
||||
after the Applied-under line, which `w.git` trims, so the test now
|
||||
anchors that line at the end of the message. Five thread-launch tests
|
||||
failed because the test host lacked `landHeld`. A rerun under the
|
||||
inherited TMPDIR failed the same five (`r2-thread-launch-inherited-tmpdir.log`),
|
||||
which ruled out TMPDIR. With the op added, the file passed 8 of 8.
|
||||
This round also changed gate.sh: its launcher line used `env -u TMPDIR`,
|
||||
and it now passes the inherited TMPDIR.
|
||||
3. Round 3, cli launcher.test, 18 pass, 1 fail. The `landHeld` test's
|
||||
wrapper used `Object.assign` on a host whose `op` is a read-only
|
||||
inherited property and threw a TypeError. It now uses `Object.create`.
|
||||
19 of 19 passed, 0 skipped.
|
||||
4. Round 4, seat, 146 pass, 2 fail. Two runGate tests named their "must
|
||||
not run" script test-three.sh, which sorts before test-two.sh, so it
|
||||
ran first. It is now test-z.sh, with a comment saying why. landing.test
|
||||
passed 8 of 8.
|
||||
|
||||
Researcher's row 148 gate ran from /mnt/storage/scratch/researcher/q148
|
||||
during my slot (sage-0527). I didn't look inside that directory. Each
|
||||
failure above traces to a line in the candidate or its tests, so I
|
||||
changed code rather than rerunning for a flake.
|
||||
|
||||
Not run: mutants. Builder rounds may be targeted (decision 136), and the
|
||||
reviewers have the gate above.
|
||||
|
||||
## Round 2 (Filbert's comment 28782, sage-0541)
|
||||
|
||||
Filbert asked for two tests the brief requires. Both are in
|
||||
packages/seat/tests/working.test.mjs, the only file that changed.
|
||||
|
||||
- B1, "a landing whose applied diff isn't the reviewed one refuses
|
||||
patch-drift and leaves no worktree". A `git` first on the PATH runs the
|
||||
real git, then adds a line to the README that `apply --index` staged, as
|
||||
scripts/test-land-work.sh does for land-work. prepareLand refuses
|
||||
`patch-drift`, main stays put and no worktree is left. The same landing
|
||||
with the real git then prepares.
|
||||
- B2, "once the root shares no history with a landed main, a push is
|
||||
checked against main, not the root". After a landing, the owner starts
|
||||
the root over on an orphan branch. The seed moves root to it and leaves
|
||||
main. A push built on main lands, and a push built on the new root
|
||||
refuses `unrelated-history`.
|
||||
|
||||
Also fixed: the stale "Row 139 isn't built yet" in "Arbiter path and
|
||||
`gated` refusal left out". The test table above names both tests.
|
||||
|
||||
### Candidate, round 2
|
||||
|
||||
`r2/build.patch` against BASE `7a2987cf5`
|
||||
(sha256 `383fc8329ef340f804de68f981146593bf06e597481991fa9889649e29cb8691`).
|
||||
`r2/candidate-manifest.sha256` (sha256
|
||||
`3311b46a61e525a1897190bbce05de15a850843d00fce4497ef3d4828434c09f`) lists
|
||||
the same 31 paths as r1. Only the working.test.mjs line differs. I applied
|
||||
the patch to a fresh worktree at BASE: `sha256sum -c` passed on every line
|
||||
and `git diff --cached --check` was clean (31 files, +2043 -255). Canonical
|
||||
HEAD was `96fd8593e`, and `git diff 7a2987cf5 96fd8593e` on the 31 paths is
|
||||
empty.
|
||||
|
||||
### Checks, round 2
|
||||
|
||||
The slot was mine from 19:18Z (sage-0547). This round was targeted
|
||||
(decision 136). `r2/round.sh` ran each file singly with TMPDIR
|
||||
`~/darkwing-scratch/r137/tmp` and no Docker, then probed each check the way
|
||||
Filbert did. A probe edits working.mjs in place, runs working.test, and
|
||||
restores the file. The script then checks working.mjs's sha256 against the
|
||||
one it started with, and it must fail on exactly the new test. Output is in
|
||||
`r2/gate-run.log`, step logs in `r2/gate/`.
|
||||
|
||||
| Step | Pass | Fail |
|
||||
|---|---|---|
|
||||
| seat working.test, candidate | 26 | 0 |
|
||||
| cli git-socket.test, candidate | 23 | 0 |
|
||||
| probe B1: line 348 `if (false) refuse("patch-drift", ...)` | 25 | 1 |
|
||||
| probe B2: line 224 merge-base against `refs/heads/root` | 25 | 1 |
|
||||
| seat, whole suite, restored candidate | 150 | 0 |
|
||||
|
||||
- Probe B1 failed only "a landing whose applied diff isn't the reviewed one
|
||||
refuses patch-drift and leaves no worktree", with "Missing expected
|
||||
rejection".
|
||||
- Probe B2 failed only "once the root shares no history with a landed main,
|
||||
a push is checked against main, not the root". The push built on main
|
||||
refused `unrelated-history`.
|
||||
|
||||
After each probe working.mjs was back at
|
||||
`0d332d73596e94d2114751c1924c4f8463c387aba9ffdb0924d61f6228e1c463`, its
|
||||
manifest hash. Afterwards `sha256sum -c` on the r2 manifest passed in my
|
||||
worktree, no `.orig` file was left, and no node process of mine was
|
||||
running.
|
||||
|
||||
Not run in this round: the other package suites, the scripts/test-*.sh and
|
||||
mutants. Round 2 changes one test file. The r1 gate above covers the other
|
||||
30 paths, which are unchanged.
|
||||
|
||||
## Round 3 (sage-0565): rebased onto row 139, with both carry items
|
||||
|
||||
Row 139 landed first as `63c82f1c4`, so this row carries the two items the
|
||||
brief gives the second lander (brief blob `6805904555dc`). The r2 patch
|
||||
applied to `63c82f1c4` without a conflict. B1 and B2 are unchanged.
|
||||
|
||||
### What row 139 changed under this row
|
||||
|
||||
In broker.mjs, `GATED` is now the hard-wait set, and vocabulary.mjs's
|
||||
`GATED_ONLY` matches it. `git.merge.protected` isn't in it. A role file
|
||||
may grant a merge cross-role, and a business that grants a hard wait at
|
||||
either class refuses `invalid-authority` (REQ-WAIT-2). So a hard wait is
|
||||
never a cross-role decision. decision.raise routes:
|
||||
|
||||
- cross-role to `arbiters[domain]`, or to the human when the arbiter is
|
||||
the raiser's own role;
|
||||
- gated and cited to the arbiter;
|
||||
- gated and uncited, or any hard wait, to the human.
|
||||
|
||||
An agent's resolution writes `via: 'broker'` with its run as `by`. A
|
||||
human-routed decision resolved by an agent refuses `human-required`.
|
||||
|
||||
### (a) REQ-LAND-1: a gated merge decision never lands
|
||||
|
||||
`#landFacts` starts with `if (cls === 'gated') fail('not-authorized')`.
|
||||
checkLand passes the class `#checkAuthority` returned, and recordLand
|
||||
passes the one from `#authorityFor`, so both run the same line. The class
|
||||
can't change between the two: `#authorityFor` requires the decision's class
|
||||
to be the one the role holds. The refusal comes before
|
||||
`decision-consumed` and `readLanding`, so who resolved a gated decision
|
||||
doesn't matter.
|
||||
|
||||
### (b) REQ-DEC-2: the host op accepts an arbiter-resolved merge
|
||||
|
||||
`readLanding` takes `{ into, arbiter = false }`. It accepts a resolution
|
||||
when one of these holds:
|
||||
|
||||
- the human resolved it through the CLI with one human answer, the check
|
||||
rounds 1 and 2 already had; or
|
||||
- `arbiter` is true, the decision is `cross-role`, its `route_to` isn't
|
||||
`human`, the resolution came `via: 'broker'`, and there is no human
|
||||
answer.
|
||||
|
||||
Only the broker's `#landFacts` passes `arbiter: true`. read.mjs is
|
||||
unchanged, so land-work passes nothing and stays human-only (item 4). The
|
||||
route check holds because the broker lets only a run of the `route_to` role
|
||||
resolve an agent-routed decision.
|
||||
|
||||
### Item 5: no hard wait through the arbiter path
|
||||
|
||||
A hard wait can't reach the arbiter path, for three reasons:
|
||||
|
||||
1. `readLanding` refuses `not-a-merge` for any action but
|
||||
`git.merge.protected`, which isn't a hard wait.
|
||||
2. The arbiter path takes only `cross-role`, and REQ-WAIT-2 keeps a hard
|
||||
wait out of that class.
|
||||
3. A gated decision refuses `not-authorized` before `readLanding` runs.
|
||||
|
||||
### landHeld and the prompt
|
||||
|
||||
`landHeld` now skips any decision that isn't `cross-role`, so the launcher
|
||||
binds the land op only for a role that could land. The bundle's prompt
|
||||
line no longer says the human approved the merge. It reads "Landing: once
|
||||
your merge decision is approved, land_work it with the task." The harness
|
||||
bundle test and the cli launcher test assert it.
|
||||
|
||||
### Tests (packages/bus/tests/land.test.mjs)
|
||||
|
||||
The world gains a `merge-gate` role granted `git.merge.protected`
|
||||
cross-role, with pm as the technical and delivery arbiter. The landing
|
||||
tests now use it instead of a coder raising a gated decision.
|
||||
|
||||
- **(b)**, "REQ-DEC-2: a merge-gate raise its arbiter resolved lands
|
||||
through the host op: ...". The raise routes `cross-role` to pm, and pm
|
||||
resolves it (`by: 'pm-run'`, `via: 'broker'`). `readLanding` without
|
||||
`arbiter` refuses `not-human` on it. checkLand answers the facts with
|
||||
`by: 'pm-run'`, and recordLand writes the merge event with class
|
||||
`cross-role` and spends the decision once.
|
||||
- **(a)**, "REQ-LAND-1: a gated merge decision refuses not-authorized,
|
||||
cited and approved by the arbiter or uncited and approved by the human".
|
||||
On row 139's spec fixture, the coder pushes, gets an approving review and
|
||||
raises a merge citing `spec/north-star.md` at the fixture commit. The
|
||||
raise routes `gated` to pm, and pm approves. checkLand refuses
|
||||
`not-authorized`, `readLanding` with `arbiter: true` refuses `not-human`,
|
||||
and landHeld is false. Then, uncited: the raise routes `gated` to the
|
||||
human, the human approves, and checkLand still refuses `not-authorized`.
|
||||
Nothing merges.
|
||||
- New: "a cross-role merge that routes to the human, because merge-gate is
|
||||
its own arbiter, lands on the human's CLI answer". pm's resolve refuses
|
||||
`human-required`; the human's lands with `by` set to the human.
|
||||
- landHeld's test adds a coder's gated decision approved by the human,
|
||||
for which landHeld is false.
|
||||
|
||||
`not-human` still can't reach checkLand (see the test table above). A
|
||||
comment above the land-work codes test says so.
|
||||
|
||||
### Docs, round 3
|
||||
|
||||
- `packages/bus/README.md`: land-work accepts only a human CLI resolution;
|
||||
the broker's `arbiter: true` also accepts a cross-role decision its
|
||||
arbiter resolved; `not-authorized` for gated (REQ-LAND-1); checkLand and
|
||||
landHeld name `cross-role`.
|
||||
- `packages/cli/README.md`: a role granted the merge cross-role lands once
|
||||
its arbiter or the human approved the decision.
|
||||
- `packages/cli/tests/git-socket.test.mjs`: one comment. Its broker is a
|
||||
stand-in, and no logic changed.
|
||||
|
||||
### Candidate, round 3
|
||||
|
||||
`r3/build.patch` against BASE `63c82f1c4`
|
||||
(sha256 `52c1f1d6564d9e5e12b5708cbf2f12675dee0582b5fc42ece2fcc203fb5b2a7a`).
|
||||
`r3/candidate-manifest.sha256` (sha256
|
||||
`0fae2b6fa41f1cbcf2117b637a2f7a89cb2af209bf32647f0afc1612a9a34e16`) lists
|
||||
the same 31 paths as r2. Round 3 changed 9 of them: the bus and cli
|
||||
READMEs, broker.mjs, landing.mjs, land.test.mjs, git-socket.test.mjs,
|
||||
launcher.test.mjs, bundle.mjs and bundle.test.mjs. I applied the patch to a
|
||||
fresh worktree at BASE. `sha256sum -c` passed on every line, and
|
||||
`git diff --cached --check` was clean (31 files, +2115 -255). I removed
|
||||
that worktree. Canonical HEAD was `c492f4aaa`, and
|
||||
`git diff 63c82f1c4 c492f4aaa` on the 31 paths is empty.
|
||||
|
||||
### Checks, round 3
|
||||
|
||||
The slot was mine from 19:43:51Z to 19:46:02Z (sage-0569). Before the
|
||||
start, /proc showed no `node --test` process outside my own cwd. This
|
||||
round was targeted (decision 136). `r3/round.sh` ran every test file the
|
||||
candidate touches, plus row 139's hard-waits.test, each on its own with
|
||||
TMPDIR `~/darkwing-scratch/r137/tmp` and no Docker. cli launcher.test and
|
||||
thread-launch.test ran under the inherited TMPDIR. Then came
|
||||
scripts/test-land-work.sh and one kill per check. A kill edits one source
|
||||
file in place, runs one test file, which must fail on the named test, and
|
||||
restores the file. The script checks each restored file against its
|
||||
starting sha256. Last came the whole bus and seat suites. Output is in
|
||||
`r3/gate-run.log`, step logs in `r3/gate/`. It ran from 19:43:51 to
|
||||
19:45:35 UTC and ended ROUND_PASSED.
|
||||
|
||||
| Step | Pass | Fail |
|
||||
|---|---|---|
|
||||
| bus land.test | 10 | 0 |
|
||||
| bus hard-waits.test (row 139) | 12 | 0 |
|
||||
| bus project-runtime.test | 3 | 0 |
|
||||
| seat landing.test | 8 | 0 |
|
||||
| seat working.test | 26 | 0 |
|
||||
| harness bundle.test | 22 | 0 |
|
||||
| harness git-tools.test | 5 | 0 |
|
||||
| harness tools.test | 19 | 0 |
|
||||
| cli git-socket.test | 23 | 0 |
|
||||
| cli launcher.test, inherited TMPDIR | 19 | 0 |
|
||||
| cli thread-launch.test, inherited TMPDIR | 8 | 0 |
|
||||
| scripts/test-land-work.sh | 86 | 0 |
|
||||
| bus, whole suite, restored candidate | 316 | 0 |
|
||||
| seat, whole suite, restored candidate | 150 | 0 |
|
||||
|
||||
0 skipped in each.
|
||||
|
||||
| Kill | Edit | Must fail | Failing |
|
||||
|---|---|---|---|
|
||||
| B1 | working.mjs:348 `if (false) refuse("patch-drift", ...)` | the patch-drift test, exactly 1 | 1 |
|
||||
| B2 | working.mjs:224 merge-base against `refs/heads/root` | the root-history test, exactly 1 | 1 |
|
||||
| (a) gated refusal | broker.mjs:815 `if (false) fail('not-authorized')` | REQ-LAND-1, exactly 1 | 1 |
|
||||
| (b) arbiter path | landing.mjs:112 `arbitrated = false && ...` | REQ-DEC-2, one or more | 6 |
|
||||
| item 5, cross-role only | landing.mjs:112 drops `d.class === 'cross-role'` | REQ-LAND-1, exactly 1 | 1 |
|
||||
| land-work stays human-only | landing.mjs:91 `arbiter = true` | REQ-DEC-2, exactly 1 | 1 |
|
||||
| landHeld cross-role | broker.mjs:924 drops `d.class !== 'cross-role'` | the landHeld test, one or more | 2 |
|
||||
|
||||
- Kill (b) fails all 6 land.test tests that land or check an
|
||||
arbiter-resolved merge.
|
||||
- The item 5 kill fails only REQ-LAND-1. With the gated refusal in place,
|
||||
the `readLanding` call with `arbiter: true` on the arbiter-resolved gated
|
||||
decision is the only check that sees it.
|
||||
- The arbiter-default kill fails REQ-DEC-2 on its `readLanding` call
|
||||
without `arbiter`, which must refuse `not-human`.
|
||||
- The landHeld kill fails the landHeld test and REQ-LAND-1, since both
|
||||
assert landHeld is false for a gated decision.
|
||||
|
||||
Afterwards no node or chromium process of mine had a cwd under
|
||||
`~/darkwing-scratch`. No `.orig` file was left, and every killed file was
|
||||
back at its starting sha256. The r137 TMPDIR held 847 entries from round
|
||||
1's full gate (newest 18:53Z) and none from this run. I removed them.
|
||||
|
||||
Not run in this round: the other package suites, the other
|
||||
scripts/test-*.sh, Docker and mutants. Some untouched test files also read
|
||||
a source round 3 changed, and they didn't run on this base:
|
||||
|
||||
- broker.mjs: packages/cli/tests/helpers.mjs (and so the cli tests that
|
||||
build a broker through it), cli tester.test and harness runner.test;
|
||||
- launcher.mjs, which asks landHeld: cli launch-limits.test;
|
||||
- bundle.mjs: harness claude-gate, claude-session, mcp-server and
|
||||
pi-session tests.
|
||||
|
||||
All of them passed in the r1 full gate on `7a2987cf5`, before the gated
|
||||
refusal, the arbiter path and landHeld's filter. The reviewers' gates and
|
||||
Sage's gate at the landing target run them on `63c82f1c4`.
|
||||
|
||||
## Round 4 (sage-0585): B1, the class refusal and the landing.mjs comment
|
||||
|
||||
Dewey asked for changes on round 3 (#1631 comment 28801, rev 1595), and
|
||||
Filbert approved it (comment 28804, manifest `0fae2b6f`). sage-0585 fixed
|
||||
round 4 as three items. Everything else in round 3 is unchanged. Base is
|
||||
still `63c82f1c4`.
|
||||
|
||||
### Item 1, Dewey B1: the squash names the real channel
|
||||
|
||||
Round 3's `landMessage` wrote "Resolved <choice> by <by> via the CLI" for
|
||||
every landing. For an arbiter's landing that put "by pm-run via the CLI"
|
||||
into main's history, which is false. Now:
|
||||
|
||||
- `readLanding` returns `via: res.via`, and `#landFacts` passes it into
|
||||
checkLand's facts. The broker's ticket answer gains `via`.
|
||||
- git-socket.mjs maps it: `cli` writes "via the CLI", and `broker` writes
|
||||
"as its arbiter, via the broker". readLanding accepts no other value. If
|
||||
one ever got through, the line would print `via <value>`. It never falls
|
||||
back to the CLI.
|
||||
- land-work's read.mjs prints every key, so it now prints a `via` line too.
|
||||
land-work.sh reads keys by name and still writes "via the CLI" itself,
|
||||
which holds, since it accepts only a human CLI resolution.
|
||||
|
||||
### Item 2, Filbert note 1 and Dewey N1: every class but cross-role refuses
|
||||
|
||||
`#landFacts` now starts with `if (cls !== 'cross-role') fail('not-authorized')`,
|
||||
ahead of the spent check and the human check in readLanding. Round 3
|
||||
refused only `gated`. A role granted `git.merge.protected` within-role
|
||||
resolves its own raise (`via: 'broker'`), so its landing got past that
|
||||
line and refused `not-human` in readLanding instead. It now refuses
|
||||
`not-authorized`, like a gated one. role.mjs is unchanged: whether it
|
||||
should refuse a within-role merge grant at load is a follow-up for row 149
|
||||
(sage-0585).
|
||||
|
||||
The comment above land.test's land-work codes test now matches the code.
|
||||
checkLand never gives `not-human`: #landFacts refuses every class but
|
||||
cross-role first, and the broker resolves a cross-role decision only
|
||||
through the human's CLI answer or its arbiter's decision.resolve.
|
||||
|
||||
### Item 3, Dewey N2: the comment at landing.mjs:112
|
||||
|
||||
The arbiter path's line now has a comment above it. A cross-role decision
|
||||
routed to an agent closes only through decision.resolve, which takes it
|
||||
from the routed role alone (`s.role === route_to`, else `not-resolver`), so
|
||||
`res.by` there is the arbiter's run.
|
||||
|
||||
### Tests, round 4
|
||||
|
||||
- land.test, REQ-DEC-2: checkLand's facts gain `via: 'broker'`.
|
||||
- land.test, the human-routed cross-role landing: checkLand answers
|
||||
`by: 'jason'`, `via: 'cli'`.
|
||||
- land.test, new: "REQ-LAND-1: a within-role merge grant refuses
|
||||
not-authorized at the land". The world's merge-gate holds the grant
|
||||
within-role, so its raise with `choice: 'yes'` closes in the call
|
||||
(`within-role`, routed to itself, `via: 'broker'`). checkLand refuses
|
||||
`not-authorized`, landHeld is false, and nothing merges or refuses on
|
||||
the trail. `setup` takes a `roles` override for it.
|
||||
- git-socket.test, the first land test: the stand-in's facts gain
|
||||
`via: "cli"`, and the squash's message must hold "Resolved yes by jason
|
||||
via the CLI at 2026-10-16T00:00:00.000Z."
|
||||
- git-socket.test, new: "land: an arbiter-resolved landing's squash says
|
||||
the arbiter resolved it through the broker". The stand-in answers
|
||||
`by: "pm-run", via: "broker"`. The message must hold "Resolved yes by
|
||||
pm-run as its arbiter, via the broker at ..." and no "via the CLI".
|
||||
|
||||
### Docs, round 4
|
||||
|
||||
- `packages/bus/README.md`: not-authorized for every class but
|
||||
`cross-role`, gated and within-role named; checkLand's answer carries
|
||||
the resolution's `via`.
|
||||
- `packages/cli/README.md`: the squash's Resolved line names the channel
|
||||
from the ticket's `via`.
|
||||
|
||||
### Interdiff, round 3 to round 4
|
||||
|
||||
`r4/interdiff.patch` (sha256
|
||||
`dcc4672cf6f6ad01cf068725969bfb724d52460528df1adeb405c75a13856af3`), 7
|
||||
files, +65 -20:
|
||||
|
||||
| File | Change |
|
||||
|---|---|
|
||||
| packages/bus/src/broker.mjs | the class refusal and its comment; `via` in the facts |
|
||||
| packages/bus/src/landing.mjs | `via` in readLanding's return; the N2 comment |
|
||||
| packages/cli/src/git-socket.mjs | `RESOLVED_VIA` and the Resolved line |
|
||||
| packages/bus/tests/land.test.mjs | `via` in two tests, the within-role test, the comment, `setup`'s `roles` |
|
||||
| packages/cli/tests/git-socket.test.mjs | `via: "cli"` in the stand-in, the CLI assertion, the arbiter test |
|
||||
| packages/bus/README.md | the refusal's classes, `via` in the answer |
|
||||
| packages/cli/README.md | the Resolved line |
|
||||
|
||||
### Candidate, round 4
|
||||
|
||||
`r4/build.patch` against BASE `63c82f1c4`
|
||||
(sha256 `0cabe175b095dd632e6ee6e166efad19089a1c87ffba6198a32c6849a1a80965`).
|
||||
`r4/candidate-manifest.sha256` (sha256
|
||||
`548ee477baca2a172d2585dd3074979f299b83db4484d1ec89674bb3142a9928`) lists
|
||||
the same 31 paths as r3, and differs from it on the 7 above. I applied the
|
||||
patch to a fresh worktree at BASE. `sha256sum -c` passed on every line,
|
||||
and `git diff --cached --check` was clean (31 files, +2160 -255). I
|
||||
removed that worktree. Canonical HEAD was `4ebef2284`, and
|
||||
`git diff 63c82f1c4 4ebef2284` on the 31 paths is empty.
|
||||
|
||||
### Checks, round 4
|
||||
|
||||
`r4/round.sh` is round 3's script with three kills added and kill (a)
|
||||
moved to the new line:
|
||||
|
||||
| Kill | Edit | Must fail |
|
||||
|---|---|---|
|
||||
| (a) class refusal | broker.mjs:815 `if (false) fail('not-authorized')` | the within-role test, one or more |
|
||||
| item 2, gated only | broker.mjs:815 back to round 3's `cls === 'gated'` | the within-role test, exactly 1 |
|
||||
| B1, CLI text | git-socket.mjs:259 hard-codes "via the CLI" | the arbiter squash test, exactly 1 |
|
||||
|
||||
The other six kills are round 3's.
|
||||
|
||||
I ran it on Sage's go (sage-0592) from 2026-10-16T20:38:29Z to
|
||||
20:40:26Z, in `~/darkwing-scratch/r137/wt4` at BASE with the patch
|
||||
applied. Log: `r4/gate-run.log`, per-step logs under `r4/gate/`.
|
||||
ROUND_PASSED.
|
||||
|
||||
| Step | Result |
|
||||
|---|---|
|
||||
| bus land, hard-waits, project-runtime | 11, 12, 3 pass, 0 fail |
|
||||
| seat landing, working | 8, 26 pass, 0 fail |
|
||||
| harness bundle, git-tools, tools | 22, 5, 19 pass, 0 fail |
|
||||
| cli git-socket | 24 pass, 0 fail |
|
||||
| cli launcher, thread-launch (inherited TMPDIR) | 19, 8 pass, 0 fail |
|
||||
| scripts/test-land-work.sh | 86 passed, 0 failed |
|
||||
| whole bus suite | 317 pass, 0 fail |
|
||||
| whole seat suite | 150 pass, 0 fail |
|
||||
|
||||
All nine kills killed:
|
||||
|
||||
| Kill | Failing |
|
||||
|---|---|
|
||||
| b1-patch-drift | 1 |
|
||||
| b2-against-root | 1 |
|
||||
| (a) class refusal | 2 |
|
||||
| item 2, gated only | 1 |
|
||||
| B1, CLI text | 1 |
|
||||
| b-arbiter-path | 6 |
|
||||
| 5-cross-role-only | 1 |
|
||||
| arbiter-default | 1 |
|
||||
| held-cross-role | 3 |
|
||||
|
||||
Each named test was among the failures. After the run the sweep found
|
||||
none of my processes left, no `.orig` file remained, and `sha256sum -c`
|
||||
on the manifest still passed. This is a targeted builder round
|
||||
(decisions 136/137). The whole cli and harness suites and the other
|
||||
`scripts/test-*.sh` are the landing gate's.
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,31 @@
|
||||
0f664971bd3e4e57fa4c53c5ded0c1e01dee9fb1a9ff3b0c459964372a56cc6e docs/TOOLS.md
|
||||
128aae5d0d6c3d2b11c474508d75b412d24b2b3fff3079822b4fe6de96b53dce packages/bus/README.md
|
||||
380f01f7d97485ff62acec37692b4b4354615fe1be486d18fbf85c82277819ec packages/bus/src/broker.mjs
|
||||
7f8a0fd2d8084632f2c1d7fdc914a89b1f902bd4c8e91ecfe68c1fa226a83171 packages/bus/src/process.mjs
|
||||
38ec7a59a12cab72ed4a58ff784e384ad135d0fd5c496b78275592a9b85d9d04 packages/bus/src/runtime.mjs
|
||||
693cb5a19162a5e7c05802a355d8fddc7d1ea325adf58ad50ca3cb451dcd0a56 packages/bus/tests/project-runtime.test.mjs
|
||||
62b641b44b2939c6eec86856b47de967d501e36d6cf437b993c844d8007353c1 packages/cli/README.md
|
||||
1709491fd769462be67845961865aa5239ae7597805bbeb4cf9e890bdc0eb385 packages/cli/src/git-socket.mjs
|
||||
c764b070ceea3145bcff4d0a3cc97a88bc750c347b62645738e215313bc22829 packages/cli/src/launcher.mjs
|
||||
03a4903b14ea72781a337e1782cba41918f35849b25e223110ed4d283864cee4 packages/cli/tests/git-socket.test.mjs
|
||||
97c613a0e59d39fa715d32144741bd996a6392862353f0bf204029d707789d50 packages/cli/tests/launcher.test.mjs
|
||||
2fef7b7e7f7943448ad041653c5e055faa319c06ff62e248b65cd9be8f1f6360 packages/cli/tests/thread-launch.test.mjs
|
||||
a47aecd10338ffa77df4f1993b90ab60dd91cf33651eb5e7ac23f53f73d73d98 packages/harness/README.md
|
||||
b97b5df64d6ea56183b2d672bbe95321ecfab5171f11e1ba643b6778b70b9fb6 packages/harness/src/bundle.mjs
|
||||
58ee910f904a976ee76a4086432fd477b7f70fdf1793fe893b8bb7beb96d7bc6 packages/harness/src/git-tools.mjs
|
||||
9db75a1688bb628f94d7d3b7a567b8376f13226222b55b9621fd2e0cbb61c5ab packages/harness/src/runner.mjs
|
||||
c1b9ec00eaa43450dc385c3374f47f0fe78f53a20999fa8e1315d517c6444be2 packages/harness/src/tools.mjs
|
||||
81966394d5d875e3e62d231df4e5442849ff7dde40bebe6f52d8d9a7b3b6d99f packages/harness/tests/bundle.test.mjs
|
||||
c0ae1baf603b1e7f4161de2021666ae7be28325436a5ebfb3dfd0e681ce4b872 packages/harness/tests/git-tools.test.mjs
|
||||
a242e6e51903362fc8ce6ff4c29ac3703db9926a080b82e4a4605133a589d670 packages/harness/tests/tools.test.mjs
|
||||
46b31ac7d9bf2fafb548b117fe783c82a65058303284e7021d27610f45339a79 packages/seat/README.md
|
||||
4936266221de342673dbee9af2162328c59bcf4d2eff0c4b6bf63c5e08575bc2 packages/seat/src/checkout.mjs
|
||||
a78268ddbed7bc955dcdee0522278744216b4562e3a699e9409532eed319d336 packages/seat/src/sandbox.mjs
|
||||
0d332d73596e94d2114751c1924c4f8463c387aba9ffdb0924d61f6228e1c463 packages/seat/src/working.mjs
|
||||
df8ea48a034cd1c08ee153fb3ce0f3fcfb13c5f23be949ff6240f07dd6f88a03 packages/seat/tests/working.test.mjs
|
||||
91ef00876a0a3719452ae464a6b2f7c69a8aa65af8fb93515308a0cb85161772 scripts/land-work.sh
|
||||
5dfcc779614378fc504191aac48dab0bc5bec608f097d799c013236e79a43379 scripts/land-work/read.mjs
|
||||
c09885c94d45a48345c132e7e7bf2233ca6787ca23771a35393e6dc635d784d6 packages/bus/src/landing.mjs
|
||||
7ed287a6035cb2ca9d9df09054403df868820a32cdc714ff6b15aa36f8474e1b packages/bus/tests/land.test.mjs
|
||||
a3a5f3e58b92b8bf57d4bd7e9246f7ce10492e308ddfd254c5e059197c2d9c14 packages/seat/src/landing.mjs
|
||||
bf7ef39b57023b498216303543b959fc387b0eeaca475cdf02eb5848b3b5de72 packages/seat/tests/landing.test.mjs
|
||||
@@ -0,0 +1,3 @@
|
||||
base 7a2987cf5 DOCKER_HOST=unset docker=29.7.2 start 18:37:45
|
||||
pkg-bus rc=1 18:37:45-18:37:57 ℹ pass 295 ℹ fail 7 ℹ skipped 0 | }
|
||||
STOP pkg-bus
|
||||
@@ -0,0 +1,5 @@
|
||||
base 7a2987cf5 DOCKER_HOST=unset docker=29.7.2 start 18:39:15
|
||||
pkg-bus rc=0 18:39:15-18:39:28 ℹ pass 302 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 12251.983083
|
||||
pkg-business rc=0 18:39:28-18:39:29 ℹ pass 109 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 1896.460233
|
||||
pkg-cli rc=1 18:39:29-18:41:01 ℹ pass 196 ℹ fail 6 ℹ skipped 0 | at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
STOP pkg-cli
|
||||
@@ -0,0 +1,6 @@
|
||||
base 7a2987cf5 DOCKER_HOST=unset docker=29.7.2 start 18:44:15
|
||||
pkg-bus rc=0 18:44:15-18:44:27 ℹ pass 302 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 12369.638742
|
||||
pkg-business rc=0 18:44:27-18:44:29 ℹ pass 109 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 1945.948742
|
||||
pkg-cli rc=0 18:44:29-18:44:50 ℹ pass 202 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 20213.873392
|
||||
pkg-cli-launcher rc=1 18:44:50-18:45:04 ℹ pass 18 ℹ fail 1 ℹ skipped 0 | at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
STOP pkg-cli-launcher
|
||||
@@ -0,0 +1,16 @@
|
||||
base 7a2987cf5 DOCKER_HOST=unset docker=29.7.2 start 18:45:35
|
||||
pkg-bus rc=0 18:45:35-18:45:46 ℹ pass 302 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 11199.134901
|
||||
pkg-business rc=0 18:45:46-18:45:48 ℹ pass 109 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 2012.878753
|
||||
pkg-cli rc=0 18:45:48-18:46:10 ℹ pass 202 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 21560.33243
|
||||
pkg-cli-launcher rc=0 18:46:10-18:46:24 ℹ pass 19 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 14833.180301
|
||||
pkg-control-board rc=0 18:46:24-18:46:25 ℹ pass 124 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 649.958587
|
||||
pkg-conversation rc=0 18:46:25-18:47:15 ℹ pass 182 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 50020.343616
|
||||
pkg-discord rc=0 18:47:15-18:47:18 ℹ pass 183 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 2640.132988
|
||||
pkg-harness rc=0 18:47:18-18:47:30 ℹ pass 108 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 12190.433259
|
||||
pkg-ledger rc=0 18:47:30-18:47:52 ℹ pass 86 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 22075.885877
|
||||
pkg-mosaic rc=0 18:47:52-18:47:54 ℹ pass 69 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 2051.574471
|
||||
pkg-plugins rc=0 18:47:54-18:47:54 ℹ pass 28 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 226.191842
|
||||
pkg-project rc=0 18:47:54-18:47:56 ℹ pass 30 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 1014.159815
|
||||
pkg-runs rc=0 18:47:56-18:47:56 ℹ pass 43 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 715.157202
|
||||
pkg-seat rc=1 18:47:56-18:48:02 ℹ pass 146 ℹ fail 2 ℹ skipped 0 | }
|
||||
STOP pkg-seat
|
||||
@@ -0,0 +1,19 @@
|
||||
✔ checkLand answers the facts and a ticket, records nothing, and recordLand spends the decision once (176.764884ms)
|
||||
✔ checkLand refuses on the decision and the review (256.209119ms)
|
||||
✔ a merge option with no first line refuses no-subject, as land-work does (114.469937ms)
|
||||
✔ checkLand refuses with land-work's codes past the authority check, and a decision raised for refactor never lands (267.381445ms)
|
||||
✔ a ticket outlives the run that asked, and recordLand checks the task again (112.362045ms)
|
||||
✔ landRefused files the code on the task, tells the role only with notify, and ends the ticket (117.330249ms)
|
||||
✔ landHeld is true only for an approved, unspent merge decision this role raised for a task in this thread (112.674263ms)
|
||||
✔ no run may write the action.allowed for git.merge.protected itself (73.676483ms)
|
||||
✔ Broker keeps the existing sandbox client import closure: no new imports or lazy project import (1.553045ms)
|
||||
✔ without a trusted project adapter all three async paths refuse project-not-configured (165.234989ms)
|
||||
✔ real startBroker injects the project adapter for socket reads and bound-author record writes (168.752393ms)
|
||||
ℹ tests 11
|
||||
ℹ suites 0
|
||||
ℹ pass 11
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1293.733361
|
||||
@@ -0,0 +1,477 @@
|
||||
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (143.490511ms)
|
||||
✔ agents: working counts what the holder received and has not read; routed alone is not working (203.729324ms)
|
||||
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (329.878819ms)
|
||||
✔ agents: working wins over waiting, and Input needed still shows (174.656985ms)
|
||||
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (226.743618ms)
|
||||
✔ agents: state reads only its own business, even for a run name both use (187.355626ms)
|
||||
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (220.521088ms)
|
||||
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (210.533074ms)
|
||||
✔ agents: stranded is oldest first and capped at 50 for a role (933.932351ms)
|
||||
✔ agents: stranded is per role and per business (332.277738ms)
|
||||
✔ agents: a message routed to a held role and not yet received is not stranded (132.446455ms)
|
||||
✔ REQ-DEC an approval outlives its run and a broker restart; a new run of the instance consumes it once (268.774469ms)
|
||||
✔ REQ-DEC another instance of the same definition cannot consume an approval, and its refusal consumes nothing (190.84645ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread approval is consumed only by a run holding the same thread (276.051807ms)
|
||||
✔ REQ-DEC a later run of the same instance supersedes an open decision; another instance cannot (252.287125ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread decision is superseded only from the same thread (287.269023ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread instance decision raised before row 121 is not consumed or superseded by any thread run (333.275539ms)
|
||||
✔ launch identity is stamped, payload identity is refused and stale holder cannot send (174.848766ms)
|
||||
✔ decision classes route from policy; gated resolution is human-only, choice and target must match (248.358118ms)
|
||||
✔ claim exclusion, holder release, gated revoke and rerouting to a new holder are atomic (273.430369ms)
|
||||
✔ launch events require a human CLI capability; generic emit cannot forge authority events (184.963236ms)
|
||||
✔ within-role decisions close atomically and invalid options or blocking omissions refuse (213.113276ms)
|
||||
✔ a recommendation that is not exactly one option key refuses invalid-recommendation after the options (274.371208ms)
|
||||
✔ observer capabilities read human inbox but cannot mutate or forge launch identity (163.175791ms)
|
||||
✔ task action subjects and linked decision trail are complete and ordered (207.906022ms)
|
||||
✔ launch binding is durable and reconnecting requires the identical trusted record (132.022789ms)
|
||||
✔ business isolation includes inherited object names and cross-business message references (210.722577ms)
|
||||
✔ authority never transfers between action, target, unresolved or replaced role holder; a later run of the instance keeps it (316.076823ms)
|
||||
✔ task projection uses schema current view, skipping earlier and equal-start polls (169.38238ms)
|
||||
✔ revocation permanently bars the old run from reclaiming first, including after broker restart (230.009469ms)
|
||||
✔ empty message references refuse before storage; refusal-evidence failure stays a typed error (144.671024ms)
|
||||
✔ both arbiters require human resolution when their cross-role route is themselves (266.265371ms)
|
||||
✔ the shipped coder role raises task.reassign as gated to the human; task.scope.change stays cross-role (210.633909ms)
|
||||
✔ S1 adapter takes resolved limits and refs, rejects mismatched instance, never mutates input (2.433026ms)
|
||||
✔ REQ-COS-1, REQ-ROLE-2: the chief of staff ends a run with a reason and no decision, and the reason is logged (246.705659ms)
|
||||
✔ REQ-ROLE-2: a role without role.end still needs a resolved decision to revoke (326.657944ms)
|
||||
✔ REQ-ROLE-2: storage accepts a revoke with a reason or a decision and aborts one with neither (254.749039ms)
|
||||
✔ REQ-ROLE-2: the chief of staff may still cite a decision, and a decision alone is the old path (267.417052ms)
|
||||
✔ REQ-ROLE-2: a role without role.end still ends a run through a resolved decision, which is recorded and has no reason (275.088751ms)
|
||||
✔ REQ-ROLE-2: a reason is required, bounded, and never sent with a decision (278.518569ms)
|
||||
✔ REQ-COS-1: the chief of staff cannot end its own run or the assistant's through role.end (288.807851ms)
|
||||
✔ REQ-LIMIT-1, REQ-COS-1: organization.set from the chief of staff reaches the shared writer, named as the actor (256.38867ms)
|
||||
✔ REQ-LIMIT-1, REQ-COS-1: a refused organization.set logs action.refused and no action.allowed, like a refused limits.set (337.87114ms)
|
||||
✔ REQ-LIMIT-1: organization.set is refused for every caller whose role file lacks organization.change (297.056572ms)
|
||||
✔ REQ-LIMIT-1: the chief of staff is logged as allowed, and organization.set takes only the human's keys (412.259472ms)
|
||||
✔ REQ-ROLE-3, REQ-LIMIT-1: a chief-of-staff change is validated, written and logged like a human's; an invalid one is refused (651.307937ms)
|
||||
✔ REQ-ROLE-2, REQ-COS-1: the 3c→3d migration lets the chief of staff end a held role with a reason; neither is still refused (1176.18563ms)
|
||||
✔ comment cursors isolate businesses, move only forward and remain append-only (118.136245ms)
|
||||
✔ only trusted sync writes validated cursors; events and cursor share rollback (112.497162ms)
|
||||
✔ explicit 3b copy migration preserves evidence and opens as 3f; normal startup never migrates (847.817256ms)
|
||||
✔ migration refuses active writers and drifted legacy schemas, with no partial upgrade (1585.825719ms)
|
||||
✔ named migration registry chains 3b through 3f to a fixture-only future version in order (881.800721ms)
|
||||
✔ migration refuses mismatched source metadata without changing schema or evidence (949.603435ms)
|
||||
✔ offline command migrates only the supplied fixture root and reports usage errors (1149.112246ms)
|
||||
✔ credentials gives human and reader sessions service, account, role, date and state, and nothing else (101.306493ms)
|
||||
✔ credentials refuses a role session and any argument (168.160521ms)
|
||||
✔ credentials reads the status on each request, and a broker without one lists none (211.038963ms)
|
||||
✔ the broker process answers credentials without a token, path or variable in its output, log or store (228.472124ms)
|
||||
✔ only validated broker references load; returned data and exceptions cannot expose a known token (4.00558ms)
|
||||
✔ bad file modes, symlinks, repository/data paths, malformed tokens and missing dates refuse (4.41877ms)
|
||||
✔ expiry refuses use and env references never become client data (0.696483ms)
|
||||
✔ S1 parsed service refs work, service mismatch refuses, Gitea rotation due is a warning state (1.495284ms)
|
||||
✔ opaque tokens shorter than 16 characters refuse before use (0.278469ms)
|
||||
✔ each C-suite role file carries the same two lists: human, chief-of-staff, pm, cto (2.391418ms)
|
||||
✔ chief-executive-officer: messages to and from the user, chief of staff, pm and cto pass (465.587113ms)
|
||||
✔ chief-executive-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (460.704203ms)
|
||||
✔ chief-executive-officer: another C-suite role isn't on the lists either (435.90759ms)
|
||||
✔ chief-financial-officer: messages to and from the user, chief of staff, pm and cto pass (478.233563ms)
|
||||
✔ chief-financial-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (485.519025ms)
|
||||
✔ chief-financial-officer: another C-suite role isn't on the lists either (411.650058ms)
|
||||
✔ chief-information-officer: messages to and from the user, chief of staff, pm and cto pass (506.221186ms)
|
||||
✔ chief-information-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (567.462014ms)
|
||||
✔ chief-information-officer: another C-suite role isn't on the lists either (486.529759ms)
|
||||
✔ chief-information-security-officer: messages to and from the user, chief of staff, pm and cto pass (641.273402ms)
|
||||
✔ chief-information-security-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (573.338972ms)
|
||||
✔ chief-information-security-officer: another C-suite role isn't on the lists either (432.537028ms)
|
||||
✔ chief-marketing-officer: messages to and from the user, chief of staff, pm and cto pass (474.387193ms)
|
||||
✔ chief-marketing-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (435.069446ms)
|
||||
✔ chief-marketing-officer: another C-suite role isn't on the lists either (409.258351ms)
|
||||
✔ a human resolve sends the raising role one message from the human, and its request is the answer (234.873073ms)
|
||||
✔ a cross-role decision resolved by its arbiter comes from that role and run, with no request (234.474783ms)
|
||||
✔ a human withdraw sends one message with the note (244.483269ms)
|
||||
✔ a human seen before the close leaves the request on the close's answer, not the seen (311.203051ms)
|
||||
✔ the raising run's withdraw, a supersede, a within-role raise and seen send nothing (290.108897ms)
|
||||
✔ refused closes send nothing: invalid-choice, decision-closed, not-resolver (304.966897ms)
|
||||
✔ a raising role nobody holds at the close gets the message on the next claim (284.228955ms)
|
||||
✔ a human DECISION send keeps its own instruction as the request, not a close's answer (245.78354ms)
|
||||
✔ a cross-role raise whose arbiter the raiser does not hear from is refused and stores nothing (293.642849ms)
|
||||
✔ a gated raise by a role that does not hear from the human is refused and stores nothing (289.555346ms)
|
||||
✔ a route the raiser hears from is allowed, checked from the route to the raiser (354.090367ms)
|
||||
✔ a refused supersede withdraws nothing (315.316466ms)
|
||||
✔ the assistant's within-role and gated raises still work (304.521825ms)
|
||||
✔ roles lists open decisions routed to a role, and never the human inbox (218.668476ms)
|
||||
✔ recent lists closed decisions of every route, newest close first, with how each closed (285.8522ms)
|
||||
✔ recent gives the closing event as closed when the decision was seen first (305.918506ms)
|
||||
✔ recent stops at RECENT rows (836.83975ms)
|
||||
✔ every row is what trail already gives the same session for that id (291.013109ms)
|
||||
✔ a role session can't list decisions, so it can't read another role's open decisions (418.893184ms)
|
||||
✔ decisions is a read: one business, strict arguments, nothing written (417.549319ms)
|
||||
✔ endLaunch writes session.ended, releases the run claim and kills its capabilities (125.873816ms)
|
||||
✔ endLaunch refuses an unknown run, a second end and a rebind of the ended run (139.425984ms)
|
||||
✔ a restarted broker refuses to rebind an ended run; a refused rebind leaves the run unbound (142.701541ms)
|
||||
✔ endLaunch leaves a claim another run took alone (178.418176ms)
|
||||
✔ refuse records action.refused against the caller with the code only (152.136743ms)
|
||||
✔ launches off refuses role.launch with launch-revoked until launches on (197.700524ms)
|
||||
✔ broker process: launch ops authorize role.launch, record refusals and end runs (358.768553ms)
|
||||
✔ human proof binds CLI entry, process start and nonce; agents and incomplete ancestry refuse (1.891171ms)
|
||||
✔ process reader gets own kernel identity without exposing environment values (0.562783ms)
|
||||
✔ EACCES ancestor environments skip only markers; commands and registered launches still refuse (0.896502ms)
|
||||
✔ real pid 1 remains inspectable when its environment is protected (0.337478ms)
|
||||
✖ checkLand answers the facts and a ticket, records nothing, and recordLand spends the decision once (251.698675ms)
|
||||
✖ checkLand refuses on the decision and the review (271.998353ms)
|
||||
✖ a merge option with no first line refuses no-subject, as land-work does (249.96045ms)
|
||||
✖ checkLand refuses with land-work's codes past the authority check, and a decision raised for refactor never lands (261.880846ms)
|
||||
✖ a ticket outlives the run that asked, and recordLand checks the task again (239.557719ms)
|
||||
✖ landRefused files the code on the task, tells the role only with notify, and ends the ticket (261.776469ms)
|
||||
✔ landHeld is true only for an approved, unspent merge decision this role raised for a task in this thread (257.462367ms)
|
||||
✔ no run may write the action.allowed for git.merge.protected itself (180.797745ms)
|
||||
✔ a message to a stopped role sends launch.by one notice, and the result says so (212.68727ms)
|
||||
✔ a message to a role outside launch.instances says so in its result and in the notice (156.001011ms)
|
||||
✔ a message to a running role sends no notice and its result is unchanged (141.407436ms)
|
||||
✔ a re-route at a claim, a release and claim, and a broker restart send no second notice (250.120155ms)
|
||||
✔ a run launched but not yet claimed counts as no holder (131.584568ms)
|
||||
✔ no notice for a message to launch.by, from it, from a tester, to the human, or in a thread to a thread instance (291.571469ms)
|
||||
✔ a business with no launch block tells nobody and says there is no launcher (131.057905ms)
|
||||
✔ the notice sender stays internal: no role is named _bus and no caller can send as it or to it (343.765708ms)
|
||||
✔ limits binds actor from human proof and rejects role, reader, tester and forged actor (202.772346ms)
|
||||
✔ runtime wires verified human settings to the actual shared file writer and actor receipt (276.296566ms)
|
||||
✔ uncertain organization receipts leave bus startup and reads alone but refuse writes until reconciled (433.397652ms)
|
||||
✔ within-role sends cite an open gated launch decision without spending it or naming it in grants (203.818503ms)
|
||||
✔ missing and foreign-business citations refuse and roll back message and grant (193.03303ms)
|
||||
✔ cross-role sends still need a matching resolved decision and consume it once (246.348276ms)
|
||||
✔ messages pages all human messages newest first without writes; read state is history (2736.956684ms)
|
||||
✔ messages refuses role callers, invalid paging and cursors outside this human feed (350.489486ms)
|
||||
✔ views messages passes only its paging arguments through (0.330354ms)
|
||||
✔ messages isolates businesses even with a valid foreign cursor (201.826917ms)
|
||||
✔ the assistant sends to the user and to the chief of staff only (335.633359ms)
|
||||
✔ an assistant send to any other role, or to the tester, is refused and logged (376.02215ms)
|
||||
✔ only the user and the chief of staff may send to the assistant; the tester is refused by default (376.867904ms)
|
||||
✔ REQ-ASSIST-2 REQ-THREAD-1 thread.send to an instance that does not hear from the user is refused and stores nothing (322.789916ms)
|
||||
✔ a sender-side list alone refuses a send to a role that has no list (345.143558ms)
|
||||
✔ a target-side list alone refuses a send from a role that has no list (356.297553ms)
|
||||
✔ the sender list is checked before the target list (364.169697ms)
|
||||
✔ roles without the field behave exactly as before (534.290305ms)
|
||||
✔ a business with no role definitions at all is unlimited (417.614533ms)
|
||||
✔ a malformed messaging field refuses at boot (120.573164ms)
|
||||
✔ the assistant's review.request to a reviewer is refused and logged, even with an approved decision (524.027342ms)
|
||||
✔ a review.verdict to the assistant from a role outside its receiveFrom is refused and logged (470.5462ms)
|
||||
✔ review requests and verdicts between roles without the field are unchanged (357.705211ms)
|
||||
✔ plugins and plugins.set refuse every non-human session and a forged actor, and pass only the patch with the verified actor (219.722597ms)
|
||||
✔ runtime: the switch changes the organization file, the receipt carries the actor, and a bad shape, an unknown module and a stale revision are refused with nothing written (521.783388ms)
|
||||
✔ vikunja:19/309 through the broker, a patch switches the kinds it names and keeps the rest; null removes one kind and is trailed (440.001994ms)
|
||||
✔ broker process binds trusted launches, offers reader capabilities, refuses human mutation, closes cleanly (241.113797ms)
|
||||
✔ startup token refusal returns safe code without value or partial listening broker (81.958897ms)
|
||||
✔ loaded fixture token is absent from socket replies and SQLite, including refusal evidence (236.181575ms)
|
||||
✔ killed broker leaves an explicit stale lock; another process cannot silently reclaim it (275.039792ms)
|
||||
✔ trusted host registers later launches; socket clients never have a registration verb (228.440239ms)
|
||||
✔ runtime excludes declared project roots even when host supplies no repoRoots (77.496756ms)
|
||||
✔ a refused launch binding leaves the broker and existing capabilities alive; bad protocol stops it (197.910674ms)
|
||||
✔ D1: committed write with a failed receipt refuses outcome-unknown without action.allowed (162.815337ms)
|
||||
✔ D2: spec.read refuses without content if its role is released during the read (164.702208ms)
|
||||
✔ D3: spec.read secret check refuses flagged content without content (147.159495ms)
|
||||
✔ D3: spec.read secret check refuses flagged subject without content (137.947353ms)
|
||||
✖ Broker keeps the existing sandbox client import closure: no new imports or lazy project import (2.074077ms)
|
||||
✔ without a trusted project adapter all three async paths refuse project-not-configured (232.796731ms)
|
||||
✔ real startBroker injects the project adapter for socket reads and bound-author record writes (220.860931ms)
|
||||
✔ a reply is listed for human and reader sessions, and its delivery rows are unchanged (237.042825ms)
|
||||
✔ the reply still reaches the human message.receive (mosaic talk) after the Console showed it (205.705566ms)
|
||||
✔ a message with no reply gives an empty list (175.75095ms)
|
||||
✔ replies come oldest first and stop at REPLIES (775.050895ms)
|
||||
✔ an id that names no message in the business refuses message-not-found, and the refusal is recorded (399.607373ms)
|
||||
✔ strict arguments; a role session gets human-required (387.639921ms)
|
||||
✔ views passes replies through as one call with the id (0.267351ms)
|
||||
✔ requirements returns the committed list to a holding role session, and no one else (226.570569ms)
|
||||
✔ the PM's prd.approve with no task, when no id fits, reaches the human's Inbox (148.561691ms)
|
||||
✔ the PM's non-blocking role.revoke with no task reaches the human's Inbox (206.770021ms)
|
||||
✔ a push is recorded as the action.allowed for git.push.working on the task, and only the host records one (255.905917ms)
|
||||
✔ review.request names the latest pushed commit and sends the reviewer a REVIEW-REQUEST (252.025607ms)
|
||||
✔ review.request says which run holds the reviewer role, or null, and a null request waits for a claim (276.91177ms)
|
||||
✔ review.request refuses a commit that isn't the latest push, a non-reviewer and a role without the action (430.414621ms)
|
||||
✔ reviewFetch answers only the addressed reviewer, for the request it cites (328.835711ms)
|
||||
✔ review.verdict answers one request once, to the role that asked (364.529318ms)
|
||||
✔ task.close on a pushed task needs an approve verdict for the latest push (470.555475ms)
|
||||
✔ a refusal the host decided is filed on the task it names, and only a task ref counts (382.899139ms)
|
||||
✔ v3b prototype refusals, views and append-only mutations (1646.850984ms)
|
||||
✔ gated approval authorizes once, survives store reopen, and fresh approval works (281.624204ms)
|
||||
✔ another run of the same instance consumes an approval once; a failed check leaves it usable (206.458712ms)
|
||||
✔ two scheduled callers have exactly one grant and one consumed refusal (158.814102ms)
|
||||
✔ failed commit rolls consumption back; cross-role consumes and within-role stays reusable (361.047459ms)
|
||||
✔ class drift gated to cross-role refuses before consumption (301.578832ms)
|
||||
✔ class drift cross-role to gated refuses before consumption (274.956218ms)
|
||||
✔ class drift gated to within-role refuses before consumption (293.475013ms)
|
||||
✔ class drift cross-role to within-role refuses before consumption (298.074973ms)
|
||||
✔ class drift within-role to gated refuses before consumption (322.993141ms)
|
||||
✔ class drift within-role to cross-role refuses before consumption (291.933089ms)
|
||||
✔ message.send consumes approval and prevents a later send or authorize (273.588487ms)
|
||||
✔ role.revoke consumes approval and prevents a later revoke or authorize (304.31343ms)
|
||||
✔ 3e copy migrates to 3f preserving every old column/row and adding null spec citations (1517.517785ms)
|
||||
✔ real socket awaits spec reads, record writes and cited raises; other requests still return normally (280.96622ms)
|
||||
✔ real socket preserves asynchronous refusal codes and disconnects its transient proof (218.74477ms)
|
||||
✔ two real socket writes to one repository yield one commit and one project-busy refusal (330.036646ms)
|
||||
✔ client disconnect during await tolerates late reply (193.94252ms)
|
||||
✔ client disconnect during await tolerates late refusal (188.722535ms)
|
||||
✔ N-a: slow admitted record.write returns its committed result after the idle deadline (446.561423ms)
|
||||
✔ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (325.788404ms)
|
||||
✔ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (394.908448ms)
|
||||
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (302.06813ms)
|
||||
✔ record writes bind the session author, require authority and refuse spec and impersonation paths (291.923846ms)
|
||||
✔ REQ-COS-1: the pm asks the chief of staff for roles and counts; the chief receives a STAFF-REQUEST and answers it (257.045507ms)
|
||||
✔ REQ-COS-1: only the pm can send a staff request; every other session is refused and the chief of staff hears nothing (358.525504ms)
|
||||
✔ REQ-COS-1: a pm without message.send is refused like any other gated action (230.116836ms)
|
||||
✔ REQ-COS-1: the request goes to the business launcher, and only when that is a chief of staff (486.221833ms)
|
||||
✔ REQ-COS-1: the sender is judged by definition: an instance `lead` of the pm definition can ask, an instance `pm` of the coder definition can't (479.789283ms)
|
||||
✔ REQ-COS-1: the launcher is judged by definition: an instance `boss` of the chief-of-staff definition receives, a `chief` of the coder definition gives no-chief-of-staff (548.521633ms)
|
||||
✔ REQ-COS-1: a refused staff request leaves no staff.request action.allowed event (282.377581ms)
|
||||
✔ REQ-ASSIST-2: the role definitions' messaging lists hold for a staff request, sender and recipient (663.935827ms)
|
||||
✔ a staff request names a task, 1 to 10 distinct roles and counts of 1 to 20; nothing else is accepted (457.088912ms)
|
||||
✔ REQ-COS-1: a staff request grants nothing: the pm still can't launch and the chief of staff launches as before (234.495545ms)
|
||||
✔ a business that never switched launches reads allowed with no time and no event (176.574662ms)
|
||||
✔ launches revoked and then restored read allowed, with the restore time and event id (239.118619ms)
|
||||
✔ a task closed on the tracker leaves the open list, and total counts the open ones (158.376647ms)
|
||||
✔ a tombstone is not open (160.736199ms)
|
||||
✔ the open list stops at the cap and says so; total still counts every open task (148.509209ms)
|
||||
✔ a role and a reader session read state; arguments, and an unbound cap, refuse (200.77214ms)
|
||||
✔ a human session reads the same state, with the same cap (179.792362ms)
|
||||
✔ reading state writes nothing: every table keeps its row count (187.955769ms)
|
||||
✔ creates private WAL store and excludes a second writer until explicit close (182.3317ms)
|
||||
✔ rollback is atomic and schema metadata is checked against trusted DDL, not just itself (198.594739ms)
|
||||
✔ existing empty database and symlink runtime directory refuse, never initialize over damage (225.938935ms)
|
||||
✔ crash during a transaction recovers no partial event after explicit fixture-only lock removal (221.318894ms)
|
||||
✔ writer refuses mixed at/read_at forms atomically, even through trusted SQL helpers (124.673247ms)
|
||||
✔ async transactions refuse before invoking their function (117.021873ms)
|
||||
✔ the session default fits under the reply cap and pages to the end with next (383.492014ms)
|
||||
✔ the short form: no description, assignees by role, every listed key (307.144225ms)
|
||||
✔ each filter, alone and together, and total counts every match (465.120843ms)
|
||||
✔ task_ref reads one task in full, as the whole board has it (397.038186ms)
|
||||
✔ no arguments is the read the Console and mosaic make, unchanged (278.752867ms)
|
||||
✔ an unknown argument or a bad value refuses invalid-request (1016.259495ms)
|
||||
✔ tasks rows carry priority and requirement for every session that reads tasks (387.143416ms)
|
||||
✔ the read model rebuilds from the ledger: a reopened bus and each trail give the same values (413.43234ms)
|
||||
✔ an empty business and one with snapshots but no task.created read cleanly (174.507851ms)
|
||||
✔ recordTask keeps sync reads and a role write apart (239.284441ms)
|
||||
✔ read_at must be one canonical UTC format, so the projection compares strings safely (132.004003ms)
|
||||
✔ a bad entry refuses the whole record (121.105267ms)
|
||||
✔ taskView reads the projection for one business (191.396833ms)
|
||||
✔ requestTask hands only a holder and a task verb to the handler, and records refusals (361.891756ms)
|
||||
✔ the server sends task verbs to the adapter with its own timeout; other verbs stay synchronous (441.789101ms)
|
||||
✔ without an adapter the server refuses every task verb (234.67147ms)
|
||||
✔ the runtime refuses an invalid adapter and closes a valid one (257.321858ms)
|
||||
✔ the process loads the S3 adapter from plain-data trackers (352.673986ms)
|
||||
✔ the tester binds only when the business sets bus.tester to exactly true (1063.802589ms)
|
||||
✔ a business may not name a role tester, so the tester address is never a role (280.267126ms)
|
||||
✔ every verb outside the tester list refuses tester-refused and is recorded against the tester (607.792776ms)
|
||||
✔ a tester message is from tester, starts [mos test], and writes no human.input or authority (238.527938ms)
|
||||
✔ a role answers a tester only in reply to a tester message, and the answer never reaches the human (266.218743ms)
|
||||
✔ the tester reads the human views a reader reads (186.010192ms)
|
||||
✔ tester proof binds its own CLI, start time and nonce, refuses a managed run and allows an agent (1.392009ms)
|
||||
✔ neither CLI's nonce proves the other: each proof is bound to its own CLI and nonce variable (0.396415ms)
|
||||
✔ testerNonce reads only the tester's variable and gives null on any read error (0.236377ms)
|
||||
✔ an envelope carries exactly one of cap, human and tester; no tester authenticator refuses (114.743952ms)
|
||||
✔ tester-cli.mjs binds through the runtime when the switch is on, and refuses off or under a run marker (976.344086ms)
|
||||
✔ REQ-THREAD-1 REQ-ORG-2: the 3d→3e migration adds the thread tables and leaves messages from before threads as written (1309.130998ms)
|
||||
✔ REQ-THREAD-1: a 3d bus with a changed schema is refused and keeps its version and tables (880.350161ms)
|
||||
✔ REQ-THREAD-1: the offline command prints the kept-message counts before the ready line (856.018418ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: one holder per thread, through the broker and the trigger (452.002637ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: the 3e triggers refuse writes that skip the broker (1316.367475ms)
|
||||
✔ REQ-MSG-1: a message to or from the assistant names its thread, or is refused (345.100581ms)
|
||||
✔ REQ-MSG-1: the chief of staff's reply comes back to the thread that sent the work (3609.36047ms)
|
||||
✔ REQ-MSG-1: a reply can't carry one thread instance's thread to another thread instance (100.908296ms)
|
||||
✔ REQ-THREAD-1 REQ-USER-2: one thread's messages never reach another thread's holder (158.341625ms)
|
||||
✔ REQ-LAUNCH-1: a message to a thread with no holder waits, and the next holder gets it (168.688742ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1: threadIdle releases only a thread with nothing waiting, and only for its holder (164.772802ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1: a message delivered to a run that ended unread doesn't hold up the next holder (146.689436ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: an approved role.revoke never reaches a thread run, and the thread stays held (132.197711ms)
|
||||
✔ REQ-USER-2: the human verbs refuse another owner's thread (160.4486ms)
|
||||
✔ REQ-THREAD-1: thread.create refuses when the business has no thread instance or more than one (128.377522ms)
|
||||
✔ REQ-ORG-2: projects and threads are named once, and the repo names a business project (150.953193ms)
|
||||
✔ REQ-THREAD-2: thread.messages returns the thread's history in pages and writes nothing (547.448518ms)
|
||||
✔ socket capability stamps launch identity; shared views use wire, no SQL client (255.351931ms)
|
||||
✔ two wire claims serialize; a lost reply never automatically retries (251.263242ms)
|
||||
✔ malformed, oversized and identity-forging envelopes refuse without echoing input (143.08084ms)
|
||||
✔ client preserves UTF-8 when a response divides a multibyte character (12.692636ms)
|
||||
✔ committed mutation followed by dropped reply reports unknown and is never retried (168.034534ms)
|
||||
✔ web.search: a granted role gets labelled results, and the call is trailed with role, run, verb and query (253.051245ms)
|
||||
✔ web.fetch: a granted role gets the page as labelled text, and the call is trailed with the url (212.723667ms)
|
||||
✔ a role without the grant is refused, the refusal is logged with the verb, and nothing is fetched (233.431633ms)
|
||||
✔ a broker with no web service refuses a granted role (168.3812ms)
|
||||
✔ bad requests are refused: unknown verb, extra or missing argument, not a string, a human or reader session (225.068426ms)
|
||||
✔ a session that is not the role holder is refused (160.720599ms)
|
||||
✔ web.mjs's fences hold on the broker side: refusals are normal results with the fixed reason (404.553886ms)
|
||||
✔ web.search with no search source configured is a refused result, not an error (151.34125ms)
|
||||
✔ a search source that fails with its own refusal, or that throws, is handled (182.50646ms)
|
||||
✔ a slow search source ends in a refusal at the deadline (196.484324ms)
|
||||
✔ a secret in the arguments is refused before anything is trailed or fetched (136.476069ms)
|
||||
✔ over the socket: the server routes web verbs to the service; other roles are refused; no service is web-not-configured (246.239771ms)
|
||||
✔ busBusiness: the web grant comes from "web" in the resolved tool limit (0.304299ms)
|
||||
✔ webServices: the business's search-source plug-in and web.searxng var make web.search work; without either it is refused as not configured (209.536361ms)
|
||||
✔ an ungranted call is refused at once: no admission, no wait, nothing touched (153.95907ms)
|
||||
✔ over the socket an ungranted caller is dropped by the server timeout and a granted one gets the longer wait (456.651467ms)
|
||||
✔ a search that never answers is aborted at the deadline, the module sees the signal, and the call is trailed as refused (timeout) (176.285303ms)
|
||||
✔ a fetch that stalls is cut off at the deadline: the request is destroyed, not left running (202.452522ms)
|
||||
✔ one query limit: over SEARCH_MAX_QUERY_CHARS or empty is refused with the same reason before any backend, and the tool schema carries the same number (169.182866ms)
|
||||
ℹ tests 302
|
||||
ℹ suites 0
|
||||
ℹ pass 295
|
||||
ℹ fail 7
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 12151.056693
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at tests/land.test.mjs:87:1
|
||||
✖ checkLand answers the facts and a ticket, records nothing, and recordLand spends the decision once (251.698675ms)
|
||||
Error: decision-not-found
|
||||
at fail (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:85:9)
|
||||
at #landFacts (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:775:40)
|
||||
at file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:761:36
|
||||
at Store.transaction (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.checkLand (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:756:24)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/tests/land.test.mjs:90:17)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.start (node:internal/test_runner/test:1262:17)
|
||||
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
|
||||
code: 'decision-not-found'
|
||||
}
|
||||
|
||||
test at tests/land.test.mjs:137:1
|
||||
✖ checkLand refuses on the decision and the review (271.998353ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /no-verdict/. Input:
|
||||
|
||||
'Error: decision-not-found'
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/tests/land.test.mjs:160:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: Error: decision-not-found
|
||||
at fail (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:85:9)
|
||||
at #landFacts (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:775:40)
|
||||
at file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:761:36
|
||||
at Store.transaction (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.checkLand (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:756:24)
|
||||
at check (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/tests/land.test.mjs:139:36)
|
||||
at file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/tests/land.test.mjs:160:23
|
||||
at getActual (node:assert:580:5)
|
||||
at strict.throws (node:assert:728:24)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/tests/land.test.mjs:160:10),
|
||||
expected: /no-verdict/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/land.test.mjs:168:1
|
||||
✖ a merge option with no first line refuses no-subject, as land-work does (249.96045ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /no-subject/. Input:
|
||||
|
||||
'Error: decision-not-found'
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/tests/land.test.mjs:179:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: Error: decision-not-found
|
||||
at fail (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:85:9)
|
||||
at #landFacts (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:775:40)
|
||||
at file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:761:36
|
||||
at Store.transaction (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.checkLand (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:756:24)
|
||||
at file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/tests/land.test.mjs:179:27
|
||||
at getActual (node:assert:580:5)
|
||||
at strict.throws (node:assert:728:24)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/tests/land.test.mjs:179:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14),
|
||||
expected: /no-subject/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/land.test.mjs:185:1
|
||||
✖ checkLand refuses with land-work's codes past the authority check, and a decision raised for refactor never lands (261.880846ms)
|
||||
AssertionError [ERR_ASSERTION]: The input did not match the regular expression /work-ref/. Input:
|
||||
|
||||
'Error: decision-not-found'
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/tests/land.test.mjs:195:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19)
|
||||
at Test.run (node:internal/test_runner/test:1467:12)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: Error: decision-not-found
|
||||
at fail (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:85:9)
|
||||
at #landFacts (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:775:40)
|
||||
at file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:761:36
|
||||
at Store.transaction (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.checkLand (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:756:24)
|
||||
at file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/tests/land.test.mjs:187:34
|
||||
at getActual (node:assert:580:5)
|
||||
at strict.throws (node:assert:728:24)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/tests/land.test.mjs:195:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14),
|
||||
expected: /work-ref/,
|
||||
operator: 'throws',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/land.test.mjs:218:1
|
||||
✖ a ticket outlives the run that asked, and recordLand checks the task again (239.557719ms)
|
||||
Error: decision-not-found
|
||||
at fail (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:85:9)
|
||||
at #landFacts (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:775:40)
|
||||
at file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:761:36
|
||||
at Store.transaction (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.checkLand (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:756:24)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/tests/land.test.mjs:221:26)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19) {
|
||||
code: 'decision-not-found'
|
||||
}
|
||||
|
||||
test at tests/land.test.mjs:235:1
|
||||
✖ landRefused files the code on the task, tells the role only with notify, and ends the ticket (261.776469ms)
|
||||
Error: decision-not-found
|
||||
at fail (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:85:9)
|
||||
at #landFacts (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:775:40)
|
||||
at file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:761:36
|
||||
at Store.transaction (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/store.mjs:242:22)
|
||||
at Broker.checkLand (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/src/broker.mjs:756:24)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/tests/land.test.mjs:238:21)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
|
||||
at Test.postRun (node:internal/test_runner/test:1542:19) {
|
||||
code: 'decision-not-found'
|
||||
}
|
||||
|
||||
test at tests/project-runtime.test.mjs:12:1
|
||||
✖ Broker keeps the existing sandbox client import closure: no new imports or lazy project import (2.074077ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal:
|
||||
+ actual - expected
|
||||
|
||||
[
|
||||
"import { randomUUID, randomBytes } from 'node:crypto';",
|
||||
"import { loadRequirements } from '../../tasks/src/requirements.mjs';",
|
||||
+ "import { MERGE, LandingRefusal, readLanding } from './landing.mjs';"
|
||||
]
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/bus/tests/project-runtime.test.mjs:14:10)
|
||||
at Test.runInAsyncScope (node:async_hooks:226:14)
|
||||
at Test.run (node:internal/test_runner/test:1402:25)
|
||||
at Test.start (node:internal/test_runner/test:1262:17)
|
||||
at startSubtestAfterBootstrap (node:internal/test_runner/harness:387:17) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: [ "import { randomUUID, randomBytes } from 'node:crypto';", "import { loadRequirements } from '../../tasks/src/requirements.mjs';", "import { MERGE, LandingRefusal, readLanding } from './landing.mjs';" ],
|
||||
expected: [ "import { randomUUID, randomBytes } from 'node:crypto';", "import { loadRequirements } from '../../tasks/src/requirements.mjs';" ],
|
||||
operator: 'deepStrictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1 REQ-MSG-1 a thread message starts the thread's session, which stops when idle; its history survives the stop and a restart and no other thread sees it (5355.268474ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1 a running thread counts against its model's limit and an idle-stopped one doesn't (1491.150316ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1 a turn longer than the idle time isn't stopped, and the thread idles out after it (4369.024927ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1 a message sent after the idle snapshot keeps the session, which answers it (2805.354208ms)
|
||||
✔ REQ-ROLE-2 REQ-LAUNCH-1 a thread held by a run the launcher didn't start gets no second session (50.252057ms)
|
||||
✔ REQ-LAUNCH-1 a run that ends without taking its thread's message isn't started again for that message (150.180822ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1 a thread id that isn't a safe segment, or a thread of a non-thread instance, launches nothing (178.824534ms)
|
||||
✔ REQ-THREAD-1 REQ-LAUNCH-1 the chief can't launch the assistant outside a thread (45.955149ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 8
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 14537.475334
|
||||
@@ -0,0 +1,280 @@
|
||||
✔ every screen and overlay fits 120x36, 80x24 and the narrow layout, row for row (1586.54654ms)
|
||||
✔ width counts terminal cells: wide CJK and emoji 2, U+FE0F after a one-cell base 1, marks 0 (85.154678ms)
|
||||
✔ broker text is shown, never interpreted: no raw control character or bidi override reaches the terminal (241.09577ms)
|
||||
✔ NO_COLOR: no escape codes, except reverse video on the selected row (311.198065ms)
|
||||
✔ 1-9 shows the decide flow's own lines and question; only y resolves (202.245549ms)
|
||||
✔ the app shows the same decide text as mosaic decide (111.612001ms)
|
||||
✔ any key but y or Y at the question answers No; nothing is sent (2965.181872ms)
|
||||
✔ below 40x10 the question is hidden, so every key answers it No, y included (Filbert R3) (484.467652ms)
|
||||
✔ under 40 columns a tall terminal shows the too-small screen even where the decide box would fit; y sends nothing (Filbert N10) (1681.765701ms)
|
||||
✔ a hidden decide box names the way out, and the status line under it does not promise y (Filbert N12) (136.021747ms)
|
||||
✔ a throw while answering the question goes to crash, sends nothing and leaves no job pending (138.620791ms)
|
||||
✔ type-ahead never answers the question: a paste, keys typed before it is drawn, keys inside askMs (891.976905ms)
|
||||
✔ quitting at the question answers No and sends nothing, armed or not (205.885793ms)
|
||||
✔ a timer tick reads nothing under an overlay, never answers the question, and keeps a resolved status (193.390657ms)
|
||||
✔ a long question is cut inside the question; the action, target, choice and prompt stay (Dewey B1) (141.573484ms)
|
||||
✔ a decide box too big for the terminal says so, and every key answers it No, y included (Dewey B1, round 3) (1003.140373ms)
|
||||
✔ at every size the decide box shows each line y depends on, or says it is hidden (8769.924433ms)
|
||||
✔ outcome unknown: the CLI's sentence, no retry, then the trail or a re-read (154.957595ms)
|
||||
✔ refused and failed reads keep the last list, marked stale; a refused decide says refused (161.821857ms)
|
||||
✔ help or a detail box cut to fit keeps its last line, Esc included (Dewey) (82.034227ms)
|
||||
✔ keys: views, moving, trail of a selection, the command line, help and quit (260.527119ms)
|
||||
✔ one option: the status line says Press 1, not 1-1 (98.222316ms)
|
||||
✔ no business: the app says so and :business picks one (50.30584ms)
|
||||
✔ mosaic with no argument: exit 3 in an agent run, exit 4 with the usage off a terminal, the app on one (1.808598ms)
|
||||
✔ scripts/mosaic with no argument reaches the app entry; the seat usage it printed before has not drifted (172.042218ms)
|
||||
✔ strings to keep exactly live once, in the decide flow and the transport; the app does not restate them (0.464708ms)
|
||||
✔ decide with --note still asks; a No sends nothing (68.612248ms)
|
||||
✔ the app's business comes from a live bus host only (0.953571ms)
|
||||
✔ runApp leaves the terminal as it found it on q, end of input, SIGTERM, SIGINT, SIGHUP and an error, the first frame's included (6.67894ms)
|
||||
✔ draw is pure: same state, same frame (0.713452ms)
|
||||
✔ recordBootRefused keeps the last good load across refusals; recordBootOk clears the refusal (5.037102ms)
|
||||
✔ an unknown key and a JSON syntax error each leave the bus down with the reason and path in the status (867.148087ms)
|
||||
✔ a missing file is recorded too, and a valid file clears the status on the next start (491.247325ms)
|
||||
✔ inbox lists only decisions routed to the human, with what approving authorizes and how to decide (241.566981ms)
|
||||
✔ decide resolves by id prefix with --yes, and the trail shows it in broker order with the task to follow (145.79187ms)
|
||||
✔ decide refuses without a terminal or --yes, on an unknown option and on a short reference (122.887234ms)
|
||||
✔ decide prints a declining choice as declining (210.407708ms)
|
||||
✔ an unknown outcome is reported once and never resent (183.588922ms)
|
||||
✔ a decision closed before the answer arrives exits 2 and points at its trail (133.895776ms)
|
||||
✔ a prefix that matches two open decisions exits 2 and resolves neither (115.014525ms)
|
||||
✔ without --business a command uses the live host's business, and a stale host.json is not a host (177.865231ms)
|
||||
✔ every human command refuses inside an agent run before it touches the bus (101.555991ms)
|
||||
✔ usage errors exit 4; no business and no host is a usage error (96.217485ms)
|
||||
✔ agents and tasks print through the broker (101.223497ms)
|
||||
✔ notify.json: missing, loose, malformed and extra keys refuse; a binding or null passes (3.83694ms)
|
||||
✔ bootConfig builds the broker's boot message for one business, with no trackers key when no project names one (71.180132ms)
|
||||
✔ trackers come from the tracker.* variables of the one project that names a tracker project (116.307676ms)
|
||||
✔ with two projects, the one that sets tracker.project supplies the tracker and the other is no conflict (50.667744ms)
|
||||
✔ two projects that each name a tracker project refuse, since the boot shape holds one (42.096612ms)
|
||||
✔ a business without tracker.baseUrl gets no trackers entry (38.095144ms)
|
||||
✔ an unknown business and a broken system config refuse with exit 3 (82.951068ms)
|
||||
✔ follow prints an unsolicited message after plain talk returned (293.530529ms)
|
||||
✔ talk --follow continues after reply and prints a later unsolicited message (200.981749ms)
|
||||
✔ inbox lists all unread human messages under decisions, does not deliver or read them (2836.214856ms)
|
||||
✔ follow refuses agent context and bad arguments (791.286088ms)
|
||||
✔ follow Ctrl-C wakes the poll sleep and removes its handler; transport errors also clean up (488.069176ms)
|
||||
✔ plain talk leaves the process SIGINT handlers unchanged (380.438616ms)
|
||||
✔ empty views say so (1.084811ms)
|
||||
✔ the trail keeps the broker's order and names a decision's task without its rows (1.332596ms)
|
||||
✔ tasks print the tracker fields the snapshot carries (0.246354ms)
|
||||
✔ the review loop: the coder pushes and asks, the reviewer fetches and approves, and the task's trail holds each step (971.292957ms)
|
||||
✔ refusals: no action, non-fast-forward, an unknown commit or request, and a push for another task moves only that task's ref (834.085703ms)
|
||||
✔ the size cap refuses a push before any byte (435.670784ms)
|
||||
✔ a fetch over the cap refuses before any byte reaches the reviewer (658.671094ms)
|
||||
✔ the socket refuses a request with no capability, an unknown one, and a bad request line (1421.403537ms)
|
||||
✔ a rigged clone runs nothing: hooks, fsmonitor, a filter, a gitlink and a symlinked .git/config leave no marker (1182.864034ms)
|
||||
✔ an identity with no role, or of another business, refuses not-a-role and moves no ref (440.342446ms)
|
||||
✔ a review of a project the business no longer has refuses unknown-project (608.242609ms)
|
||||
✔ past maxActive connections the socket refuses git-busy, and a hung-up connection frees its slot (309.593048ms)
|
||||
✔ close() answers host-closing to a connection still sending its request line (351.120084ms)
|
||||
✔ a bundle that trickles in refuses body-timeout at its deadline and frees its slot (897.782249ms)
|
||||
✔ a reviewer gone before its bundle was sent is filed fetch-aborted, not as the host's fault (818.554008ms)
|
||||
✔ a reviewer that hangs up the moment it has the whole bundle was served, not aborted (745.729918ms)
|
||||
✔ send: a close after every byte left is served; one that fails a queued write is fetch-aborted (41.491929ms)
|
||||
✔ a bundle with no bytes for bodyIdle refuses body-timeout long before its deadline (584.219189ms)
|
||||
✔ send: a close once the loop is past its last chunk is served, and a failed write there is fetch-aborted (44.066289ms)
|
||||
✔ letGo waits for an answer to leave for at most its cap, then destroys the socket (301.837235ms)
|
||||
✔ a record that fails and can't be undone refuses rollback-failed, which the host logs (515.458198ms)
|
||||
✖ land: the squash runs the gate in its own worktree, then main moves and the broker records it (405.51588ms)
|
||||
✔ land: refusals before the gate answer the role at once and leave main and no worktree (425.891445ms)
|
||||
✔ land: a failed gate is refused gate-failed with its step, told to the role, and main stays (393.989817ms)
|
||||
✔ land: a record the broker refuses moves main back, and the landing is refused with the broker's code (389.474689ms)
|
||||
✔ land: a second landing while one runs refuses land-busy, and close() stops the gate and refuses host-closing (368.681583ms)
|
||||
✔ the host boots the broker, binds a launch in process, and the notifier DMs a blocking decision exactly once (1041.793769ms)
|
||||
✔ a notifier that dies takes the host down with exit 1, so the unit restarts the pair (296.619584ms)
|
||||
✔ a second host for the same data root refuses with exit 3 while the first runs (219.812506ms)
|
||||
✔ two bus starts racing for one data root leave one host running; the other refuses that a host already runs (750.841709ms)
|
||||
✔ a host takes over a host.lock its dead host left, and puts back a live claim that replaced it meanwhile (2.787137ms)
|
||||
✔ a host.lock that goes between the check and the read is tried again; one that can't be parsed still refuses as unreadable (1.35886ms)
|
||||
✔ a live host's lock stays, however old the file is (0.719969ms)
|
||||
✔ a host.lock left by a host killed with SIGKILL doesn't stop the next bus start (997.571568ms)
|
||||
✔ while a host boots, a reader sees no host: the human commands still ask for --business, stop and status find none (204.431841ms)
|
||||
✔ a host started before host.lock existed, holding only host.json, still refuses a second start, which leaves no lock (45.72049ms)
|
||||
✔ a broker fork that throws leaves no host.lock and no host.json (28.699467ms)
|
||||
✔ a broker send that throws leaves no host.lock and no host.json (29.31541ms)
|
||||
✔ a broker that misses its boot wait leaves no host.lock and no host.json (48.839654ms)
|
||||
✔ a notifier fork that throws stops the broker and leaves no host.lock and no host.json (670.652778ms)
|
||||
✔ a notifier send that throws stops the broker and leaves no host.lock and no host.json (547.854572ms)
|
||||
✔ a boot reply with no reader for the business refuses with exit 3 naming it, before the notifier starts, and leaves no host.lock and no live broker (384.788051ms)
|
||||
✔ a boot reply with no reader for the business refuses with exit 3 naming it, with no notifier, and leaves no host.lock and no live broker (201.956185ms)
|
||||
✔ a host.json that can't be written stops both children and leaves no host.lock (296.389569ms)
|
||||
✔ an error event on the broker before it replies fails the start at once, and leaves no host.lock and no live child (29.775815ms)
|
||||
✔ an error event on the notifier before it replies fails the start at once, and leaves no host.lock and no live child (180.582127ms)
|
||||
✔ an error event on the broker while the notifier starts fails the start once the notifier replies (336.938125ms)
|
||||
✔ an error event on the broker once the host is up stops the host with exit 1, and leaves no host.lock and no host.json (401.251593ms)
|
||||
✔ an error event on the notifier once the host is up stops the host with exit 1, and leaves no host.lock and no host.json (291.839473ms)
|
||||
✔ a broker reply that misses the wait breaks the channel: the late reply answers nothing, later requests refuse, the host exits 1 (1246.70776ms)
|
||||
✔ a broker reply with another request's id, or none, breaks the channel and the host exits 1 (462.02535ms)
|
||||
✔ a broker reply with no request waiting breaks the channel and the host exits 1 (199.203098ms)
|
||||
✔ a notifier that refuses stops the broker and the host refuses with exit 3 (270.260742ms)
|
||||
✔ a notifier that refuses after the broker died still refuses with exit 3, without a send to the dead broker (243.483793ms)
|
||||
✔ a notifier that dies before it replies, after the broker died, still refuses, without a send to the dead broker (173.551652ms)
|
||||
✔ a close send that fails with EPIPE after the notifier refuses still gives the notifier's refusal, exit 3 (208.323474ms)
|
||||
✔ a close send that fails with EPIPE after the notifier dies unanswered still gives the notifier's error (163.750364ms)
|
||||
✔ close() whose stop and close sends fail with EPIPE still finishes, with exit 1 (235.634201ms)
|
||||
✔ watchChildren reports a child that died before it was called, and one that dies later (25.005153ms)
|
||||
✔ bus stop refuses to signal a live pid that is not a bus host (202.610935ms)
|
||||
✔ bus start refuses with exit 3 and the code when the broker refuses to boot; bus status names the lock (312.746842ms)
|
||||
✔ bus start refuses with exit 3 without a notifier config (118.252934ms)
|
||||
✔ bus start runs until bus stop; status reports it while it runs (806.388256ms)
|
||||
✔ bus-service.sh renders the unit and installs it into a given directory (62.869069ms)
|
||||
✔ bus-service.sh pins the claude binary, refuses one the unit can't carry, and renders without one (75.434352ms)
|
||||
✔ bus-service.sh refuses a directory pin and keeps a symlink default unresolved (16.064265ms)
|
||||
✔ bus-service.sh refuses a default claude without the execute bit, or in a PATH dir with a space (10.570917ms)
|
||||
✔ each launch rereads limits and model selections; lowered limits keep sessions and log exact hit (47.714601ms)
|
||||
✔ migration needs no bus/config, prints whole converted document, is idempotent and never writes (47.18683ms)
|
||||
✔ limits view/set use the human bus transport and pass only the explicit patch (1.965794ms)
|
||||
✔ post-119 example and Jason fixture migrate with checked inherited models; wrong or absent config refuses (247.458073ms)
|
||||
✔ plugins view/set use the human bus transport and pass only the explicit patch (vikunja:19/305) (2.750049ms)
|
||||
✔ zoned uses the IANA zone across DST (28.565406ms)
|
||||
✔ each open blocking decision is DM'd once, across polls and a restart; non-blocking ones are not (236.010176ms)
|
||||
✔ two blocking decisions get two DMs with different nonces (144.382429ms)
|
||||
✔ the digest nonce differs per business and per day and fits Discord's 25 characters (0.300151ms)
|
||||
✔ a failed DM is journaled, backs off, and is retried until it lands (125.390755ms)
|
||||
✔ five definite refusals stop a DM: one gave-up line, one log line, and a restart keeps the count (204.217673ms)
|
||||
✔ 429s, 5xx-style unknowns and refusals without a status never count toward the limit (192.586092ms)
|
||||
✔ a crash between the fifth refusal and its gave-up line: the next poll appends it and sends nothing (132.48634ms)
|
||||
✔ polled every POLL_MS against a permanent 403, a DM is sent at 0, 30, 60, 90 and 120 min and gives up only then (226.611067ms)
|
||||
✔ a restart after the second refusal does not send before that refusal's 30 min are up (233.992363ms)
|
||||
✔ the digest goes at 08:00 Chicago once a day, with blocking ones marked as DM'd (118.320469ms)
|
||||
✔ a late start with no digest for the day sends one at once; an empty inbox gets one line (94.655551ms)
|
||||
✔ an inbox read failure is logged and the next poll retries (1.409802ms)
|
||||
✔ no Discord id reaches the journal or the log (113.249298ms)
|
||||
✔ the journal: a torn tail is copied out and truncated, so an append after it reopens cleanly (71.286517ms)
|
||||
✔ the journal: a crash between the copy and the truncate leaves a tail the next open repairs (54.509437ms)
|
||||
✔ the journal: a whole file that is one torn line truncates to empty (29.435327ms)
|
||||
✔ the journal: a malformed complete line refuses and leaves the file and any torn tail alone (2.300847ms)
|
||||
✔ the journal: a loose file mode, a loose directory or a symlinked journal refuses (2.827955ms)
|
||||
✔ the journal: a line with a wrong type refuses with exit 3 and names the field (4.526814ms)
|
||||
✔ the journal: a symlinked directory refuses and says it is a link (0.597224ms)
|
||||
✔ the journal: a dangling directory link, a parent that is a file and a journal that is a directory each refuse with exit 3 (0.585617ms)
|
||||
✔ the journal: an append after the file was swapped for a symlink refuses and writes nothing through it (0.467884ms)
|
||||
✔ the journal: a directory it cannot write or create refuses with exit 3 and names the path (0.519466ms)
|
||||
✔ digest content stays within Discord's 2000 characters (0.368765ms)
|
||||
✔ runLoop never overlaps ticks and stops after the one in flight (110.36339ms)
|
||||
✔ a human command refused with human-required prints the other-tree line and exits 3 (4.006243ms)
|
||||
✔ a --tester command refused with tester-required prints the other-tree line and exits 3 (1.585394ms)
|
||||
✔ other exit-3 refusals print no other-tree line (2.246136ms)
|
||||
✔ the line names no path (0.15946ms)
|
||||
✔ project init/check use declared business repo and never contact the bus (182.263126ms)
|
||||
✔ project commands validate args and refuse undeclared projects and agent init (35.65919ms)
|
||||
✔ project dispatcher reaches the human CLI (117.090338ms)
|
||||
✔ shared copy: npm ci, pushed reachability, readonly/existing copy, webui delegation (758.840692ms)
|
||||
✔ wrapper preserves Q81 lease and marker, rejects foreign/symlink; check uses effective roots (499.524781ms)
|
||||
✔ bus unit copy/pm pins, install refuses all busy states and failed reads, drop-in refusal (594.108914ms)
|
||||
✔ missing package manifest refuses before npm; npm failure removes the unpublished temp copy (303.569235ms)
|
||||
✔ real pinned install loads bus and Console; same-copy mosaic talk passes proof, other trees refuse (4415.630353ms)
|
||||
✔ bus status reads effective copy/pm/drop-ins without writes; check refuses an overridden ExecStart (526.939803ms)
|
||||
✔ drop-ins in either override field and malformed metadata refuse; uninstall also checks --no-reload (202.019081ms)
|
||||
✔ install never shows a template name on systemd 261; template drop-ins still refuse (220.617525ms)
|
||||
✔ unlisted instance drop-in is found in another unit lookup directory; path discovery errors refuse (191.803318ms)
|
||||
✔ inherited mosaic-.service.d override refuses without changing the unit (192.633764ms)
|
||||
✔ inherited service.d override refuses without changing the unit (213.873028ms)
|
||||
✔ inherited drop-in unreadable directory or file refuses before writing (205.226014ms)
|
||||
✔ talk --tester sends a [mos test] message as tester from inside an agent and prints the role's reply (224.693752ms)
|
||||
✔ talk --tester refuses text without the [mos test] prefix before any call (114.418366ms)
|
||||
✔ the read verbs take --tester inside an agent, and the trail shows the tester as the sender (129.233542ms)
|
||||
✔ decide, stop and launches take no --tester (189.784694ms)
|
||||
✔ the tester transport runs tester-cli.mjs, and the tester's refusals exit 3 (0.406072ms)
|
||||
✔ with no stand-in transport, --tester runs tester-cli.mjs on the data root's socket (0.656394ms)
|
||||
✔ talk --tester to a stopped role says nobody is told to launch it (174.753155ms)
|
||||
✖ REQ-THREAD-2 REQ-LAUNCH-1 REQ-MSG-1 a thread message starts the thread's session, which stops when idle; its history survives the stop and a restart and no other thread sees it (20289.307699ms)
|
||||
✖ REQ-THREAD-2 REQ-LAUNCH-1 a running thread counts against its model's limit and an idle-stopped one doesn't (264.278986ms)
|
||||
✖ REQ-THREAD-2 REQ-LAUNCH-1 a turn longer than the idle time isn't stopped, and the thread idles out after it (30132.369423ms)
|
||||
✖ REQ-THREAD-2 REQ-LAUNCH-1 a message sent after the idle snapshot keeps the session, which answers it (20166.195003ms)
|
||||
✔ REQ-ROLE-2 REQ-LAUNCH-1 a thread held by a run the launcher didn't start gets no second session (123.779554ms)
|
||||
✖ REQ-LAUNCH-1 a run that ends without taking its thread's message isn't started again for that message (20203.107203ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1 a thread id that isn't a safe segment, or a thread of a non-thread instance, launches nothing (257.451435ms)
|
||||
✔ REQ-THREAD-1 REQ-LAUNCH-1 the chief can't launch the assistant outside a thread (104.2624ms)
|
||||
task.close {} answered: invalid-request; fake saw 18 requests, first GET /info 200, GET /projects/1 200, GET /projects/1/views 200
|
||||
task.close on a missing task answered: task-not-found; it made GET /tasks/999 404
|
||||
✔ bootConfig trackers reach the S3 adapter in the real broker child, which goes ready against a fake Vikunja (523.56421ms)
|
||||
✔ the transport writes {business, verb, args} to the child and reads its JSON (51.20011ms)
|
||||
✔ a bus code on stderr becomes the exit code; garbage and timeouts are outcome problems (2188.017122ms)
|
||||
✔ busExit and refuseInsideAgent (0.635562ms)
|
||||
✔ talk sends a REQUEST, prints and reads only the reply to it, and leaves other messages unread (366.400166ms)
|
||||
✔ talk --wait 0 only sends; no reply within --wait exits 1 and says where it will show (1159.768427ms)
|
||||
✔ a late reply the Console has listed stays unread for mosaic inbox, and the next talk skips it (2346.666044ms)
|
||||
✔ talk says when the role isn't running, whether launch.by was told, and how to start launch.by (944.888744ms)
|
||||
✔ talk to a role launch.by can't launch says it isn't in the launch block (144.870441ms)
|
||||
✔ talk to a stopped role prints the waiting line once, skips a non-reply and prints the reply (236.244028ms)
|
||||
✔ talk, stop and launches off/on refuse inside an agent run; bad arguments are usage errors (109.627425ms)
|
||||
✔ launches off and on go to the broker and change the business's launch state (101.990085ms)
|
||||
✔ launches list reads sessions.json and marks a stale entry; stop reports it and refuses a non-runner (119.454281ms)
|
||||
ℹ tests 202
|
||||
ℹ suites 0
|
||||
ℹ pass 196
|
||||
ℹ fail 6
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 91785.656988
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at tests/git-socket.test.mjs:681:1
|
||||
✖ land: the squash runs the gate in its own worktree, then main moves and the broker records it (405.51588ms)
|
||||
AssertionError [ERR_ASSERTION]: Applied-under: git socket land (bus host)
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/git-socket.test.mjs:704:201)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: false,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: false,
|
||||
expected: true,
|
||||
operator: '==',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/thread-launch.test.mjs:157:1
|
||||
✖ REQ-THREAD-2 REQ-LAUNCH-1 REQ-MSG-1 a thread message starts the thread's session, which stops when idle; its history survives the stop and a restart and no other thread sees it (20289.307699ms)
|
||||
Error: timed out waiting
|
||||
at until (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/thread-launch.test.mjs:41:9)
|
||||
at async ask (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/thread-launch.test.mjs:143:17)
|
||||
at async TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/thread-launch.test.mjs:169:17)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
|
||||
test at tests/thread-launch.test.mjs:205:1
|
||||
✖ REQ-THREAD-2 REQ-LAUNCH-1 a running thread counts against its model's limit and an idle-stopped one doesn't (264.278986ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
+ actual - expected
|
||||
|
||||
+ 'launch-failed'
|
||||
- 'capacity-full'
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/thread-launch.test.mjs:216:10)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 'launch-failed',
|
||||
expected: 'capacity-full',
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/thread-launch.test.mjs:230:1
|
||||
✖ REQ-THREAD-2 REQ-LAUNCH-1 a turn longer than the idle time isn't stopped, and the thread idles out after it (30132.369423ms)
|
||||
Error: timed out waiting
|
||||
at until (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/thread-launch.test.mjs:41:9)
|
||||
at async TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/thread-launch.test.mjs:240:3)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
|
||||
test at tests/thread-launch.test.mjs:247:1
|
||||
✖ REQ-THREAD-2 REQ-LAUNCH-1 a message sent after the idle snapshot keeps the session, which answers it (20166.195003ms)
|
||||
Error: timed out waiting
|
||||
at until (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/thread-launch.test.mjs:41:9)
|
||||
at async TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/thread-launch.test.mjs:268:3)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
|
||||
test at tests/thread-launch.test.mjs:305:1
|
||||
✖ REQ-LAUNCH-1 a run that ends without taking its thread's message isn't started again for that message (20203.107203ms)
|
||||
Error: timed out waiting
|
||||
at until (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/thread-launch.test.mjs:41:9)
|
||||
at async TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/thread-launch.test.mjs:319:15)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
@@ -0,0 +1,70 @@
|
||||
✖ REQ-THREAD-2 REQ-LAUNCH-1 REQ-MSG-1 a thread message starts the thread's session, which stops when idle; its history survives the stop and a restart and no other thread sees it (20089.359097ms)
|
||||
✖ REQ-THREAD-2 REQ-LAUNCH-1 a running thread counts against its model's limit and an idle-stopped one doesn't (213.225675ms)
|
||||
✖ REQ-THREAD-2 REQ-LAUNCH-1 a turn longer than the idle time isn't stopped, and the thread idles out after it (30097.204022ms)
|
||||
✖ REQ-THREAD-2 REQ-LAUNCH-1 a message sent after the idle snapshot keeps the session, which answers it (20111.345033ms)
|
||||
✔ REQ-ROLE-2 REQ-LAUNCH-1 a thread held by a run the launcher didn't start gets no second session (64.830451ms)
|
||||
✖ REQ-LAUNCH-1 a run that ends without taking its thread's message isn't started again for that message (20124.549297ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1 a thread id that isn't a safe segment, or a thread of a non-thread instance, launches nothing (188.933703ms)
|
||||
✔ REQ-THREAD-1 REQ-LAUNCH-1 the chief can't launch the assistant outside a thread (65.066059ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 3
|
||||
ℹ fail 5
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 91061.303114
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at tests/thread-launch.test.mjs:157:1
|
||||
✖ REQ-THREAD-2 REQ-LAUNCH-1 REQ-MSG-1 a thread message starts the thread's session, which stops when idle; its history survives the stop and a restart and no other thread sees it (20089.359097ms)
|
||||
Error: timed out waiting
|
||||
at until (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/thread-launch.test.mjs:41:9)
|
||||
at async ask (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/thread-launch.test.mjs:143:17)
|
||||
at async TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/thread-launch.test.mjs:169:17)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3)
|
||||
|
||||
test at tests/thread-launch.test.mjs:205:1
|
||||
✖ REQ-THREAD-2 REQ-LAUNCH-1 a running thread counts against its model's limit and an idle-stopped one doesn't (213.225675ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
+ actual - expected
|
||||
|
||||
+ 'launch-failed'
|
||||
- 'capacity-full'
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/thread-launch.test.mjs:216:10)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: 'launch-failed',
|
||||
expected: 'capacity-full',
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/thread-launch.test.mjs:230:1
|
||||
✖ REQ-THREAD-2 REQ-LAUNCH-1 a turn longer than the idle time isn't stopped, and the thread idles out after it (30097.204022ms)
|
||||
Error: timed out waiting
|
||||
at until (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/thread-launch.test.mjs:41:9)
|
||||
at async TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/thread-launch.test.mjs:240:3)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
|
||||
test at tests/thread-launch.test.mjs:247:1
|
||||
✖ REQ-THREAD-2 REQ-LAUNCH-1 a message sent after the idle snapshot keeps the session, which answers it (20111.345033ms)
|
||||
Error: timed out waiting
|
||||
at until (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/thread-launch.test.mjs:41:9)
|
||||
at async TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/thread-launch.test.mjs:268:3)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
|
||||
test at tests/thread-launch.test.mjs:305:1
|
||||
✖ REQ-LAUNCH-1 a run that ends without taking its thread's message isn't started again for that message (20124.549297ms)
|
||||
Error: timed out waiting
|
||||
at until (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/thread-launch.test.mjs:41:9)
|
||||
at async TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/thread-launch.test.mjs:319:15)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
@@ -0,0 +1,27 @@
|
||||
✔ bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest (1202.307722ms)
|
||||
✔ the chief of staff launches a coder through its launch tool; the coder answers; refusals name their code (431.292479ms)
|
||||
✔ a launched pm's request_staff reaches the chief of staff; no other session has the tool and the launch limits still hold (879.568947ms)
|
||||
✔ each launch makes sure the workspace has a clone of the project: cloned, fast-forwarded, or fetched and logged (3595.780022ms)
|
||||
✔ a role the broker says holds a merge decision gets land_work, its prompt line and the git socket; without it, none (362.623568ms)
|
||||
✔ a project clone that can't be made refuses checkout-failed, from --chief and from a session, with no run and no clone left (142.570763ms)
|
||||
✔ a runner that stops at once ends its launch with the runner's reason (209.45992ms)
|
||||
✔ a Claude Code launch with no session credential refuses before it starts (113.602047ms)
|
||||
✔ a pi launch needs no session credential: pi logs in through its own ENV_ALLOW variables (195.268534ms)
|
||||
✔ a runner killed from the host ends its launch as killed, not failed (260.755627ms)
|
||||
✔ a missing or failing bwrap refuses sandbox-unavailable before anything starts; there is no unconfined fallback (119.116659ms)
|
||||
✔ a real Claude Code coder's shell can't read a stand-in secret or anything else its sandbox doesn't hold (1017.539544ms)
|
||||
✔ a host that died hard leaves its sessions to the next host, which kills them and ends their runs so the role can be launched again (668.125675ms)
|
||||
✔ a host that died hard leaves its sessions to the next host, which finds one already exited (23) and ends their runs so the role can be launched again (3653.685549ms)
|
||||
✔ a malformed sessions.json refuses the host start with exit 3 and stays as it was (124.518299ms)
|
||||
✔ an over-long launch request is refused at once, not at the 10 s idle timeout (123.525994ms)
|
||||
✔ a launch client that never closes its side doesn't hold the host's close (127.649735ms)
|
||||
✔ a runner that ignores SIGTERM is killed when the host closes (1268.041829ms)
|
||||
✔ claudeVersion asks MOSAIC_CLAUDE_BIN when set, else claude on PATH (4.577645ms)
|
||||
ℹ tests 19
|
||||
ℹ suites 0
|
||||
ℹ pass 19
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 14588.082229
|
||||
@@ -0,0 +1,40 @@
|
||||
✔ bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest (1221.688504ms)
|
||||
✔ the chief of staff launches a coder through its launch tool; the coder answers; refusals name their code (431.583027ms)
|
||||
✔ a launched pm's request_staff reaches the chief of staff; no other session has the tool and the launch limits still hold (883.815567ms)
|
||||
✔ each launch makes sure the workspace has a clone of the project: cloned, fast-forwarded, or fetched and logged (3596.266654ms)
|
||||
✖ a role the broker says holds a merge decision gets land_work, its prompt line and the git socket; without it, none (107.851503ms)
|
||||
✔ a project clone that can't be made refuses checkout-failed, from --chief and from a session, with no run and no clone left (138.328266ms)
|
||||
✔ a runner that stops at once ends its launch with the runner's reason (208.047689ms)
|
||||
✔ a Claude Code launch with no session credential refuses before it starts (114.70623ms)
|
||||
✔ a pi launch needs no session credential: pi logs in through its own ENV_ALLOW variables (222.613902ms)
|
||||
✔ a runner killed from the host ends its launch as killed, not failed (325.826349ms)
|
||||
✔ a missing or failing bwrap refuses sandbox-unavailable before anything starts; there is no unconfined fallback (124.477897ms)
|
||||
✔ a real Claude Code coder's shell can't read a stand-in secret or anything else its sandbox doesn't hold (1142.29206ms)
|
||||
✔ a host that died hard leaves its sessions to the next host, which kills them and ends their runs so the role can be launched again (674.537386ms)
|
||||
✔ a host that died hard leaves its sessions to the next host, which finds one already exited (23) and ends their runs so the role can be launched again (3614.297677ms)
|
||||
✔ a malformed sessions.json refuses the host start with exit 3 and stays as it was (113.518859ms)
|
||||
✔ an over-long launch request is refused at once, not at the 10 s idle timeout (113.663326ms)
|
||||
✔ a launch client that never closes its side doesn't hold the host's close (119.225169ms)
|
||||
✔ a runner that ignores SIGTERM is killed when the host closes (1234.844201ms)
|
||||
✔ claudeVersion asks MOSAIC_CLAUDE_BIN when set, else claude on PATH (4.595537ms)
|
||||
ℹ tests 19
|
||||
ℹ suites 0
|
||||
ℹ pass 18
|
||||
ℹ fail 1
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 14488.29819
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at tests/launcher.test.mjs:391:1
|
||||
✖ a role the broker says holds a merge decision gets land_work, its prompt line and the git socket; without it, none (107.851503ms)
|
||||
TypeError: Cannot assign to read only property 'op' of object '#<Object>'
|
||||
at Object.assign (<anonymous>)
|
||||
at wrap (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/launcher.test.mjs:393:57)
|
||||
at setup (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/launcher.test.mjs:92:13)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/cli/tests/launcher.test.mjs:397:15)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7)
|
||||
@@ -0,0 +1,16 @@
|
||||
✔ rootHits: a top-level file, a new top-level directory, src/ and v1/ are the root; paths under known directories aren't (1.424583ms)
|
||||
✔ gateEnv keeps the named variables that are strings and drops everything else (0.150863ms)
|
||||
✔ isMosaicStack: a checkout whose HEAD descends from the root commit and has node_modules; nothing else (35.25504ms)
|
||||
✔ gateSteps: each package with tests but queue in name order, then each scripts/test-*.sh (1.27315ms)
|
||||
✔ runGate: every step passes, each with its own log and a summary line, under the environment it was given (141.957345ms)
|
||||
✔ runGate: the first failing step stops the gate and names its log (213.391947ms)
|
||||
✔ runGate: an abort stops the running step and everything in its group, and runs nothing after it (163.113586ms)
|
||||
✔ the CLI: root-file prints the hits and exits 2, or exits 0; gate exits 0, or 2 with the step and its log; anything else is usage (529.928359ms)
|
||||
ℹ tests 8
|
||||
ℹ suites 0
|
||||
ℹ pass 8
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1132.663811
|
||||
@@ -0,0 +1,199 @@
|
||||
✔ a first launch clones the root at its branch, with the root's path as origin (33.780741ms)
|
||||
✔ the clone is not at its place until git clone has finished (23.824884ms)
|
||||
✔ a later launch fast-forwards a clean clone after a commit to the root, then finds it current (68.084632ms)
|
||||
✔ a clone ahead of the root keeps its commits and counts as current (44.68769ms)
|
||||
▶ a dirty clone and one on another branch are fetched, and nothing but refs/remotes moves
|
||||
✔ a modified file (48.03528ms)
|
||||
✔ an untracked file (46.359055ms)
|
||||
✔ a staged file (43.079086ms)
|
||||
✔ another branch (42.915501ms)
|
||||
✔ a detached HEAD (49.981539ms)
|
||||
✔ a dirty clone and one on another branch are fetched, and nothing but refs/remotes moves (231.50517ms)
|
||||
✔ a diverged clone gets the fetch into refs/remotes and is kept, not-fast-forward (49.275804ms)
|
||||
▶ a clone kept before the branch check, or for a failed status, gets no fetch
|
||||
✔ not-a-clone (30.129059ms)
|
||||
✔ hooks-present (29.626879ms)
|
||||
✔ submodule (38.181524ms)
|
||||
✔ config-changed (32.597796ms)
|
||||
✔ root-unreadable (31.817972ms)
|
||||
✔ root-detached (35.217986ms)
|
||||
✔ status-failed, on the root's branch and clean (37.881384ms)
|
||||
✔ status-failed, dirty (36.624416ms)
|
||||
✔ a clone kept before the branch check, or for a failed status, gets no fetch (273.378164ms)
|
||||
✔ a dirty clone whose fetch fails is kept, fetch-failed, exactly as it was (37.661727ms)
|
||||
✔ every git call the host makes, for a new clone and an existing one, carries maintenance.auto=false and gc.auto=0 (50.16932ms)
|
||||
✔ a clone with loose objects enough for gc --auto gets no maintenance or gc from the fetch and the merge (78.93048ms)
|
||||
▶ a clone with user.name or user.email in its config is kept, and git runs nothing in it
|
||||
✔ user.name (26.868432ms)
|
||||
✔ user.email (27.934343ms)
|
||||
✔ a clone with user.name or user.email in its config is kept, and git runs nothing in it (55.265042ms)
|
||||
✔ a commit git can't read after the fast-forward is null (48.984355ms)
|
||||
✔ a new clone whose commit can't be read refuses the launch and leaves nothing behind (21.541438ms)
|
||||
▶ a clone the session rigged is kept, and git runs nothing and writes nothing outside it
|
||||
✔ core.fsmonitor (35.603151ms)
|
||||
✔ core.hooksPath (34.737046ms)
|
||||
✔ a hook file (33.232331ms)
|
||||
✔ include.path (36.30016ms)
|
||||
✔ includeIf (35.232282ms)
|
||||
✔ a filter driver (32.900995ms)
|
||||
✔ origin moved (33.949975ms)
|
||||
✔ a second origin url (34.74862ms)
|
||||
✔ the origin url twice, both the root (34.966195ms)
|
||||
✔ an ext:: origin (37.636707ms)
|
||||
✔ a branch tracking another remote (32.251826ms)
|
||||
✔ a branch merging a tag (33.575779ms)
|
||||
✔ a fetch line onto local branches (34.315906ms)
|
||||
✔ no origin (38.652341ms)
|
||||
✔ a config file over the size cap (36.21229ms)
|
||||
✔ config a symlink to /dev/zero (34.640648ms)
|
||||
✔ the clone a symlink to the bait (31.285268ms)
|
||||
✔ the clone a file (32.583438ms)
|
||||
✔ the clone a plain directory (33.026692ms)
|
||||
✔ .git a gitdir: file (31.237799ms)
|
||||
✔ .git a symlink (30.421966ms)
|
||||
✔ .git/logs a symlink (31.363094ms)
|
||||
✔ .git/refs/heads a symlink (32.354658ms)
|
||||
✔ .git/objects a symlink (33.31079ms)
|
||||
✔ a reflog hard-linked to a file outside (32.521602ms)
|
||||
✔ HEAD a fifo (31.320266ms)
|
||||
✔ a commondir file (33.454178ms)
|
||||
✔ an alternates file (31.914408ms)
|
||||
✔ a gitlink staged, no .gitmodules (45.229707ms)
|
||||
✔ a gitlink and .gitmodules staged (45.616457ms)
|
||||
✔ a gitlink to a repository with its own gitlink (52.44187ms)
|
||||
✔ a gitlink and .gitmodules committed (47.801858ms)
|
||||
✔ a gitlink and submodule.active in config (46.540826ms)
|
||||
✔ a .git/modules with no gitlink (33.556382ms)
|
||||
✔ a clone the session rigged is kept, and git runs nothing and writes nothing outside it (1219.218153ms)
|
||||
▶ a root that can't be cloned refuses with the project id and leaves nothing behind
|
||||
✔ missing (9.940027ms)
|
||||
✔ not a repository (9.805732ms)
|
||||
✔ a plain directory inside another repository (15.698224ms)
|
||||
✔ unreadable (11.842842ms)
|
||||
✔ on no branch (11.847933ms)
|
||||
✔ missing an object (18.513393ms)
|
||||
✔ a root that can't be cloned refuses with the project id and leaves nothing behind (78.431515ms)
|
||||
✔ a clone whose root is on no branch, or gone, is kept and named (28.240299ms)
|
||||
✔ no credential or forge remote of the root reaches a clone (48.117801ms)
|
||||
✔ every project in the business file gets its own clone at its own branch (35.215117ms)
|
||||
✔ a clone past its time gets SIGTERM and refuses the launch, with nothing left in the workspace (513.254587ms)
|
||||
✔ a clone that ignores SIGTERM gets SIGKILL once the grace period is over (1015.975689ms)
|
||||
✔ a timeout signals git's process group, so a process git started dies with it (512.959495ms)
|
||||
✔ once a signalled git has closed, its group gets SIGKILL, so a process that ignored SIGTERM dies too (513.521346ms)
|
||||
✔ rootHits: a top-level file, a new top-level directory, src/ and v1/ are the root; paths under known directories aren't (1.547572ms)
|
||||
✔ gateEnv keeps the named variables that are strings and drops everything else (0.162313ms)
|
||||
✔ isMosaicStack: a checkout whose HEAD descends from the root commit and has node_modules; nothing else (27.068869ms)
|
||||
✔ gateSteps: each package with tests but queue in name order, then each scripts/test-*.sh (1.387808ms)
|
||||
✔ runGate: every step passes, each with its own log and a summary line, under the environment it was given (157.717577ms)
|
||||
✖ runGate: the first failing step stops the gate and names its log (147.364142ms)
|
||||
✖ runGate: an abort stops the running step and everything in its group, and runs nothing after it (163.168203ms)
|
||||
✔ the CLI: root-file prints the hits and exits 2, or exits 0; gate exits 0, or 2 with the step and its log; anything else is usage (550.085413ms)
|
||||
✔ RUNNER_FILES is exactly what the runner and the harness sources it starts import (1.985402ms)
|
||||
✔ sandboxProblem names a missing bwrap and a bwrap that fails (8.851839ms)
|
||||
✔ every bind says why; the bundle and session file stay read-only over the run directory (1.279942ms)
|
||||
✔ REQ-THREAD-2 a thread store binds its session directory and Claude transcripts, and nothing more (0.84569ms)
|
||||
✔ the host's git socket is bound only when given, read-only and before the writable binds (0.691092ms)
|
||||
✔ the git identity is the instance's, at <instance>@<business>.mosaic.invalid, and sandboxArgv refuses without it (1.199414ms)
|
||||
✔ a confined session's shell reaches its own workspace and run directory and nothing of the founder's or another session's (1707.874339ms)
|
||||
✔ a bind that exposes a stand-in, or a missing workspace bind, fails the matching check (2469.427669ms)
|
||||
✔ a confined session that runs tester-cli.mjs is refused as tester, and the same shim outside the sandbox binds (263.65085ms)
|
||||
✔ resolveSeat: by name under --repo resolves the repo layout (1.252956ms)
|
||||
✔ resolveSeat: by path resolves the fleet layout (0.315026ms)
|
||||
✔ resolveSeat: refusals for missing dir, missing launch.sh, non-executable launch.sh, invalid name, and unknown layout (0.741634ms)
|
||||
✔ tmuxContext: outside tmux, default socket, custom socket, and exec failure (0.647829ms)
|
||||
✔ makeRegistration produces a record that validates; each shape violation throws SeatError (0.896433ms)
|
||||
✔ writeRegistration/readRegistration: round trip, permissions, absence, and malformed records (1.354151ms)
|
||||
✔ updateTask: changes task, taskSetBy and updatedAt only, and refuses appropriately (1.185631ms)
|
||||
✔ CLI launch: registers, execs the fake launch script, and passes args through (29.540712ms)
|
||||
✔ CLI launch: --harness lands in the record (28.689824ms)
|
||||
✔ CLI launch: the launch script's own exit code passes through (26.996727ms)
|
||||
✔ CLI launch: relaunching a seat rewrites the one registration record (61.34607ms)
|
||||
✔ CLI launch: omitting --task records an empty string, not null (28.79304ms)
|
||||
✔ CLI seat task: updates only the task after a launch, and refuses on an unlaunched seat (83.001905ms)
|
||||
✔ CLI refusals: no args, unknown flag, missing config, already-registered env, and exec failure (135.400989ms)
|
||||
✔ samePath: equal paths, symlinked dirs, distinct dirs, and non-strings (0.478489ms)
|
||||
✔ resolveSetBy: explicit --by wins over the environment; absent or empty environment gives unknown; invalid explicit or environment values refuse with exit 4 (0.706764ms)
|
||||
✔ validateRegistration/readRegistration: taskSetBy is optional; a record without it (written before #1511) still loads unchanged; an invalid one is refused; the version does not change (0.71127ms)
|
||||
✔ updateTask: records setBy, preserves startedAt and every unrelated field, upgrades an old record in place only when the task is set, and replaces a previous attribution (1.171762ms)
|
||||
✔ CLI seat task: --by beats MOSAIC_AGENT_NAME, the environment beats nothing, empty environment is unknown, invalid --by or environment refuses with exit 4 and leaves the record byte for byte (269.787114ms)
|
||||
✔ REQ-LIMIT-1: family substring matching is no longer exported (0.801036ms)
|
||||
✔ sessionEnv passes only the allowlist, the repo's bin on PATH, and the run id (0.689715ms)
|
||||
✔ sessionExit gives a runner's signal death back as the signal; a session credential is one whole set of nonempty variables (0.269757ms)
|
||||
✔ newRun: short ids, 0700 directories, and a refusal when the socket path won't fit (1.466905ms)
|
||||
✔ session file and launch log: 0600, the session file written once (1.010292ms)
|
||||
✔ endReason maps the runner's exit codes; a signal is killed (0.116223ms)
|
||||
✔ Registry mirrors to sessions.json; readSessions marks live entries; bad files refuse (1.193741ms)
|
||||
✔ REQ-THREAD-1 Registry.running keys a thread run by business, instance and thread (0.588223ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1 threadStore checks both segments before the join and refuses an unsafe directory (2.867402ms)
|
||||
✔ stopSession refuses an unknown run, reports a stale one, and won't signal a pid that isn't a runner (1.871553ms)
|
||||
✔ a session runs in its sandbox as pid 1 of its namespace, claims, answers, and stops on mosaic stop (281.694173ms)
|
||||
✔ workRef and validBranch take only what a ref name can hold (1.147966ms)
|
||||
✔ a push lands as the task's work ref, a fast-forward lands after it, and main is the root's (160.304935ms)
|
||||
✔ a rewritten branch refuses non-fast-forward and the work ref stays (136.741882ms)
|
||||
✔ a branch with no history in common with main refuses unrelated-history (72.040763ms)
|
||||
✔ a bundle that needs commits the working repository lacks refuses missing-prerequisite (49.363452ms)
|
||||
✔ the root is fetched again before each push and main follows it, so a clone of a newer root pushes (173.705653ms)
|
||||
✔ a root moved back after the clone leaves the push's base unknown: missing-prerequisite (96.934926ms)
|
||||
✔ a commit with a broken object refuses invalid-bundle, and only because fsck is on (89.154899ms)
|
||||
✔ only a v2 bundle with the named branch is read (54.575858ms)
|
||||
✔ a branch named main, or named for another task, moves only this task's work ref (99.122228ms)
|
||||
✔ a record that throws moves the work ref back, or removes a new one (156.481748ms)
|
||||
✔ a work ref that can't go back refuses rollback-failed, naming the ref and the commit (396.377187ms)
|
||||
✔ a root that can't be read refuses root-unreadable (31.210664ms)
|
||||
✔ a git past its time gets SIGTERM, leaves no ref lock, and the next push lands (2195.080989ms)
|
||||
✔ a git that ignores SIGTERM gets SIGKILL once the grace period is over (1029.037334ms)
|
||||
✔ a working repository path that isn't a directory refuses (23.617561ms)
|
||||
✔ review bundles a pushed commit as refs/mosaic/review, leaving out what the reviewer has (120.949682ms)
|
||||
✔ review of a project with no working repository refuses unknown-commit (13.391771ms)
|
||||
✔ the runner's git tools hold the host's limits and branch rule (1.241609ms)
|
||||
✔ a reseed moves root but leaves a landed main, and main forwards once root contains it (215.29908ms)
|
||||
✔ after a landing, a push built on the root still lands and main stays where the landing put it (147.057776ms)
|
||||
✔ a landing squashes the reviewed diff onto main as the bus host and moves main only at finish (121.311561ms)
|
||||
✔ a landing refuses ref-moved, base-conflict and root-file before it makes a commit (361.948194ms)
|
||||
✔ finish refuses base-moved when main moved, and a record that throws moves main back (247.841541ms)
|
||||
ℹ tests 148
|
||||
ℹ suites 0
|
||||
ℹ pass 146
|
||||
ℹ fail 2
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 6055.97211
|
||||
|
||||
✖ failing tests:
|
||||
|
||||
test at tests/landing.test.mjs:126:1
|
||||
✖ runGate: the first failing step stops the gate and names its log (147.364142ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
true !== false
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/seat/tests/landing.test.mjs:132:10)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: true,
|
||||
expected: false,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
|
||||
test at tests/landing.test.mjs:142:1
|
||||
✖ runGate: an abort stops the running step and everything in its group, and runs nothing after it (163.168203ms)
|
||||
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
|
||||
|
||||
true !== false
|
||||
|
||||
at TestContext.<anonymous> (file:///home/jwoltje/darkwing-scratch/r137/wt/packages/seat/tests/landing.test.mjs:163:10)
|
||||
at process.processTicksAndRejections (node:internal/process/task_queues:104:5)
|
||||
at async Test.run (node:internal/test_runner/test:1409:7)
|
||||
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
|
||||
generatedMessage: true,
|
||||
code: 'ERR_ASSERTION',
|
||||
actual: true,
|
||||
expected: false,
|
||||
operator: 'strictEqual',
|
||||
diff: 'simple'
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
base 7a2987cf5 DOCKER_HOST=unset docker=29.7.2 start 18:49:43
|
||||
pkg-bus rc=0 18:49:43-18:49:55 ℹ pass 302 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 11643.870722
|
||||
pkg-business rc=0 18:49:55-18:49:57 ℹ pass 109 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 1902.454793
|
||||
pkg-cli rc=0 18:49:57-18:50:17 ℹ pass 202 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 19914.143774
|
||||
pkg-cli-launcher rc=0 18:50:17-18:50:31 ℹ pass 19 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 14753.442572
|
||||
pkg-control-board rc=0 18:50:31-18:50:32 ℹ pass 124 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 601.318424
|
||||
pkg-conversation rc=0 18:50:32-18:51:20 ℹ pass 182 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 47622.749502
|
||||
pkg-discord rc=0 18:51:20-18:51:22 ℹ pass 183 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 2585.981236
|
||||
pkg-harness rc=0 18:51:22-18:51:34 ℹ pass 108 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 12062.67946
|
||||
pkg-ledger rc=0 18:51:34-18:51:57 ℹ pass 86 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 22208.339871
|
||||
pkg-mosaic rc=0 18:51:57-18:51:59 ℹ pass 69 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 2056.635811
|
||||
pkg-plugins rc=0 18:51:59-18:51:59 ℹ pass 28 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 223.296533
|
||||
pkg-project rc=0 18:51:59-18:52:00 ℹ pass 30 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 1176.427414
|
||||
pkg-runs rc=0 18:52:00-18:52:01 ℹ pass 43 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 718.469224
|
||||
pkg-seat rc=0 18:52:01-18:52:07 ℹ pass 148 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 6079.672118
|
||||
pkg-tasks rc=0 18:52:07-18:52:12 ℹ pass 97 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 5020.853991
|
||||
pkg-webui rc=0 18:52:12-18:53:07 ℹ pass 113 ℹ fail 0 ℹ skipped 0 | ℹ duration_ms 55154.695667
|
||||
script-auth rc=0 18:53:07-18:53:08 | selftest: 15 passed, 0 failed
|
||||
script-conductor rc=0 18:53:08-18:53:13 | selftest: 17 passed, 0 failed
|
||||
script-config rc=0 18:53:13-18:53:15 | selftest: 24 passed, 0 failed
|
||||
script-discord rc=0 18:53:15-18:53:22 | discord suite: 78 passed, 0 failed
|
||||
script-extension-package rc=0 18:53:22-18:53:23 | extension package selftest: 18 passed, 0 failed
|
||||
script-foundation rc=0 18:53:23-18:54:02 | selftest: 44 passed, 0 failed
|
||||
script-land-work rc=0 18:54:02-18:54:15 | land-work selftests: 84 passed, 0 failed
|
||||
script-queue rc=0 18:54:15-18:54:46 ℹ pass 156 ℹ fail 0 | queue suite: 28 passed, 0 failed
|
||||
script-release rc=0 18:54:46-18:54:57 | selftest: 14 passed, 0 failed
|
||||
script-task rc=0 18:54:57-18:55:25 | selftest: 98 passed, 0 failed
|
||||
GATE_PASSED 18:55:25
|
||||
network darkwing-r137_default removed
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/bin/bash
|
||||
set -o pipefail
|
||||
# Darkwing builder gate, row 137 (#1631), candidate in the r137 worktree on
|
||||
# base 7a2987cf5. Every package's node suite except queue's (test-queue.sh
|
||||
# runs it), then every scripts/test-*.sh, sequential, each teed to its own
|
||||
# log; stops at the first failure. cli's launcher test runs on its own under
|
||||
# the session's inherited TMPDIR (the bwrap runner fails "did not start" under
|
||||
# an override or with TMPDIR unset).
|
||||
G=$HOME/darkwing-scratch/r137/wt
|
||||
OUT=$HOME/darkwing-scratch/r137/gate${1:+-$1}
|
||||
INHERITED_TMPDIR=${TMPDIR:?the session TMPDIR}
|
||||
export TMPDIR=$HOME/darkwing-scratch/r137/tmp
|
||||
export COMPOSE_PROJECT_NAME=darkwing-r137
|
||||
dropnet() { n=${COMPOSE_PROJECT_NAME}_default
|
||||
if docker network inspect "$n" >/dev/null 2>&1; then
|
||||
c=$(docker network inspect -f '{{len .Containers}}' "$n"); [ "$c" = 0 ] && docker network rm "$n" >/dev/null && echo "network $n removed" || echo "network $n kept, $c containers"
|
||||
fi; }
|
||||
trap dropnet EXIT
|
||||
mkdir -p "$OUT" "$TMPDIR"
|
||||
cd "$G" || exit 9
|
||||
[ -e "$G/node_modules" ] || { echo "STOP no node_modules in $G"; exit 8; }
|
||||
echo "base $(git rev-parse --short HEAD) DOCKER_HOST=${DOCKER_HOST:-unset} docker=$(docker info --format '{{.ServerVersion}}' 2>/dev/null || echo none) start $(date -u +%H:%M:%S)"
|
||||
run() { local name="$1" dir="$2" cmd="$3" t0; t0=$(date -u +%H:%M:%S)
|
||||
(cd "$G/$dir" && bash -c "$cmd") 2>&1 | tee "$OUT/$name.log" > /dev/null; local rc=$?
|
||||
echo "$name rc=$rc $t0-$(date -u +%H:%M:%S) $(grep -E '^ℹ (pass|fail|skipped) [0-9]+' "$OUT/$name.log" | tr '\n' ' ') | $(tail -n1 "$OUT/$name.log")"
|
||||
[ $rc -eq 0 ] || { echo "STOP $name"; exit $rc; }; }
|
||||
for d in packages/*/; do p=$(basename "$d"); [ -d "$d/tests" ] || continue; [ "$p" = queue ] && continue
|
||||
if [ "$p" = cli ]; then
|
||||
run pkg-cli packages/cli 'node --test $(ls tests/*.test.mjs | grep -v "^tests/launcher\.test\.mjs$")'
|
||||
run pkg-cli-launcher packages/cli "TMPDIR=$INHERITED_TMPDIR node --test tests/launcher.test.mjs"
|
||||
else run "pkg-$p" "packages/$p" 'node --test tests/*.test.mjs'; fi; done
|
||||
for s in scripts/test-*.sh; do n=$(basename "$s" .sh); run "script-${n#test-}" . "bash $s"; done
|
||||
echo "GATE_PASSED $(date -u +%H:%M:%S)"
|
||||
@@ -0,0 +1,310 @@
|
||||
✔ agents: a held role with nothing on the bus is idle; a role session gets the claim rows unchanged (144.05929ms)
|
||||
✔ agents: working counts what the holder received and has not read; routed alone is not working (213.346928ms)
|
||||
✔ agents: input needed is the role's open decisions routed to the human, gated first, then oldest (345.556383ms)
|
||||
✔ agents: working wins over waiting, and Input needed still shows (179.954512ms)
|
||||
✔ agents: a new holder doesn't inherit what the last one left unread; decisions stay with the role (210.800758ms)
|
||||
✔ agents: state reads only its own business, even for a run name both use (175.100516ms)
|
||||
✔ agents: a message the holder released unread is stranded; the next holder gets nothing and cannot read it (214.74548ms)
|
||||
✔ agents: a message the holder read is not stranded; one the current holder has not read is not listed (182.239793ms)
|
||||
✔ agents: stranded is oldest first and capped at 50 for a role (885.389857ms)
|
||||
✔ agents: stranded is per role and per business (329.753864ms)
|
||||
✔ agents: a message routed to a held role and not yet received is not stranded (136.839639ms)
|
||||
✔ REQ-DEC an approval outlives its run and a broker restart; a new run of the instance consumes it once (265.502052ms)
|
||||
✔ REQ-DEC another instance of the same definition cannot consume an approval, and its refusal consumes nothing (194.901872ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread approval is consumed only by a run holding the same thread (268.53578ms)
|
||||
✔ REQ-DEC a later run of the same instance supersedes an open decision; another instance cannot (264.138006ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread decision is superseded only from the same thread (247.882667ms)
|
||||
✔ REQ-DEC REQ-THREAD-1 a thread instance decision raised before row 121 is not consumed or superseded by any thread run (352.427312ms)
|
||||
✔ launch identity is stamped, payload identity is refused and stale holder cannot send (175.464817ms)
|
||||
✔ decision classes route from policy; gated resolution is human-only, choice and target must match (269.391653ms)
|
||||
✔ claim exclusion, holder release, gated revoke and rerouting to a new holder are atomic (293.680928ms)
|
||||
✔ launch events require a human CLI capability; generic emit cannot forge authority events (191.580167ms)
|
||||
✔ within-role decisions close atomically and invalid options or blocking omissions refuse (192.187452ms)
|
||||
✔ a recommendation that is not exactly one option key refuses invalid-recommendation after the options (260.938844ms)
|
||||
✔ observer capabilities read human inbox but cannot mutate or forge launch identity (178.170841ms)
|
||||
✔ task action subjects and linked decision trail are complete and ordered (181.627308ms)
|
||||
✔ launch binding is durable and reconnecting requires the identical trusted record (110.334877ms)
|
||||
✔ business isolation includes inherited object names and cross-business message references (194.872137ms)
|
||||
✔ authority never transfers between action, target, unresolved or replaced role holder; a later run of the instance keeps it (325.151088ms)
|
||||
✔ task projection uses schema current view, skipping earlier and equal-start polls (151.025872ms)
|
||||
✔ revocation permanently bars the old run from reclaiming first, including after broker restart (225.769996ms)
|
||||
✔ empty message references refuse before storage; refusal-evidence failure stays a typed error (151.980561ms)
|
||||
✔ both arbiters require human resolution when their cross-role route is themselves (246.483924ms)
|
||||
✔ the shipped coder role raises task.reassign as gated to the human; task.scope.change stays cross-role (175.47955ms)
|
||||
✔ S1 adapter takes resolved limits and refs, rejects mismatched instance, never mutates input (2.215999ms)
|
||||
✔ REQ-COS-1, REQ-ROLE-2: the chief of staff ends a run with a reason and no decision, and the reason is logged (254.44728ms)
|
||||
✔ REQ-ROLE-2: a role without role.end still needs a resolved decision to revoke (326.383224ms)
|
||||
✔ REQ-ROLE-2: storage accepts a revoke with a reason or a decision and aborts one with neither (254.756276ms)
|
||||
✔ REQ-ROLE-2: the chief of staff may still cite a decision, and a decision alone is the old path (244.248268ms)
|
||||
✔ REQ-ROLE-2: a role without role.end still ends a run through a resolved decision, which is recorded and has no reason (255.167246ms)
|
||||
✔ REQ-ROLE-2: a reason is required, bounded, and never sent with a decision (279.645384ms)
|
||||
✔ REQ-COS-1: the chief of staff cannot end its own run or the assistant's through role.end (262.029861ms)
|
||||
✔ REQ-LIMIT-1, REQ-COS-1: organization.set from the chief of staff reaches the shared writer, named as the actor (270.183817ms)
|
||||
✔ REQ-LIMIT-1, REQ-COS-1: a refused organization.set logs action.refused and no action.allowed, like a refused limits.set (311.670727ms)
|
||||
✔ REQ-LIMIT-1: organization.set is refused for every caller whose role file lacks organization.change (305.806919ms)
|
||||
✔ REQ-LIMIT-1: the chief of staff is logged as allowed, and organization.set takes only the human's keys (385.436063ms)
|
||||
✔ REQ-ROLE-3, REQ-LIMIT-1: a chief-of-staff change is validated, written and logged like a human's; an invalid one is refused (547.299838ms)
|
||||
✔ REQ-ROLE-2, REQ-COS-1: the 3c→3d migration lets the chief of staff end a held role with a reason; neither is still refused (971.93228ms)
|
||||
✔ comment cursors isolate businesses, move only forward and remain append-only (146.56018ms)
|
||||
✔ only trusted sync writes validated cursors; events and cursor share rollback (119.600379ms)
|
||||
✔ explicit 3b copy migration preserves evidence and opens as 3f; normal startup never migrates (879.596381ms)
|
||||
✔ migration refuses active writers and drifted legacy schemas, with no partial upgrade (1516.80763ms)
|
||||
✔ named migration registry chains 3b through 3f to a fixture-only future version in order (797.021667ms)
|
||||
✔ migration refuses mismatched source metadata without changing schema or evidence (767.716303ms)
|
||||
✔ offline command migrates only the supplied fixture root and reports usage errors (1031.434504ms)
|
||||
✔ credentials gives human and reader sessions service, account, role, date and state, and nothing else (106.572352ms)
|
||||
✔ credentials refuses a role session and any argument (174.177222ms)
|
||||
✔ credentials reads the status on each request, and a broker without one lists none (222.966953ms)
|
||||
✔ the broker process answers credentials without a token, path or variable in its output, log or store (218.695392ms)
|
||||
✔ only validated broker references load; returned data and exceptions cannot expose a known token (3.93501ms)
|
||||
✔ bad file modes, symlinks, repository/data paths, malformed tokens and missing dates refuse (2.415081ms)
|
||||
✔ expiry refuses use and env references never become client data (0.653496ms)
|
||||
✔ S1 parsed service refs work, service mismatch refuses, Gitea rotation due is a warning state (1.22835ms)
|
||||
✔ opaque tokens shorter than 16 characters refuse before use (0.291602ms)
|
||||
✔ each C-suite role file carries the same two lists: human, chief-of-staff, pm, cto (2.333507ms)
|
||||
✔ chief-executive-officer: messages to and from the user, chief of staff, pm and cto pass (472.617413ms)
|
||||
✔ chief-executive-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (483.596555ms)
|
||||
✔ chief-executive-officer: another C-suite role isn't on the lists either (398.904562ms)
|
||||
✔ chief-financial-officer: messages to and from the user, chief of staff, pm and cto pass (439.372537ms)
|
||||
✔ chief-financial-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (491.050882ms)
|
||||
✔ chief-financial-officer: another C-suite role isn't on the lists either (386.048306ms)
|
||||
✔ chief-information-officer: messages to and from the user, chief of staff, pm and cto pass (472.419681ms)
|
||||
✔ chief-information-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (455.229065ms)
|
||||
✔ chief-information-officer: another C-suite role isn't on the lists either (410.738186ms)
|
||||
✔ chief-information-security-officer: messages to and from the user, chief of staff, pm and cto pass (529.453115ms)
|
||||
✔ chief-information-security-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (516.767302ms)
|
||||
✔ chief-information-security-officer: another C-suite role isn't on the lists either (387.98007ms)
|
||||
✔ chief-marketing-officer: messages to and from the user, chief of staff, pm and cto pass (437.277805ms)
|
||||
✔ chief-marketing-officer: a message to or from the coder, reviewer or assistant is refused and logged, and nothing is stored (434.285457ms)
|
||||
✔ chief-marketing-officer: another C-suite role isn't on the lists either (343.030321ms)
|
||||
✔ a human resolve sends the raising role one message from the human, and its request is the answer (227.47827ms)
|
||||
✔ a cross-role decision resolved by its arbiter comes from that role and run, with no request (241.261649ms)
|
||||
✔ a human withdraw sends one message with the note (243.397158ms)
|
||||
✔ a human seen before the close leaves the request on the close's answer, not the seen (313.858185ms)
|
||||
✔ the raising run's withdraw, a supersede, a within-role raise and seen send nothing (263.109493ms)
|
||||
✔ refused closes send nothing: invalid-choice, decision-closed, not-resolver (291.209925ms)
|
||||
✔ a raising role nobody holds at the close gets the message on the next claim (247.910634ms)
|
||||
✔ a human DECISION send keeps its own instruction as the request, not a close's answer (236.878189ms)
|
||||
✔ a cross-role raise whose arbiter the raiser does not hear from is refused and stores nothing (286.201279ms)
|
||||
✔ a gated raise by a role that does not hear from the human is refused and stores nothing (297.082822ms)
|
||||
✔ a route the raiser hears from is allowed, checked from the route to the raiser (358.292683ms)
|
||||
✔ a refused supersede withdraws nothing (295.233421ms)
|
||||
✔ the assistant's within-role and gated raises still work (300.699805ms)
|
||||
✔ roles lists open decisions routed to a role, and never the human inbox (210.465021ms)
|
||||
✔ recent lists closed decisions of every route, newest close first, with how each closed (302.276529ms)
|
||||
✔ recent gives the closing event as closed when the decision was seen first (300.372063ms)
|
||||
✔ recent stops at RECENT rows (793.217442ms)
|
||||
✔ every row is what trail already gives the same session for that id (263.144818ms)
|
||||
✔ a role session can't list decisions, so it can't read another role's open decisions (429.759421ms)
|
||||
✔ decisions is a read: one business, strict arguments, nothing written (393.163901ms)
|
||||
✔ endLaunch writes session.ended, releases the run claim and kills its capabilities (142.917216ms)
|
||||
✔ endLaunch refuses an unknown run, a second end and a rebind of the ended run (143.986521ms)
|
||||
✔ a restarted broker refuses to rebind an ended run; a refused rebind leaves the run unbound (155.472208ms)
|
||||
✔ endLaunch leaves a claim another run took alone (192.667767ms)
|
||||
✔ refuse records action.refused against the caller with the code only (134.34704ms)
|
||||
✔ launches off refuses role.launch with launch-revoked until launches on (205.787798ms)
|
||||
✔ broker process: launch ops authorize role.launch, record refusals and end runs (311.617838ms)
|
||||
✔ human proof binds CLI entry, process start and nonce; agents and incomplete ancestry refuse (2.428167ms)
|
||||
✔ process reader gets own kernel identity without exposing environment values (0.538745ms)
|
||||
✔ EACCES ancestor environments skip only markers; commands and registered launches still refuse (0.663909ms)
|
||||
✔ real pid 1 remains inspectable when its environment is protected (0.243614ms)
|
||||
✔ checkLand answers the facts and a ticket, records nothing, and recordLand spends the decision once (245.354458ms)
|
||||
✔ checkLand refuses on the decision and the review (325.023483ms)
|
||||
✔ a merge option with no first line refuses no-subject, as land-work does (252.355977ms)
|
||||
✔ checkLand refuses with land-work's codes past the authority check, and a decision raised for refactor never lands (583.610972ms)
|
||||
✔ a ticket outlives the run that asked, and recordLand checks the task again (238.540455ms)
|
||||
✔ landRefused files the code on the task, tells the role only with notify, and ends the ticket (267.964982ms)
|
||||
✔ landHeld is true only for an approved, unspent merge decision this role raised for a task in this thread (290.740704ms)
|
||||
✔ no run may write the action.allowed for git.merge.protected itself (163.341282ms)
|
||||
✔ a message to a stopped role sends launch.by one notice, and the result says so (203.923332ms)
|
||||
✔ a message to a role outside launch.instances says so in its result and in the notice (173.36188ms)
|
||||
✔ a message to a running role sends no notice and its result is unchanged (157.876236ms)
|
||||
✔ a re-route at a claim, a release and claim, and a broker restart send no second notice (255.323027ms)
|
||||
✔ a run launched but not yet claimed counts as no holder (139.757418ms)
|
||||
✔ no notice for a message to launch.by, from it, from a tester, to the human, or in a thread to a thread instance (258.179438ms)
|
||||
✔ a business with no launch block tells nobody and says there is no launcher (116.612643ms)
|
||||
✔ the notice sender stays internal: no role is named _bus and no caller can send as it or to it (332.223962ms)
|
||||
✔ limits binds actor from human proof and rejects role, reader, tester and forged actor (202.946908ms)
|
||||
✔ runtime wires verified human settings to the actual shared file writer and actor receipt (290.873044ms)
|
||||
✔ uncertain organization receipts leave bus startup and reads alone but refuse writes until reconciled (451.637256ms)
|
||||
✔ within-role sends cite an open gated launch decision without spending it or naming it in grants (208.532641ms)
|
||||
✔ missing and foreign-business citations refuse and roll back message and grant (206.947969ms)
|
||||
✔ cross-role sends still need a matching resolved decision and consume it once (271.944948ms)
|
||||
✔ messages pages all human messages newest first without writes; read state is history (2563.822625ms)
|
||||
✔ messages refuses role callers, invalid paging and cursors outside this human feed (265.300298ms)
|
||||
✔ views messages passes only its paging arguments through (0.51912ms)
|
||||
✔ messages isolates businesses even with a valid foreign cursor (171.903575ms)
|
||||
✔ the assistant sends to the user and to the chief of staff only (306.537956ms)
|
||||
✔ an assistant send to any other role, or to the tester, is refused and logged (331.658653ms)
|
||||
✔ only the user and the chief of staff may send to the assistant; the tester is refused by default (339.31255ms)
|
||||
✔ REQ-ASSIST-2 REQ-THREAD-1 thread.send to an instance that does not hear from the user is refused and stores nothing (337.231323ms)
|
||||
✔ a sender-side list alone refuses a send to a role that has no list (320.785661ms)
|
||||
✔ a target-side list alone refuses a send from a role that has no list (336.350706ms)
|
||||
✔ the sender list is checked before the target list (293.643159ms)
|
||||
✔ roles without the field behave exactly as before (427.337522ms)
|
||||
✔ a business with no role definitions at all is unlimited (344.528011ms)
|
||||
✔ a malformed messaging field refuses at boot (123.355385ms)
|
||||
✔ the assistant's review.request to a reviewer is refused and logged, even with an approved decision (384.105943ms)
|
||||
✔ a review.verdict to the assistant from a role outside its receiveFrom is refused and logged (449.896392ms)
|
||||
✔ review requests and verdicts between roles without the field are unchanged (314.692601ms)
|
||||
✔ plugins and plugins.set refuse every non-human session and a forged actor, and pass only the patch with the verified actor (189.424426ms)
|
||||
✔ runtime: the switch changes the organization file, the receipt carries the actor, and a bad shape, an unknown module and a stale revision are refused with nothing written (474.947934ms)
|
||||
✔ vikunja:19/309 through the broker, a patch switches the kinds it names and keeps the rest; null removes one kind and is trailed (441.022854ms)
|
||||
✔ broker process binds trusted launches, offers reader capabilities, refuses human mutation, closes cleanly (214.082489ms)
|
||||
✔ startup token refusal returns safe code without value or partial listening broker (67.208041ms)
|
||||
✔ loaded fixture token is absent from socket replies and SQLite, including refusal evidence (200.354192ms)
|
||||
✔ killed broker leaves an explicit stale lock; another process cannot silently reclaim it (226.239933ms)
|
||||
✔ trusted host registers later launches; socket clients never have a registration verb (229.84155ms)
|
||||
✔ runtime excludes declared project roots even when host supplies no repoRoots (64.094057ms)
|
||||
✔ a refused launch binding leaves the broker and existing capabilities alive; bad protocol stops it (210.437994ms)
|
||||
✔ D1: committed write with a failed receipt refuses outcome-unknown without action.allowed (150.599482ms)
|
||||
✔ D2: spec.read refuses without content if its role is released during the read (151.653041ms)
|
||||
✔ D3: spec.read secret check refuses flagged content without content (141.445631ms)
|
||||
✔ D3: spec.read secret check refuses flagged subject without content (184.04861ms)
|
||||
✔ Broker keeps the existing sandbox client import closure: no new imports or lazy project import (1.372603ms)
|
||||
✔ without a trusted project adapter all three async paths refuse project-not-configured (202.918249ms)
|
||||
✔ real startBroker injects the project adapter for socket reads and bound-author record writes (213.18783ms)
|
||||
✔ a reply is listed for human and reader sessions, and its delivery rows are unchanged (219.245447ms)
|
||||
✔ the reply still reaches the human message.receive (mosaic talk) after the Console showed it (228.472489ms)
|
||||
✔ a message with no reply gives an empty list (156.927627ms)
|
||||
✔ replies come oldest first and stop at REPLIES (741.089021ms)
|
||||
✔ an id that names no message in the business refuses message-not-found, and the refusal is recorded (292.641353ms)
|
||||
✔ strict arguments; a role session gets human-required (371.177219ms)
|
||||
✔ views passes replies through as one call with the id (0.238469ms)
|
||||
✔ requirements returns the committed list to a holding role session, and no one else (215.226683ms)
|
||||
✔ the PM's prd.approve with no task, when no id fits, reaches the human's Inbox (159.499926ms)
|
||||
✔ the PM's non-blocking role.revoke with no task reaches the human's Inbox (167.25647ms)
|
||||
✔ a push is recorded as the action.allowed for git.push.working on the task, and only the host records one (246.528365ms)
|
||||
✔ review.request names the latest pushed commit and sends the reviewer a REVIEW-REQUEST (241.635802ms)
|
||||
✔ review.request says which run holds the reviewer role, or null, and a null request waits for a claim (291.751571ms)
|
||||
✔ review.request refuses a commit that isn't the latest push, a non-reviewer and a role without the action (360.022747ms)
|
||||
✔ reviewFetch answers only the addressed reviewer, for the request it cites (235.238553ms)
|
||||
✔ review.verdict answers one request once, to the role that asked (312.244488ms)
|
||||
✔ task.close on a pushed task needs an approve verdict for the latest push (404.675532ms)
|
||||
✔ a refusal the host decided is filed on the task it names, and only a task ref counts (295.287783ms)
|
||||
✔ v3b prototype refusals, views and append-only mutations (1443.370064ms)
|
||||
✔ gated approval authorizes once, survives store reopen, and fresh approval works (248.27825ms)
|
||||
✔ another run of the same instance consumes an approval once; a failed check leaves it usable (207.879642ms)
|
||||
✔ two scheduled callers have exactly one grant and one consumed refusal (156.645944ms)
|
||||
✔ failed commit rolls consumption back; cross-role consumes and within-role stays reusable (319.755398ms)
|
||||
✔ class drift gated to cross-role refuses before consumption (217.404565ms)
|
||||
✔ class drift cross-role to gated refuses before consumption (256.569884ms)
|
||||
✔ class drift gated to within-role refuses before consumption (225.502317ms)
|
||||
✔ class drift cross-role to within-role refuses before consumption (282.531965ms)
|
||||
✔ class drift within-role to gated refuses before consumption (246.975882ms)
|
||||
✔ class drift within-role to cross-role refuses before consumption (226.516789ms)
|
||||
✔ message.send consumes approval and prevents a later send or authorize (293.698376ms)
|
||||
✔ role.revoke consumes approval and prevents a later revoke or authorize (258.574863ms)
|
||||
✔ 3e copy migrates to 3f preserving every old column/row and adding null spec citations (1339.585071ms)
|
||||
✔ real socket awaits spec reads, record writes and cited raises; other requests still return normally (252.134135ms)
|
||||
✔ real socket preserves asynchronous refusal codes and disconnects its transient proof (189.047194ms)
|
||||
✔ two real socket writes to one repository yield one commit and one project-busy refusal (209.570865ms)
|
||||
✔ client disconnect during await tolerates late reply (170.261308ms)
|
||||
✔ client disconnect during await tolerates late refusal (187.686062ms)
|
||||
✔ N-a: slow admitted record.write returns its committed result after the idle deadline (362.119637ms)
|
||||
✔ current citation is recorded; docs commits do not stale it and a new spec never reopens settlement (295.80187ms)
|
||||
✔ stale, unconfirmed, missing and partial spec citations refuse without inserting a decision (312.815983ms)
|
||||
✔ uncited raises retain their synchronous path and spec read is available to any held role in its business (227.988018ms)
|
||||
✔ record writes bind the session author, require authority and refuse spec and impersonation paths (262.196464ms)
|
||||
✔ REQ-COS-1: the pm asks the chief of staff for roles and counts; the chief receives a STAFF-REQUEST and answers it (227.301945ms)
|
||||
✔ REQ-COS-1: only the pm can send a staff request; every other session is refused and the chief of staff hears nothing (314.739815ms)
|
||||
✔ REQ-COS-1: a pm without message.send is refused like any other gated action (149.711731ms)
|
||||
✔ REQ-COS-1: the request goes to the business launcher, and only when that is a chief of staff (425.596753ms)
|
||||
✔ REQ-COS-1: the sender is judged by definition: an instance `lead` of the pm definition can ask, an instance `pm` of the coder definition can't (455.988926ms)
|
||||
✔ REQ-COS-1: the launcher is judged by definition: an instance `boss` of the chief-of-staff definition receives, a `chief` of the coder definition gives no-chief-of-staff (407.786491ms)
|
||||
✔ REQ-COS-1: a refused staff request leaves no staff.request action.allowed event (290.270226ms)
|
||||
✔ REQ-ASSIST-2: the role definitions' messaging lists hold for a staff request, sender and recipient (588.532539ms)
|
||||
✔ a staff request names a task, 1 to 10 distinct roles and counts of 1 to 20; nothing else is accepted (432.620333ms)
|
||||
✔ REQ-COS-1: a staff request grants nothing: the pm still can't launch and the chief of staff launches as before (227.947296ms)
|
||||
✔ a business that never switched launches reads allowed with no time and no event (131.231526ms)
|
||||
✔ launches revoked and then restored read allowed, with the restore time and event id (156.726798ms)
|
||||
✔ a task closed on the tracker leaves the open list, and total counts the open ones (137.986053ms)
|
||||
✔ a tombstone is not open (144.321565ms)
|
||||
✔ the open list stops at the cap and says so; total still counts every open task (144.096806ms)
|
||||
✔ a role and a reader session read state; arguments, and an unbound cap, refuse (139.384511ms)
|
||||
✔ a human session reads the same state, with the same cap (165.792148ms)
|
||||
✔ reading state writes nothing: every table keeps its row count (168.096666ms)
|
||||
✔ creates private WAL store and excludes a second writer until explicit close (125.795527ms)
|
||||
✔ rollback is atomic and schema metadata is checked against trusted DDL, not just itself (177.078756ms)
|
||||
✔ existing empty database and symlink runtime directory refuse, never initialize over damage (184.619521ms)
|
||||
✔ crash during a transaction recovers no partial event after explicit fixture-only lock removal (198.388518ms)
|
||||
✔ writer refuses mixed at/read_at forms atomically, even through trusted SQL helpers (113.13483ms)
|
||||
✔ async transactions refuse before invoking their function (107.323659ms)
|
||||
✔ the session default fits under the reply cap and pages to the end with next (313.561137ms)
|
||||
✔ the short form: no description, assignees by role, every listed key (277.454348ms)
|
||||
✔ each filter, alone and together, and total counts every match (343.794468ms)
|
||||
✔ task_ref reads one task in full, as the whole board has it (377.385568ms)
|
||||
✔ no arguments is the read the Console and mosaic make, unchanged (249.971048ms)
|
||||
✔ an unknown argument or a bad value refuses invalid-request (909.062664ms)
|
||||
✔ tasks rows carry priority and requirement for every session that reads tasks (334.485901ms)
|
||||
✔ the read model rebuilds from the ledger: a reopened bus and each trail give the same values (371.119884ms)
|
||||
✔ an empty business and one with snapshots but no task.created read cleanly (114.388617ms)
|
||||
✔ recordTask keeps sync reads and a role write apart (203.854399ms)
|
||||
✔ read_at must be one canonical UTC format, so the projection compares strings safely (115.386305ms)
|
||||
✔ a bad entry refuses the whole record (135.404217ms)
|
||||
✔ taskView reads the projection for one business (145.342065ms)
|
||||
✔ requestTask hands only a holder and a task verb to the handler, and records refusals (279.3021ms)
|
||||
✔ the server sends task verbs to the adapter with its own timeout; other verbs stay synchronous (495.938555ms)
|
||||
✔ without an adapter the server refuses every task verb (212.882634ms)
|
||||
✔ the runtime refuses an invalid adapter and closes a valid one (199.108836ms)
|
||||
✔ the process loads the S3 adapter from plain-data trackers (324.23708ms)
|
||||
✔ the tester binds only when the business sets bus.tester to exactly true (879.263527ms)
|
||||
✔ a business may not name a role tester, so the tester address is never a role (300.496414ms)
|
||||
✔ every verb outside the tester list refuses tester-refused and is recorded against the tester (541.744279ms)
|
||||
✔ a tester message is from tester, starts [mos test], and writes no human.input or authority (225.91737ms)
|
||||
✔ a role answers a tester only in reply to a tester message, and the answer never reaches the human (252.162895ms)
|
||||
✔ the tester reads the human views a reader reads (168.249503ms)
|
||||
✔ tester proof binds its own CLI, start time and nonce, refuses a managed run and allows an agent (1.080436ms)
|
||||
✔ neither CLI's nonce proves the other: each proof is bound to its own CLI and nonce variable (0.318087ms)
|
||||
✔ testerNonce reads only the tester's variable and gives null on any read error (0.208512ms)
|
||||
✔ an envelope carries exactly one of cap, human and tester; no tester authenticator refuses (109.507557ms)
|
||||
✔ tester-cli.mjs binds through the runtime when the switch is on, and refuses off or under a run marker (880.628091ms)
|
||||
✔ REQ-THREAD-1 REQ-ORG-2: the 3d→3e migration adds the thread tables and leaves messages from before threads as written (1144.651491ms)
|
||||
✔ REQ-THREAD-1: a 3d bus with a changed schema is refused and keeps its version and tables (789.919403ms)
|
||||
✔ REQ-THREAD-1: the offline command prints the kept-message counts before the ready line (801.50748ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: one holder per thread, through the broker and the trigger (366.655408ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: the 3e triggers refuse writes that skip the broker (1204.453558ms)
|
||||
✔ REQ-MSG-1: a message to or from the assistant names its thread, or is refused (322.820901ms)
|
||||
✔ REQ-MSG-1: the chief of staff's reply comes back to the thread that sent the work (3551.967817ms)
|
||||
✔ REQ-MSG-1: a reply can't carry one thread instance's thread to another thread instance (144.409622ms)
|
||||
✔ REQ-THREAD-1 REQ-USER-2: one thread's messages never reach another thread's holder (157.570831ms)
|
||||
✔ REQ-LAUNCH-1: a message to a thread with no holder waits, and the next holder gets it (273.600268ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1: threadIdle releases only a thread with nothing waiting, and only for its holder (233.703195ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1: a message delivered to a run that ended unread doesn't hold up the next holder (188.016116ms)
|
||||
✔ REQ-ROLE-2 REQ-THREAD-1: an approved role.revoke never reaches a thread run, and the thread stays held (136.142461ms)
|
||||
✔ REQ-USER-2: the human verbs refuse another owner's thread (184.452407ms)
|
||||
✔ REQ-THREAD-1: thread.create refuses when the business has no thread instance or more than one (124.182281ms)
|
||||
✔ REQ-ORG-2: projects and threads are named once, and the repo names a business project (151.70596ms)
|
||||
✔ REQ-THREAD-2: thread.messages returns the thread's history in pages and writes nothing (490.86068ms)
|
||||
✔ socket capability stamps launch identity; shared views use wire, no SQL client (160.442983ms)
|
||||
✔ two wire claims serialize; a lost reply never automatically retries (180.376464ms)
|
||||
✔ malformed, oversized and identity-forging envelopes refuse without echoing input (117.750631ms)
|
||||
✔ client preserves UTF-8 when a response divides a multibyte character (11.585371ms)
|
||||
✔ committed mutation followed by dropped reply reports unknown and is never retried (183.173211ms)
|
||||
✔ web.search: a granted role gets labelled results, and the call is trailed with role, run, verb and query (167.981984ms)
|
||||
✔ web.fetch: a granted role gets the page as labelled text, and the call is trailed with the url (169.817193ms)
|
||||
✔ a role without the grant is refused, the refusal is logged with the verb, and nothing is fetched (258.876929ms)
|
||||
✔ a broker with no web service refuses a granted role (145.330454ms)
|
||||
✔ bad requests are refused: unknown verb, extra or missing argument, not a string, a human or reader session (201.981838ms)
|
||||
✔ a session that is not the role holder is refused (132.040888ms)
|
||||
✔ web.mjs's fences hold on the broker side: refusals are normal results with the fixed reason (373.993538ms)
|
||||
✔ web.search with no search source configured is a refused result, not an error (144.461978ms)
|
||||
✔ a search source that fails with its own refusal, or that throws, is handled (180.174112ms)
|
||||
✔ a slow search source ends in a refusal at the deadline (186.269174ms)
|
||||
✔ a secret in the arguments is refused before anything is trailed or fetched (132.148515ms)
|
||||
✔ over the socket: the server routes web verbs to the service; other roles are refused; no service is web-not-configured (215.793213ms)
|
||||
✔ busBusiness: the web grant comes from "web" in the resolved tool limit (0.241426ms)
|
||||
✔ webServices: the business's search-source plug-in and web.searxng var make web.search work; without either it is refused as not configured (189.721166ms)
|
||||
✔ an ungranted call is refused at once: no admission, no wait, nothing touched (176.24401ms)
|
||||
✔ over the socket an ungranted caller is dropped by the server timeout and a granted one gets the longer wait (439.994006ms)
|
||||
✔ a search that never answers is aborted at the deadline, the module sees the signal, and the call is trailed as refused (timeout) (195.29039ms)
|
||||
✔ a fetch that stalls is cut off at the deadline: the request is destroyed, not left running (189.385971ms)
|
||||
✔ one query limit: over SEARCH_MAX_QUERY_CHARS or empty is refused with the same reason before any backend, and the tool schema carries the same number (159.218931ms)
|
||||
ℹ tests 302
|
||||
ℹ suites 0
|
||||
ℹ pass 302
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 11643.870722
|
||||
@@ -0,0 +1,117 @@
|
||||
✔ the role file loads and resolves through loadBusiness (7.295639ms)
|
||||
✔ the shipped file is exactly the approved list (1.015557ms)
|
||||
✔ the assistant's authority is message.send and record.write within role (2.744656ms)
|
||||
✔ the assistant talks to the user and the chief of staff only, and no other shipped role is limited (0.741397ms)
|
||||
✔ a business grant through limits does not widen the role (1.860594ms)
|
||||
✔ a launch block whose by is the assistant is refused (3.582574ms)
|
||||
✔ the instance takes no credential references and no tracker (5.816844ms)
|
||||
✔ an arbiter whose role definition declares messaging lists is refused, for each kind (7.824869ms)
|
||||
✔ an arbiter without messaging lists is accepted beside the limited assistant (4.580557ms)
|
||||
✔ the contract passes work to the chief of staff and directs no one (0.847222ms)
|
||||
✔ REQ-HARN-2: the assistant holds the web grant, and no other role file does (1.541725ms)
|
||||
✔ config directory and file path follow MOSAIC_CONFIG (2.010692ms)
|
||||
✔ the fixture business validates and comes back frozen (5.766025ms)
|
||||
✔ two instances may share a definition (1.983435ms)
|
||||
✔ top-level refusals (5.955983ms)
|
||||
✔ arbiters and projects (9.224749ms)
|
||||
✔ role instances (5.611284ms)
|
||||
✔ Vikunja bots (7.694304ms)
|
||||
✔ a role without Vikunja takes no tracker block (2.643587ms)
|
||||
✔ credential references match the definition's services (2.664123ms)
|
||||
✔ launch (8.140884ms)
|
||||
✔ REQ-THREAD-2 REQ-LAUNCH-1 launch.threadIdleSeconds: absent is the default, a positive integer is used, anything else refuses (3.791929ms)
|
||||
✔ loadBusiness: file checks (1.67058ms)
|
||||
✔ loadBusiness: not a regular file (35.492597ms)
|
||||
✔ loading writes nothing (1.025281ms)
|
||||
✔ names that are Object.prototype properties don't count as declared (2.629262ms)
|
||||
✔ the shipped example refuses as written and validates once filled in (0.757987ms)
|
||||
✔ the role file loads and resolves through loadBusiness (8.939764ms)
|
||||
✔ the shipped file is exactly the approved list (0.306155ms)
|
||||
✔ the resolved record matches the approved list, so a widened file fails (2.433298ms)
|
||||
✔ the chief of staff holds role.launch, message.send, role.end, organization.change and record.write; every other action is gated (2.09852ms)
|
||||
✔ the pm does not hold role.launch (2.194301ms)
|
||||
✔ a business grant of a gated action through limits does not widen the role (2.968052ms)
|
||||
✔ a limit that drops role.launch leaves the chief of staff with no launch block (3.635672ms)
|
||||
✔ a launch block whose by is the pm instance is refused (2.172558ms)
|
||||
✔ the contract names no duty to talk to the human and the pm contract no launch (0.545488ms)
|
||||
✔ the instance takes no credential references and no tracker (2.980725ms)
|
||||
✔ usage errors exit 4 (287.877184ms)
|
||||
✔ validate: a good business exits 0 and prints instance digests (64.932397ms)
|
||||
✔ validate: project files (309.581292ms)
|
||||
✔ validate: missing files and a broken system config (231.238899ms)
|
||||
✔ validate: credential reference problems exit 2 and name each one (64.023052ms)
|
||||
✔ validate: a token file inside the repository is refused (57.378655ms)
|
||||
✔ validate: role definitions come from MOSAIC_ROLES_DIR (181.025248ms)
|
||||
✔ resolve: prints one instance's record (251.819527ms)
|
||||
✔ resolve: refusals (378.96756ms)
|
||||
✔ parse: exactly one of file or env, plus the service's date (3.306724ms)
|
||||
✔ check: a good file has no problems (1.067342ms)
|
||||
✔ check never opens the file: a write-only token passes (0.475452ms)
|
||||
✔ check: file problems (1.215801ms)
|
||||
✔ check: token files can't live in the repository or dataRoot, even through a linked directory (1.16964ms)
|
||||
✔ check: dates and environment references (0.532944ms)
|
||||
✔ each definition loads, with a contract file, and is exactly the approved list (4.343331ms)
|
||||
✔ an organization file that declares them passes, and each resolves to least privilege (7.165442ms)
|
||||
✔ the chief of staff launches each one; no other role does (4.710977ms)
|
||||
✔ a C-suite role can't be made the launcher: launch.by must hold role.launch (2.924979ms)
|
||||
✔ limits can narrow a C-suite role but never widen it (2.405157ms)
|
||||
✔ any unknown key, tool, action or version in a role file is refused (1.417506ms)
|
||||
✔ REQ-LIMIT-1 schema: every scope unset or zero, adjustable above four, bad values and unknown models refuse (19.878316ms)
|
||||
✔ REQ-LIMIT-1 counts each exact scope at/over limit, unlimited and old tuple after model reassignment (1.115318ms)
|
||||
✔ REQ-ROLE-3 writer: atomic validated revision, immutable previous bytes and authenticated actor/old/new receipt (211.921651ms)
|
||||
✔ REQ-ROLE-3 writer: pre-rename fault leaves old file, post-rename recovery records commit, conflicting recovery refuses (234.929059ms)
|
||||
✔ REQ-LIMIT-1 / decision145 migration prints only, preserves values, rejects ambiguity, and is idempotent (2.991907ms)
|
||||
✔ REQ-LIMIT-1 shared settings validates the complete proposed selection and logs exact actor (196.269825ms)
|
||||
✔ REQ-LIMIT-1 provider is table data: another provider routes separately and aliases share exact counts (1.858399ms)
|
||||
✔ REQ-ROLE-3 refuses live writer locks, symlink targets and uncertain recovery without changing bytes (117.367157ms)
|
||||
✔ REQ-PLUG-1 schema: plugins is optional, names known kinds and checked module names (15.053581ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the setter writes plugins through the organization writer and logs old and new names (249.570124ms)
|
||||
✔ vikunja:19/309 a patch changes only the kinds it names; null removes one kind, explicitly and in the trail (344.954801ms)
|
||||
✔ vikunja:19/309 an unknown kind (set or removed), a bad module, an empty patch and null on the wrong shape are refused, nothing written (1.466084ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 the writer checks the bytes it writes: a Date in plugins is refused there too (45.193425ms)
|
||||
✔ REQ-PLUG-1 REQ-ROLE-3 a refused setter write throws a code, changes nothing and logs nothing (1.350106ms)
|
||||
✔ vikunja:19/305 with an exists check, the setter refuses a module no tree file answers to, before anything is written (96.044149ms)
|
||||
✔ optional project repo is preserved and must be a normalized absolute path (13.21796ms)
|
||||
✔ loaded business project repo cannot be nested in any declared code checkout (3.973366ms)
|
||||
✔ path and load (3.009119ms)
|
||||
✔ refusals (1.646795ms)
|
||||
✔ record.write is within-role for the eleven approved v2 agents, never gated-only (4.410754ms)
|
||||
✔ systemVars flattens the validated config (2.79505ms)
|
||||
✔ precedence: system, business, project, project role, agent (8.008792ms)
|
||||
✔ limits narrow the definition and never widen it (4.634502ms)
|
||||
✔ role.launch stays within-role only for the instance the launch block names (6.674282ms)
|
||||
✔ limits.authority without role.launch leaves the launcher with no launch block (2.383492ms)
|
||||
✔ limits.authority narrows cross-role actions too (1.417899ms)
|
||||
✔ classify (1.21735ms)
|
||||
✔ the record carries what the broker and launcher need (0.844633ms)
|
||||
✔ digest: key order doesn't matter, any value change does (7.963973ms)
|
||||
✔ refusals (1.877433ms)
|
||||
✔ the four shipped version 2 roles load (4.380209ms)
|
||||
✔ shipped role scopes match addendum B section 2 and the SR runbook (1.748847ms)
|
||||
✔ shipped authority follows the note's table (1.010085ms)
|
||||
✔ every role file in roles/ loads through the validator, and a v2 contract exists (1.104631ms)
|
||||
✔ version 1 files keep loading with no authority (1.583923ms)
|
||||
✔ the conductor policy isn't a role (0.26823ms)
|
||||
✔ a missing role file is exit 4, a symbolic link too (0.543889ms)
|
||||
✔ version 2 refusals (1.907805ms)
|
||||
✔ authority: closed vocabulary, no gated-only action, no overlap (3.612598ms)
|
||||
✔ messaging: optional, role definitions and human, never the tester (2.392288ms)
|
||||
✔ credentials: Gitea scopes (1.113399ms)
|
||||
✔ credentials: Vikunja scopes are a group-to-verbs map from the grantable list (1.007523ms)
|
||||
✔ credentials: services (0.431382ms)
|
||||
✔ contract: a non-empty regular Markdown file beside the role file (0.731417ms)
|
||||
✔ every key names known layers and a merge rule (1.053692ms)
|
||||
✔ unknown keys and wrong layers refuse (0.659538ms)
|
||||
✔ types (2.289186ms)
|
||||
✔ merge: defaults, then the most specific layer wins (0.252787ms)
|
||||
✔ merge: limits only narrow, and provenance lists each source (0.366087ms)
|
||||
✔ merge doesn't change its inputs (0.138391ms)
|
||||
✔ web.searxng takes https anywhere and http on loopback, so Jason's 127.0.0.1:8888 passes (0.24056ms)
|
||||
ℹ tests 109
|
||||
ℹ suites 0
|
||||
ℹ pass 109
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 1902.454793
|
||||
@@ -0,0 +1,27 @@
|
||||
✔ bus start --pm: the launcher instance (the chief of staff) runs under its own PID namespace, registered, with a manifest (1199.665821ms)
|
||||
✔ the chief of staff launches a coder through its launch tool; the coder answers; refusals name their code (435.850497ms)
|
||||
✔ a launched pm's request_staff reaches the chief of staff; no other session has the tool and the launch limits still hold (877.080276ms)
|
||||
✔ each launch makes sure the workspace has a clone of the project: cloned, fast-forwarded, or fetched and logged (3594.111026ms)
|
||||
✔ a role the broker says holds a merge decision gets land_work, its prompt line and the git socket; without it, none (416.61912ms)
|
||||
✔ a project clone that can't be made refuses checkout-failed, from --chief and from a session, with no run and no clone left (208.996173ms)
|
||||
✔ a runner that stops at once ends its launch with the runner's reason (221.990934ms)
|
||||
✔ a Claude Code launch with no session credential refuses before it starts (114.83846ms)
|
||||
✔ a pi launch needs no session credential: pi logs in through its own ENV_ALLOW variables (200.914036ms)
|
||||
✔ a runner killed from the host ends its launch as killed, not failed (256.566631ms)
|
||||
✔ a missing or failing bwrap refuses sandbox-unavailable before anything starts; there is no unconfined fallback (115.969336ms)
|
||||
✔ a real Claude Code coder's shell can't read a stand-in secret or anything else its sandbox doesn't hold (1173.546373ms)
|
||||
✔ a host that died hard leaves its sessions to the next host, which kills them and ends their runs so the role can be launched again (673.294266ms)
|
||||
✔ a host that died hard leaves its sessions to the next host, which finds one already exited (23) and ends their runs so the role can be launched again (3611.82562ms)
|
||||
✔ a malformed sessions.json refuses the host start with exit 3 and stays as it was (103.196827ms)
|
||||
✔ an over-long launch request is refused at once, not at the 10 s idle timeout (110.866327ms)
|
||||
✔ a launch client that never closes its side doesn't hold the host's close (114.035064ms)
|
||||
✔ a runner that ignores SIGTERM is killed when the host closes (1231.20764ms)
|
||||
✔ claudeVersion asks MOSAIC_CLAUDE_BIN when set, else claude on PATH (4.665307ms)
|
||||
ℹ tests 19
|
||||
ℹ suites 0
|
||||
ℹ pass 19
|
||||
ℹ fail 0
|
||||
ℹ cancelled 0
|
||||
ℹ skipped 0
|
||||
ℹ todo 0
|
||||
ℹ duration_ms 14753.442572
|
||||
Loaded 100 of 7946 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user