docs(row333): R1 repair packet, receipts and author log appends (#1831)

Commits agents/codex/work/queue-333/r1-repair/ (packet, receipts, review and author files) and the append-only BUILD-LOG.md and docs/SESSIONS.md entries. The packet INDEX.json sha256 is 3eb9b8d10445aa328be3b854385e4792dda2c5712b19d443d485d1b00a18d0f8 and source-tests.patch is a78bc385801b64be270fb9d6e84672c443738a5fce8eb68f7d2a01359a57a770; the product commit for these bytes is 2627321f. Two packet tarballs are deliberately not committed: packet/baseline-input-bytes.tar.gz and packet/fixed-input-bytes.tar.gz. The secret check reported a -----BEGIN marker in each (members packages/bus/src/credentials.mjs and packages/discord/src/tools.mjs, byte-identical to 503b91e56 and with no PEM body). They stay untracked until the lead rules on them.
This commit is contained in:
jason.woltje committed 2026-11-02 13:37:52 -06:00
1 parent 2627321f64
commit c012b2e0a3
37 files changed
+14410

No files matched your search

+14
View File
@@ -5826,3 +5826,17 @@ Base 09a847eda on isolated t3/model-proxy-p5-quota-usage includes landed 362893d
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.
@@ -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);},
+ };
+}
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"
}
]
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"
]
@@ -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
+4
View File
@@ -1883,3 +1883,7 @@ are never rewritten or removed; corrections are new entries.
2026-10-26 | Codex P5 builder | row333/Mos1961 isolated t3/model-proxy-p5-quota-usage at 09a847eda; clean base verified, queue next refused linked worktree (no canonical mutation) | implementation started; local fake-only serial nice19 verification; parent owns review/full gates/landing.
2026-10-26 | Codex P5 builder | row333/Mos1961 implementation candidate on isolated base09a847eda | 174/174 scoped whole-file GREEN; upstream-value mutant killed/restored+positive; native current/retiring key ownership fail-closed and telemetry isolated; 202 consumed inputs frozen in agents/codex/work/queue-333; own scratch cleaned; parent fresh review/full/browser gate pending1014.Q264; no queue/remote/push/landing.
2026-10-26 | Codex P5 builder | row333 R1 CHANGES response on same isolated503b91e | full real review hash7c95672a30c0d5c39189c7c7d610ada89cd539dcb9413617071fbb81200fd008 verified; all three findings source-confirmed; RED-first repairs authorized; original candidate/raw history preserved; no heavy/full/browser/remote/landing.
2026-10-26 | Codex P5 builder | row333 independentR1 repair source/static packet | all3 source fixes + regression controls authored, UNCOMMITTED on503b91e; nativepriority07 drift19→16 yielded78UNVERIFIED/STOP and no local retry;01–06 priorityUNVERIFIED; held-response controls unexecuted; admittedrunner baselineRED/fixedGREEN/nativeprovenance + newR2 pending; original503/R1/raws preserved; no productcommit/heavy/full/browser/queue/push/landing.