Ruling 1: model records keep a bounded previous list (64 ids, oldest dropped)
of ids that left by rotation, grace expiry or re-issue; a fire removes the
record. A tokens.keys leaf matches and counts every id in the lineage that
holds it. Lineage ids are unique host-wide. An orphaned leaf limits nothing,
logs one value-free line when it becomes orphaned, and the Console usage
view lists it.
Ruling 2: an agent with no model key under a key quota refuses
key-quota-no-model-key, passed through the broker, launcher and stop reason.
Ruling 3: covered by the lineage; no mayLaunch change.
Ruling 4: the usage module receives a frozen { readUsageQueue } only.
Ruling 5: every telemetry fixture wait races a 5 s real-timer deadline.
Optional CLIProxyAPI queue telemetry (P5)
Enable through the human plugins.set transport with plugins.usage set to
"cliproxy-queue". Omission is off. The same patch may set
usage.cliproxyQueue.pollSeconds (integer 1 through 59, default 15); usage: null
removes this setting. Both switches and polling changes are human-only, including
on the tester path. The existing instance configuration and proxy key paths do
not change.
Interface 1 exports read({ readUsageQueue }). The bus hands the module one
frozen object holding one function, its management client's queue read, and
nothing else (row 333 R3), so no key write, credential call or OAuth call is
reachable from it. The module never reads credentials, configuration paths or
the environment. Each read performs exactly one bounded GET of
/v8/management/observability/usage/queue?count=100 per poll. Existing fixed
loopback, timeout, response byte cap and no-redirect/no-retry controls apply.
The proxy's array response is validated completely and mapped immediately:
api_key and source become their first 12 hexadecimal SHA-256 characters.
Only whitelisted token counts, a failure flag/status, and IDs leave the client.
No request IDs, failure bodies, client values or upstream values are retained.
Malformed batches fail atomically and yield a fixed, value-free failure code.
One bus/store writer owns the reader for its instance. It serializes polls,
drains the shared queue once, and assigns IDs to current and retiring model-key
metadata owners. Unknown msk- IDs go to the reconcile receipt. Foreign keys
without that prefix are ignored. Disabled businesses receive no telemetry.
Telemetry uses the existing append-only usage table with source
@proxy/cliproxy-queue, separate from native session source records. turnRecords
excludes it before every limit check and native usage total. Proxy totals may be
incomplete (60-second upstream retention and a 100-event drain); the Console
labels them proxy-reported and reports the reader's availability. They never
independently enforce quotas.
Native transcript counts carry the immutable run's safe modelKeyId in the
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. 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 run bound to a
retiring key keeps that key id in its usage records.
A key quota follows the agent its key id belongs to, across rotations and
re-issues, for as long as the agent stays hired: it applies to any key in that
agent's lineage (current, retiring and up to 64 earlier ids) and counts the
whole lineage, while usage records and the Console's per-key counts stay per key
id. A fire removes the agent's model record, so a re-hired agent starts a new
lineage and a quota named by an old id matches no agent: it limits nothing, the
Console usage view lists it, and the bus logs one value-free
limit-key-orphaned line when it becomes orphaned. An agent with no model key
under a key quota refuses key-quota-no-model-key; an id in two agents'
lineages, or a run bound to an id the agent no longer holds, refuses
proxy-key-refused. The human writer stamps a new since on a renamed leaf, so
moving a quota to a new key id restarts its count; after a rotation no move is
needed.