> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tuturuuu.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent quota routing

> Inspect local agent quota signals and spread delegated work across accounts.

`packages/agent-quota` is a read-only local CLI and routing library for Codex,
Claude Code, and Antigravity provider instances available to T3 Code. It
recommends where to send delegated tasks using provider headroom when available,
active assignments, data freshness, reset time, and account reserves.

## Data sources and authority

| Source | Signals | Authority and freshness |
| - | - | - |
| T3 Code `~/.t3/userdata/statev2.sqlite` | Provider instance IDs, latest session timestamps, active subagent counts | Authoritative for T3's locally persisted orchestration metadata. It does not contain provider quota snapshots. Read through a read-only SQLite connection and only query non-content columns. |
| T3 provider status cache `~/.t3/caches/<providerInstanceId>.json` | `usageLimits` windows with provider-reported utilization and resets | Authoritative only for each reported window and its model scope at `checkedAt`. A model with no covering window is UNKNOWN; no percentage is inferred. |
| Antigravity live catalog | Provider instance ID, supported models and delegation availability | Identifies routable models, not quota. Gemini models without a covering provider-reported usage/reset window remain UNKNOWN. |
| Codex local `codex app-server` snapshot (primary), with `~/.codex/sessions` and `~/.codex-t3/sessions` JSONL fallback | Local JSON-RPC `account/rateLimits/read` primary/secondary `usedPercent`, window length and reset time; JSONL token increments | Codex owns authentication and provider communication. The app-server snapshot and provider-reported windows are authoritative at their observation timestamp. Token totals are estimates, limited to recent local rollouts. |
| Claude `~/.claude-t3/<instance>/projects` JSONL | Recent input/output token usage; structured `rate_limit_event` utilization and numeric `resetsAt` values | Token sums are estimates and are not converted into quota percentages. Structured provider limit events are authoritative; numeric reset times are normalized to ISO timestamps. Plain-text “usage limit reached” messages are ignored. |

The collector allowlists the local instance directories and JSONL session paths.
For Codex, it starts a local `codex app-server` and calls its
`account/rateLimits/read` method over JSON-RPC. Codex owns authentication and any
provider communication; the collector does not open authentication or
credential files. No quota percentage is inferred from token counts without an
explicit budget.

The local Codex homes are `~/.codex` for `codex` and `~/.codex-t3` for
`codex_ai4ed`. Claude's provider IDs are resolved to the local `claude_<label>`
homes using the T3 account labels (`claudeAgent` → `claude_hehe`,
`claude_mira` → `claude_kv`, `claude_kv` → `claude_mira`, `claude_dd` →
`claude_dd`, and `claude_hehe` → `claude_skora`). Active assignment counts and
provider associations come from the T3 SQLite projections, not those names.

## Commands

```sh theme={null}
bun packages/agent-quota/src/cli.ts status
bun packages/agent-quota/src/cli.ts recommend --provider claude --count 3 --json
bun packages/agent-quota/src/cli.ts recommend --provider codex --count 2 --json
```

`recommend` returns a ranked list with reasons and a simulated assignment list
that spreads the requested task count. A stale or missing quota signal is
uncertain and makes the pool ineligible. A fresh reported window at or above
90% is excluded. A reset timestamp already in the past also makes that window
uncertain, so it receives no imminent-reset preference. `claude_hehe` defaults
to at most one active assignment and a 25%
remaining reserve to keep the orchestrator account available.

Set `AGENT_QUOTA_RESERVES` to a JSON object keyed by instance ID to override or
add per-account `minRemainingPercent`, `maxConcurrent`, or `excluded` values.
These policy choices are local routing recommendations; T3 Code dispatch still
requires its normal provider instance selection.

## Freshness, reservations, and Antigravity

The 2026-10-23 routing policy includes every configured Codex, Claude, and
Antigravity instance. Availability alone is never quota evidence. Only
provider-reported percentages with valid observation and future reset timestamps
can establish healthy capacity. Every reported quota window must be current.
Codex and Claude signals have a 15-minute TTL; Antigravity has a 5-minute TTL.
These are conservative local policy defaults, not provider reset cadences.
Output includes `state`, `ageMs` (oldest quota window), `ttlMs`, `activeCount`,
`action`, and explanatory reasons. Missing observations have a null age.
Expired, missing, malformed, or non-authoritative usage is `UNKNOWN` and cannot
be selected. Near means at least 90% used; exhausted means 100%. Both recommend
`drain`: finish existing work without assigning new lanes, then require a fresh
healthy observation. An expired reset never implies free quota.

The tool reads existing `~/.t3/caches/<providerInstanceId>.json` **provider status
snapshots**, validating both instance ID and driver. It projects only quota
windows, `usageLimits.checkedAt`, and the optional opaque account identity hash.
It does not read provider profiles or auth files, invoke Antigravity's probe, or
reproduce its authentication flow. `--snapshots-only` disables transcript and
Codex app-server collection, making this cache plus orchestration metadata the
only usage sources.

T3 Nightly source inspection found Antigravity support in provider-core's
`makeAntigravityUsageProbe`: provider quota-summary buckets are preferred, with
reported model quotas as a fallback. The probe publishes `usageLimits` with
`checkedAt`, percentage windows, reported resets, and an opaque
`credentialFingerprint`. `ProviderRegistry` persists those status snapshots;
the Limits tab deduplicates account identities. No reset cadence is inferred
when a provider omits it. Missing or unavailable cached usage produces
`UNKNOWN` with `no-usage-signal`. This is a snapshot consumer; refreshing T3's
Limits tab remains T3's responsibility.

Models and display names come from `orchestrator_capabilities`, through the
supported T3 ACP command transport when available. A caller using native MCP
can pipe that tool's JSON response to `--catalog-stdin`. No Antigravity model
IDs are baked into the router. The observed live catalog includes Gemini 4
Argon and Gemini 3.8 Flash low/medium/high variants. Without a catalog, known
instance IDs remain visible, but requested model availability is unverified.

```sh theme={null}
bun packages/agent-quota/src/cli.ts recommend --task-kind implementation --snapshots-only --json
bun packages/agent-quota/src/cli.ts recommend --task-kind review --provider antigravity --snapshots-only --json
# Pipe a sanitized orchestrator_capabilities response into this command:
bun packages/agent-quota/src/cli.ts recommend --task-kind research --catalog-stdin --snapshots-only --json
```

Task kinds share quota scoring; they do not imply invented model-quality scores.
A requested `--model` must appear in that instance's catalog. Rankings subtract
30 points per active reservation plus a bounded contention penalty. This is a
routing weight, not a usage percentage. Eligible healthy pools rank before
UNKNOWN, near, or exhausted pools even when their reservations produce a
negative score.

Reservations combine active run and subagent projections, including queued,
preparing, starting, pending and waiting work. Held queued runs do not reserve
capacity. A task and its running child thread count once per instance; a later
active child turn still counts after the original task completes. Native
subagents without child threads use their provider-thread identity. Reads are
advisory snapshots, not atomic admission locks; concurrent callers must still
coordinate dispatch.

Identity is always `providerInstanceId`, never display name. The crossed Claude
labels and the shared `skora` label do not merge pools. When T3 exposes the same
opaque account fingerprint under the same provider, instances collapse into one
pool with combined reservations and the strictest configured reserve. Otherwise
they remain separate and carry an `alias` explanation. Hashes are not printed
in CLI output. Regression coverage lives in `tests/signals.test.ts` and the
existing collector/policy suites under `packages/agent-quota`.

## Single-shot safeguards for every orchestrator

`admit`, `observe`, `switch-lease acquire|release`, `switch-check`, and
`handover-check` are opt-in, single-shot JSON hooks. They serve Tuturuuu, Upskii,
Mastermind, and other owner threads on the same host. They do not install a
controller, daemon, timer, scheduler, automatic switch, or automatic failover.
Each reads one JSON object from stdin and writes one JSON result. Invalid input,
unreadable state, or contention returns `status: "block"` with a fixed reason;
callers must inspect `status`, not just the process exit code. Errors never echo
raw input. These commands always use non-credential provider status caches;
they never invoke provider probes; receipt scans select matching final provider-limit messages only.

Pool selection follows the shared-account contract: identify quota pools by
provider identity, deduplicate aliases, apply owner reserves and concurrency caps,
and use provider preference only to order otherwise eligible healthy pools. Keep
reviewer independence, privacy authorization, queue drainage and writer custody as
hard gates. If a same-thread transition is unsafe, preserve the handover packet and
workspace binding for one successor thread; never reparent children or replay work.

### Admission and outcome protocol

`admit` accepts a stable `requestId`, the requesting `threadId`, its
`currentInstanceId`, a fresh `catalog` from `orchestrator_capabilities`, and:

```json theme={null}
{
  "requirements": {
    "capability": "implementation",
    "taskClass": "mechanical",
    "authorizedInstanceIds": ["codex_ai4ed", "antigravity"],
    "privacyApprovedInstanceIds": ["codex_ai4ed", "antigravity"],
    "candidates": [
      {"instanceId": "codex_ai4ed", "model": "catalog-model-id", "capabilities": ["implementation"]}
    ]
  },
  "policy": {
    "orchestratorReservePercent": 30,
    "nearUsedPercent": 90,
    "unknownMaxConcurrent": 1,
    "preferenceWeights": {"codex_ai4ed": 4, "antigravity": 1}
  }
}
```

The numbers above are example policy inputs, not observed quota. Capabilities
are `implementation`, `analysis`, `review`, and `research`; reviewers also require
`requirements.authorInstanceId`. Candidate task capability and privacy/authorization
approval come from the owner, since the live catalog does not establish those
permissions. Every selected model must exist in the supplied catalog and its
instance must support delegation. Missing approval blocks rather than broadening
scope. An author and every verified alias of that account are excluded from
review. Same-provider account identity uncertainty blocks bypassing an author's
account or the owner's reserve.

Output includes the chosen `providerInstanceId` and model, reasons, a durable
reservation ID, and each pool's `FRESH`, `STALE`, `UNKNOWN`, or `EXHAUSTED` state,
observation age, reset timestamp (or null), and shared reservation count. STALE
has `quotaState: "UNKNOWN"`; it never supplies current headroom. Unlike the
strict `recommend` command, `admit` permits STALE/UNKNOWN pools below the explicit
`unknownMaxConcurrent` bound. The owner's own pool requires fresh headroom
strictly above its reserve. Fresh near-limit/exhausted usage and existing
per-pool reserve/concurrency gates always win. No eligible pool yields
`no-eligible-pool` plus the exact blockers for each pool, with no exhausted fallback.

Accounts are shared: multiple threads consume one pool's usage and reservations.
Verified aliases collapse once; neither thread count nor alias count multiplies
capacity. A file transaction serializes each admission decision and its pending
reservation. Reusing a reserved/completed request ID blocks duplicate dispatch;
reconcile its original result instead. Pending reservations release on terminal observation or after a 30-minute TTL
when no active native binding confirms that work continues. Expired request IDs
remain tombstoned for 30 days; reconcile uncertain dispatch rather than replaying it.
A heartbeat can reconcile a reservation with its native child-thread/provider-thread
ID so native and local records count once. Until that mapping is supplied,
counting is conservatively additive.

`observe` accepts `eventId`, `instanceId`, `observedAt`, and `outcome` (`success`,
`usage-limit`, or `capacity-error`), optionally `resetsAt` and `requestId`.
`terminal` defaults to true and releases that matching request reservation.
An existing heartbeat must send `terminal: false`; it can also provide
`nativeReservationId` to link the admission to a native reservation. No heartbeat
is created by this tool. Event IDs are idempotent; conflicting reuse, account
mismatch, and outcomes older than the admission are rejected. A usage-limit
outcome fences the entire shared account until its reported reset, even without
a usage API. Without a reset it remains exhausted until a later fresh covering-window check
shows usage below 100%; with a reset it expires at that time unless a newer receipt exists.
A no-reset receipt is retained for at most seven days, then expires without inventing a reset.
A success receipt alone does not clear it. A capacity error imposes a 30-minute local pacing cooldown,
not a quota percentage. After a reported reset, normal fresh/unknown admission
gates apply again; reset is not proof of fresh capacity.

### Planning preference and model sizing

Default planning weights are Codex 4, Claude 1, and Antigravity 1, configurable
per instance through `policy.preferenceWeights`. They reflect the user's report
that the ChatGPT allowance is about four times one Claude allowance. **These
weights are user planning inputs, not telemetry or measured capacity.** Each
shared account gets one weight (the maximum configured member weight), never
the sum of aliases. Ordering uses the existing reservation-adjusted score plus
that weight, after separating FRESH pools from unknown telemetry and applying
all eligibility gates. Claude and Antigravity remain available for task fit,
parallel work, and reviewer independence.

The reported extra ChatGPT reset credit appears only as an unverified planning
note. No command triggers, spends, activates, or counts reset credit as capacity.
For a selected live-catalog model, `taskClass` suggests low effort for `mechanical`,
medium for `standard`, and high for `security-review`, only if the model advertises
the matching `effort` or `reasoningEffort` option. The recommendation is not
runtime enforcement and never substitutes a weaker model outside the approved
candidate list.

### Thread transition and successor gates

`switch-lease acquire` takes `instanceId` (target), `threadId`, `attemptId`, owner
`pid`, `processStartedAt`, and `ttlMs` (1,000–300,000). **The lease is keyed only
by owner thread.** Different targets competing for the same thread cannot both
win. Different threads may hold transitions to the same account simultaneously;
shared-pool admission governs their capacity. The target is metadata, not an
exclusive account lock. Acquisition is atomic, records expired takeovers, and
rejects retired attempt IDs to prevent a delayed old release from removing a
replacement. Release takes the target instance, thread, attempt, pid, and process start time; it is
idempotent and cannot release a different attempt.

`switch-check` never acquires or renews a lease. It requires the matching live
thread lease and fresh owner-supplied evidence (at most five seconds old):
`observedAt`, `threadIdle`, `queue: {threadId, complete, items}`, empty
`unfinishedWriterIds` and `backgroundJobIds`, `children: {preserved, ids}`,
`watches: {preserved, ids}`, and empty `uncertainMutationIds`. The queue must be a
complete, freshly drained `t3_queue_list` result. A queued old model selection
blocks with `queued-model-rollback-risk`. Caller attestations are not a native
atomic switch fence; recheck at the safe boundary. Only the owner calls
`t3_thread_configure(modelSelection)` after the gates pass.

`handover-check` additionally takes `currentInstanceId` and a `handover` packet
of booleans: `inThreadSwitchSupported`, `oldWriterDrainedOrStopped`,
`sourcePreserved`, `dirtyFilesPreserved`, `indexPreserved`, `jobsPreserved`,
`childParentsPreserved`, `questionsPreserved`, `watchesPreserved`,
`unknownWritesPreserved`, `bindingVerified`, `successorIndependentlyAccepted`,
and `acceptanceRecorded`, plus `successorCount`. A healthy current account reports
`path: "stay"` with no successor recommendation. Otherwise a safe supported
switch reports `in-thread`; an unsafe/unsupported switch reports `successor`
and lists missing handover gates. At most one top-level successor is permitted.
The old writer must drain or stop, the successor must independently read and
accept the packet and supported workspace binding before writing, and acceptance
must be recorded before the predecessor settles. True child parents, questions,
watches, jobs, index, dirty source and unknown writes remain preserved. The check
never launches a thread, reparents a child, replays work, or creates a writer.

### Persistence and native integration limits

The host-wide tool ledger is `~/.t3/caches/agent-quota/hooks.json`, separate from
T3-owned provider snapshots and its database. A short exclusive transaction file
protects atomic write/fsync/rename operations; it is not an account lock. There
is no daemon. Symlink ledger files and malformed data fail closed; the ledger
has a 2 MB bound. Expired outcomes and inactive reservations are compacted under
the retention rules below. A transaction lock with a recorded owner can be
reclaimed only after its PID/start identity is confirmed dead or replaced and
its inode is unchanged. An empty or partial owner record is retryable for ten
seconds, then may be reclaimed under the separate reclamation lock after an
inode check.

Current telemetry coverage, verified from non-credential caches on 2026-10-23:

| Pool | Supported cached usage/reset | Account identity hash exposed |
| - | - | - |
| `codex_ai4ed` | Yes: one reported window with reset | No |
| `codex` | Yes: one reported window with reset | No |
| `claudeAgent` | Yes: two reported windows with resets | No |
| `claude_mira` | Yes: two reported windows with resets | No |
| `claude_kv` | Yes: two reported windows with resets | No |
| `claude_hehe` | Yes: two reported windows with resets | No |
| `claude_dd` | Yes: two reported windows with resets | No |
| `antigravity` | Third-party Claude/GPT only: two windows; no Gemini coverage | Yes |

These surfaces do not establish coverage for every model. In particular,
Antigravity Gemini remains uncovered by the observed windows. Claude has a
session window plus a Fable-scoped weekly window. Coverage is not a claim that
a pool is currently fresh or healthy. Cursor, Grok, OpenCode, Muse and Pi were disabled in the catalog;
this adapter has no verified quota collector for them. Missing individual
snapshots still yield UNKNOWN, and provider identity gaps remain explicit.

Native T3 currently exposes no pre-delegation hook parameter on `delegate_task`,
no atomic quota reservation/dispatch transaction, no atomic queue-drain-and-switch
operation, and no automatic failover API. The owner must wire these one-shot
commands into its existing dispatch/completion/heartbeat boundaries, supply live
catalog and safety evidence, map native reservation IDs, and retain custody.
Cross-host coordination is not provided by this host-local ledger. Independent
security review, exact-commit CI, and an owner-driven integration exercise remain
activation gates. Offline tests exercise policy, observation, shared reservations,
concurrent leases, expiry, queued rollback and handover; they do not claim native
hook activation or actual failover.

### Reconcile descendant failures after task completion

```sh theme={null}
bun packages/agent-quota/src/cli.ts reconcile-children --parent THREAD_ID --timezone Asia/Ho_Chi_Minh
```

This read-only command traverses the existing T3 lineage and task projections,
including nested descendants and provider-native subagents. It projects only
run/task status, model/account selection, pending request metadata, delivery
receipts, structured terminal errors, and final assistant messages matching provider limit/capacity patterns, including completed runs. It never reads authentication files or credentials, and never mutates T3 state.

Each entry distinguishes an app-owned original task, provider-native subagent,
or unbound thread-send follow-up. It shows original task status separately from
the latest terminal turn; snooze deadline; queued runs with their own model and
account selections (including held queues); pending questions/approvals; failure
class; the provider's redacted terminal receipt; reported reset; delivery evidence;
and the next resume boundary. Repeated root error items collapse to one entry
per terminal run/failure. Authentication error text is withheld and recognizable
credential syntax is additionally redacted. Other terminal receipt text is
preserved; missing receipts remain explicitly unavailable.

ISO reset timestamps are used directly. A human reset such as `resets 11:20am`
requires the caller's explicit `--timezone`; it is interpreted relative to the
receipt time, not the time reconciliation runs. Without a timezone, the reset
stays unknown. A snoozed descendant with an unheld queued run reports
`auto-resume-already-queued-do-not-duplicate`. All queued runs block switching,
because their stored selection can restore the old account. No queue is removed
or replayed. With no queued work, `safe-to-switch-account` requires idle run
state and fresh owner-attested writer drainage in `--evidence-stdin`, keyed by
thread ID as `{ "observedAt": "ISO timestamp", "drained": true }`; without it,
`writer-drain-unverified` requires parent action. This disposition is only the
run/drain prerequisite: `switch-check` still enforces the lease and custody gates.

Delivery is `delivered` when a notification delivery or consumption receipt exists.
A delivered event without parent observation reports unknown parent drain;
an unbound follow-up without a matching transfer reports `missing-event`. Pending
or ambiguous delivery remains `unknown`. Original task acknowledgment is never
reused to claim delivery of a later turn. These records survive restarts; they
prove recorded observation, not completed recovery.

The observed native gap is that queued `t3_thread_send` turns are not bound to a
new delegated task, so their later failures do not use the original task's parent
notification path. The 2026-10-23 incident was an original task completing, then
an unbound follow-up failing on the old account while another old-account run
remained queued. An original-task failure did notify its parent. This command
is a reconciliation aid, not automatic recovery or failover. The recommended
native fix is to deliver **every terminal failure of every descendant turn** to
its creating parent, deduplicated by run/failure, carrying account and reset
evidence regardless of whether the original task already completed.

Every failure has a stable `recoveryAdmissionKey`. To admit recovery, send
`admit` a `recovery: {threadId, runId, failure}` object along with the usual task
requirements and owner thread ID. The router derives the key itself, ignoring
alternate caller request IDs, and atomically records it in the same ledger.
Duplicate admission blocks both while reserved and after terminal observation.
The CLI rechecks descendants, refuses already queued/superseded recovery and
pending input, and requires fresh `recoveryEvidence: {observedAt, drained}` before
admission. This is exactly-once local **admission**, not an exactly-once external
mutation or automatic task replay. Dispatch outcomes remain the owner's custody;
unknown results must be reconciled under the original operation identity.

### Read-only reset reroute planning

`agent-quota reroute-plan --parent THREAD_ID` consumes the same JSON admission
requirements and policy on stdin, plus `rerouteEvidence` keyed by descendant thread.
Evidence includes `observedAt`, `onlyResetBlocked`, a complete `writerPids` list
(with `pid` and `state`: `idle-stream-json`, `active`, or `unknown`),
`writersComplete`, `dirtyFiles`, `dirtyFilesPreserved`, `custodyPreserved`, and
`uncertainMutations`. Evidence expires after five seconds. Idle stream-json is
acceptable only with confirmed idle run and drained writer/job custody; an idle
process name alone is insufficient. Optional `configured` and `resumed` readbacks
carry provider/model; resumed additionally requires task ID, run ID and running status.

The planner simulates existing admission on a copy of the ledger, applying the
verified limit receipt before selection. It does not reserve capacity. The parent
must commit admission and revalidate gates immediately before acting. The recovery
key is stable per thread and failed run; repeated admission blocks once reserved
or completed. Planning never claims exactly-once external execution: preserve a
returned task ID and reconcile unknown send outcomes before retrying.

The supported sequence preserves queued resume text, cancels old-account queued
runs, verifies an empty queue, commits admission, acquires the thread transition
lease, checks switch safety, configures the model, sends saved resume text plus
state readback with `t3_thread_send(mode: auto)`, and verifies the returned task via
`task_status`. Configuration is reported as `configured`; only a matching running
task is `resumed-on-provider`. Preserve dirty files and index throughout. Unsafe
switches report the full successor handover gates; exhausted pools never become a
fallback. These are instructions for the owner, not automatic tool execution.

A native reset-time continuation may remain armed after rerouting. It queues
behind a running turn, but may become redundant. Reconciliation identifies
server-created `limit-resume:<thread>:<failedRun>:...` message identities without
reading message bodies and recommends preserving text then `t3_queue_cancel` when
another provider continuation has started. An armed snooze alone is not evidence
that a continuation has queued. No controller, timer, automatic failover, or native
pre-delegation hook is installed by this package.

For a reset-only wait, the owner may use the read-only reroute plan: preserve
queued text and dirty files, cancel old-account queued selections, obtain fresh
admission and the thread transition lease, then configure and verify a task-bound
running continuation. Configuration alone does not count as resumption.

### Receipt and model-scope admission gates

Every admission scans recent provider-limit receipts across all T3 threads, bounded
to catalog instances and 30 days, including completed runs whose final assistant
message reports a limit. This reflects shared accounts across orchestrators.
This catches Antigravity's `Usage Limit Reached` result even when T3 labels the run
completed. Relative resets (for example, `6 days, 23 hours`) use the observation
time and round duration up to whole seconds. A limit without a reset remains
exhausted until a later fresh covering-window check shows usage below 100%, or
for at most seven days when no reset is reported. A receipt with a reset expires
at that timestamp unless a newer receipt supersedes it. Invalid ledger rows more than five minutes
ahead are quarantined per account; that pool remains UNKNOWN until a later fresh
covering provider window is observed. The row is never trusted as a quota failure.

Cache window IDs, labels and model scopes are preserved. Claude windows are
model-scoped only when the label names a recognized model family (`Opus`,
`Sonnet`, `Haiku`, or `Fable`); generic labels such as `Weekly limit`, `Weekly
usage`, `Weekly total`, and `Current week` apply account-wide. `Current week
(Opus)` and `Current week (Sonnet only)` cover only the named family.
Antigravity `3p-*` windows cover Claude/GPT, not Gemini; `gemini-*` windows cover
Gemini. Models with no covering window are UNKNOWN and subject to bounded
admission. Availability and a zero in an unrelated window never establish
headroom.

When provider identity hashes are missing, distinct per-instance Claude homes or
an explicit owner mapping may establish separate accounts. The home identity is
the SHA-256 hash of the normalized path from
`settings.providerInstances.<id>.config.homePath`, not a built-in table. Missing
paths remain unknown. A provider identity hash, when present, takes precedence
for alias deduplication. Account keys and fingerprints are removed from hook JSON
output. Cache reads reject symlinks, non-regular files and files over 2 MB.

Reservations without a currently active native binding expire at their recorded
expiry, capped at 30 minutes; positional admits use a shorter five-minute
provisional reservation. Completion or expiry retains a 30-day request tombstone. A usage-limit receipt
expires at its recorded reset unless a newer receipt exists. Expired capacity
observations and dead-owner leases are compacted; live or uncertain expired lease
owners remain protected until release or confirmed death. Lease
history and request tombstones have 30-day retention, so callers must reconcile
older recovery operations rather than relying on indefinite idempotency. The
transaction mutex records its PID and process start time; takeover requires a
confirmed dead or replaced process and an unchanged lock inode, except for an
empty or partial record older than the ten-second grace period. Unknown liveness
fails closed. Switch lease release also requires the original PID/start identity;
an expired lease held by a live or unverified process cannot be taken over.

Reroute planning reuses and revalidates its existing reservation rather than
reserving twice. Blockers take precedence over configured/resumed status, and
resumption must match a running task, provider and model in the T3 snapshot.

### Preventive block ledger and shell-compatible gate

Before each delegation, invoke `agent-quota admit POOL MODEL`. Exit **0** means
ADMIT; exit **3** means a policy block; exit **2** means malformed input or
unverifiable state. JSON on
stdout explains the decision. This preflight uses cache-only quota and current reservations. Every successful
positional admission records a provisional reservation for five minutes, so
concurrent callers share the configured pool limit while the native task binding
settles. The reservation is provisional, not a native task reservation. The existing stdin JSON
`admit` interface remains the transactional admission path for full requirements.
Pass `--reserve-owner` when the target is the orchestrator's own account, or set
`AGENT_QUOTA_OWNER_POOL`; matching aliases require fresh headroom above the 30%
owner reserve. Uncovered/stale models remain bounded by one concurrent reservation.

Both admission interfaces and recommendations ingest
`~/.local/share/tuturuuu/orchestration/quota/blocks.json`. Version 1 preserves the
interim `blocks` entries: `pool`, `modelScope`, `reason`, `observedAt`, `resetAt`
and/or `nextEligibleAt`, plus evidence and existing metadata. Model scopes support
`*` and `?` globs. A block applies until the later supplied eligibility timestamp.
Any active scope block suppresses all provider probes for that account, including
detected aliases; cache-only reads can still admit an unblocked model. A malformed
ledger fails closed. No-model recommendations exclude a pool with any active scope.

Record a failure once with:

```sh theme={null}
agent-quota block --pool antigravity --model-scope 'gemini-4-argon-*' \
  --reason 'Usage Limit Reached resets in 6 days, 23 hours' \
  --evidence 'thread-id/run-id/terminal-receipt'
```

Optional `--observed-at`, `--reset-at` or `--next-eligible-at` records explicit
provider/operator timing. Relative reset text is anchored to observation time;
clock-only reset text uses `--timezone` or the machine timezone. Without reset
evidence, the default conservative `nextEligibleAt` is five hours later, not a
claim that quota resets then. Evidence should identify the terminal run uniquely;
repeating the same pool/scope/reason/evidence is idempotent and does not extend the
original block. Writes are atomic under a process-verified file mutex and preserve
existing interim metadata. Block expiry removes this prohibition; normal fresh
quota, owner-reserve and bounded-unknown gates still apply.

Enforcement is **orchestrator-invoked**. T3 currently has no native pre-delegation
hook or automatic failover. A native `delegate_task` pre-admission callback that
can veto dispatch is needed for platform enforcement; provider-reported usage,
model scope and reset timestamps in `orchestrator_capabilities` would supply the
corresponding telemetry. This change installs neither API nor any controller.

An existing interim block without either deadline remains blocked until its evidence is corrected; it does not invalidate unrelated pools. Newly recorded blocks always receive a deadline.

### Usage UI parity, shared receipts and operator commands

The Usage view reads `server.getConfig.providers[].usageLimits`. The application
also publishes `subscribeServerConfig` snapshots and `providerStatuses` events.
These are normal T3 application RPC surfaces; there is currently no narrow
MCP/CLI endpoint exporting only quota windows and account home paths to this
router. The router reads the existing non-credential `~/.t3/caches/<instance>.json`
provider status snapshots. It does not refresh a provider, read authentication
files, or write SQLite. A fresh RPC response does not refresh an old
`usageLimits.checkedAt`.

Each window reports **used percent**; remaining is `100 - usedPercent`. Session,
weekly and model-specific windows remain separate. Scope comes from window IDs
and labels: Claude `five_hour` is account-wide, `seven_day_fable` is Fable-only;
Codex primary/secondary windows cover its account; Antigravity `3p-*` covers
Claude/GPT, not Gemini. Uncovered Gemini models are UNKNOWN. Receipt scope follows
the corresponding model family, so Argon effort variants share a limit without
blocking Flash. The latest reset phrase wins. Every admission scans terminal
receipts across all catalog instances and orchestrator trees, limited to 30 days
and 5,000 rows per projection; overflow or unreadable state fails closed. An
expired receipt is cleared at its recorded reset unless a newer receipt exists.

Account identity uses provider metadata when available. Otherwise it is the
SHA-256 hash of the normalized, explicitly supplied account home path (including
provider kind), **not the display name**. Read the path-only projection of
`settings.providerInstances.<id>.config.homePath` from the supported, redacted
`server.getSettings`/`server.getConfig` response. Do not read raw settings files:
they can contain credentials. Missing paths remain unknown; there is no static
Claude home table. The current mapping supplied for verification is claudeAgent
→ claude\_skora, claude\_mira → claude\_mira, claude\_kv → claude\_kv, claude\_hehe →
claude\_hehe, claude\_dd → claude\_dd. These names are a comparison receipt, not
fallback routing configuration. Identical identities collapse before aggregation,
and shared reservations are non-exclusive. Home separation is configuration
identity evidence, not proof that two independently configured homes can never
contain the same provider login.

Run from the repository (the package script exposes the same commands):

```sh theme={null}
bun packages/agent-quota/src/cli.ts status --json
bun packages/agent-quota/src/cli.ts explain --pool claude_dd --model CLAUDE_MODEL_FROM_LIVE_CATALOG
bun packages/agent-quota/src/cli.ts dry-run route --model gpt-6.1-sol
bun packages/agent-quota/src/cli.ts admit codex_ai4ed gpt-6.1-sol
```

`status`, `explain` and `dry-run route` are read-only and report individual
windows, remaining/used units, source, confidence, age, reset and routing reasons.
For a review recommendation, pass `--task-kind review --author-pool INSTANCE`;
shared or unverified same-provider identity cannot satisfy reviewer independence.
`--catalog-stdin` accepts the current `orchestrator_capabilities` catalog when the
ACP transport is unavailable. Positional admission retains exit **0** for admit,
**3** for policy/exhaustion block, and **2** for malformed input or unverifiable
state. Lock contention is a retryable block (exit 3). A malformed `block`
command also exits **2**. Invalid manual observations
are skipped individually and listed in `invalidObservations`; valid observations
continue to contribute. It records pacing/hysteresis state and a five-minute provisional reservation
in the existing hook ledger; it does not switch an active writer. Full JSON
admission remains the transactional native-task reservation interface. Manual
observations more than five minutes in the future are rejected into
`invalidObservations`. A resetless session observation is bounded to five hours.
A block reset is inherited only when its scope covers the entire observed window
and the block is within that window’s maximum age.

The cross-thread terminal receipt scan targets a maximum of 2 seconds for up to
5,000 candidate runs on a local projection; it performs one bounded candidate
query and reuses those IDs for receipt reads. Exceeding this target is a
performance regression, not a reason to skip receipt checks.

For a supported manual observation, pipe a narrow JSON document into
`bun packages/agent-quota/src/cli.ts import-usage`. Include the current catalog
as `catalog` if needed:

```json theme={null}
{
  "provenance": "operator transcription of the individual T3 Usage window",
  "observations": [{
    "pool": "claude_dd", "measure": "remaining", "units": "percent",
    "value": 97, "observedAt": "2026-10-23T05:33:00Z",
    "windowId": "five_hour", "windowLabel": "Session",
    "provenance": "user screenshot at 12:33 Asia/Saigon"
  }]
}
```

This dated example is evidence, not a default percentage. Supply `resetAt` only
when observed. Without a reset or after the TTL, the reading cannot establish
fresh headroom. Existing `.observations[]` with `kind: manual-screenshot` and
`sessionRemainingPercent` are normalized explicitly to remaining percent. Names
and ordering do not identify accounts. For app-side exports, `providers[]` accepts
only `instanceId`, `driver`, and `usageLimits` (`checkedAt`, `windows`,
`unavailable`); windows accept `id`, `kind`, `label`, `usedPercent`, `resetsAt`,
`windowDurationMins`. Optional `settings.providerInstances` accepts only driver
and config homePath/shadowHomePath. Never pipe a full config or auth document.
Newer provider observations supersede older manual readings for the same window.

`configure` takes JSON stdin with `pool`, `policy`, `evidence` and optionally
`catalog`. Policy requires `reservePercent` (0–100), `nearUsedPercent` (1–100),
`hysteresisPercent` (0–50 and less than near), `pacingMs` (0–86400000),
`maxConcurrent` (integer 1–100), and `preference` (0–100). It validates and records
a dated receipt with an evidence digest. Near depletion latches until fresh used
percent falls to `nearUsedPercent - hysteresisPercent`; pacing limits time between
admissions. Aliases use the strictest reserve/concurrency/pacing thresholds and a
single preference, never multiplied capacity. Preference cannot override safety
gates. Adjusting these values never changes the active thread's model/account.

At 05:58:05Z on 2026-10-23, existing provider caches yielded the following
individual **session remaining** comparison. Snapshot `checkedAt` values were
05:56:08–05:56:12Z, within the 15-minute Claude TTL; these are cache observations,
not a newly invoked provider probe. Drift after the 05:33Z screenshot is expected.

| Catalog ID | Screenshot 05:33Z | Snapshot \~05:56Z | Session reset (UTC) |
| - | -: | -: | - |
| claudeAgent | 0% | 0% | 06:00:00 |
| claude\_kv | 12% | 8% | 05:59:59 |
| claude\_hehe | 57% | 45% | 08:29:59 |
| claude\_dd | 97% | 93% | 09:20:00 |
| claude\_mira | 100% | 94% | 10:30:00 |

All five had session and Fable weekly windows. Codex `codex` reported 0% remaining
in its primary Monthly window; `codex_ai4ed` reported 75% in primary Weekly.
Antigravity exposed only third-party `3p-5h` and `3p-weekly` windows; those do not
prove Gemini headroom. These dated observations are not configuration and expire
normally. The native gaps remain a narrow read-only usage/home-path export and a
veto-capable pre-admission callback on `delegate_task`. No native automatic
account transition or failover is implemented.

`Selected model is at capacity` is a capacity event, not a quota event. A
`block` command for this receipt requires an exact `--model-scope MODEL` and
uses a 30-minute `nextEligibleAt` by default; it rejects `*`/`?` scopes and
`--reset-at` for capacity. Other models on the shared pool remain eligible.
Likewise, `observe` with `outcome: capacity-error` requires `model`, accepts
`nextEligibleAt`, and defaults to a 30-minute model-only cooldown. Capacity
expiry does not assert quota headroom; normal admission checks still apply.

### Turn-boundary warning and safe same-thread switch

The optional, bounded `watch` command is read-only and is intended to run at an
orchestrator turn boundary. It uses the minimum remaining percentage across all
fresh authoritative windows covering the owner's model, including weekly and
monthly windows, and never probes a provider. Pass `--model` when known; without
it, model-scoped windows are included conservatively. An active block or
usage-limit receipt forces `switch-now`; stale or missing data returns `warn`.
Defaults are `warn` at 25%
remaining, `switch-now` at 12%, and a 3-point hysteresis band. Supply the previous
verdict to preserve hysteresis across invocations; callers own that small piece
of turn state, so the command needs no timer or writable watch ledger:

```sh theme={null}
bun packages/agent-quota/src/cli.ts watch --owner claude_hehe --role main \
  --previous-verdict warn --warn-percent 25 --critical-percent 12 \
  --hysteresis-percent 3
```

It emits one JSON line with the verdict, signal state, remaining percent and an
optional successor. Exit codes are 0 for `ok`, 3 for `warn`, and 4 for
`switch-now`. Missing or stale data is `warn`; a successor is selected only from
fresh healthy headroom and excludes the owner account, blocked pools, active
loads, outstanding reservations, active usage-limit receipts, and model capacity
cooldowns. `successorReason` appears only for a non-`ok` verdict. No successor
means the caller must stop and escalate rather than choose a fallback.

Before a supported same-thread account change, the owner runs a read-only
checkpoint against its thread ID and a newline-separated file of watcher PIDs:

```sh theme={null}
bun packages/agent-quota/src/cli.ts checkpoint-ready \
  --thread THREAD_ID --watcher-pids-file /path/to/watcher-pids.txt
```

It reports `go` or `no-go`, including queue/writer counts, missing watcher
process metadata and any in-flight `gh pr merge` process. Writer nodes count
only while their associated T3 run is active; the count query is capped at 1,001
nodes and SQLite lock waiting is bounded to one second. A non-empty queue,
active T3 writer/run, unknown watcher PID, or merge
blocks the configure boundary. The supported operation sequence is exactly:

1. `checkpoint-ready` passes and the owner's queue is empty.
2. The owner calls the supported `t3_thread_configure(modelSelection)` API.
3. The owner reads back the thread configuration and verifies provider/model.
4. The owner continues only after the readback matches.

The check does not acquire a lease, cancel queued work, or configure the thread.
The owner must preserve and drain any work before retrying it. T3 still has no
native pre-delegation admission callback on `delegate_task` and no automatic
account failover; these one-shot commands are orchestrator-invoked safeguards.

Main orchestrators can pass `--role main` to prefer an eligible, fresh, healthy
Claude successor; child/subagent callers use `--role child` (the default) and
retain task/provider/model-driven ranking. A main-role non-Claude fallback is
blocked unless the caller explicitly opts in with
`--allow-non-claude-fallback`; an exhausted, stale, reserved, or otherwise
ineligible Claude pool is never promoted by the role preference. The JSON
admission request carries the same choice as `policy.orchestratorRole`, with
`policy.allowNonClaudeFallback` defaulting to false. Main role changes ordering
among eligible pools only and does not bypass quota, block, reserve, capability,
privacy, authorization, concurrency, reviewer-independence, or drainage gates.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.