Quota Sentry is a local quota guard for agent harnesses. The v0.1.x line supports Codex by watching the Codex 5-hour usage window via codexbar and blocking future Codex lifecycle activity once the configured threshold is reached.
- Codex only in
v0.1.x; additional harness adapters are welcome. - Uses
codexbar usage --provider codex --source cli --format json. - Monitors the 5-hour window (
windowMinutes: 300) by default. - Blocks at
usedPercent >= 95untilresetsAtplus a 60-second buffer. - Fails open when
codexbaris missing, quota JSON is unavailable, or state is stale.
The background daemon does not interrupt an already-running model request. It polls every minute and writes state; the synchronous guard command is what sleeps when invoked from a Codex hook or wrapper.
Quota Sentry is intentionally conservative for public use: missing tools, malformed quota data, stale state, and unknown quota windows fail open instead of blocking the user.
Run from this plugin root:
./scripts/quota-sentry poll
./scripts/quota-sentry start
./scripts/quota-sentry status
./scripts/quota-sentry guard
./scripts/quota-sentry stopguard keeps stdout/stderr quiet by default because Codex surfaces hook output back into the TUI after long waits. When it starts waiting, it writes one notice directly to the controlling terminal instead:
Quota Sentry: waiting for Codex quota reset until <timestamp>.
Use ./scripts/quota-sentry guard --verbose only when running it manually and you want a captured wait message too. Use --no-notify to suppress the terminal notice.
Install global Codex hooks:
./scripts/quota-sentry install-hookThat command merges Quota Sentry hooks into ~/.codex/hooks.json and writes a .bak backup if a hooks file already exists. Restart Codex after installing hooks if the current session does not pick them up.
Quota Sentry intentionally does not rely on plugin-local hooks. Current Codex builds expose global hooks, but plugin-scoped hooks are not a reliable runtime surface yet. The installer writes absolute script paths into ~/.codex/hooks.json.
Installed hooks:
SessionStart: starts the background daemon.UserPromptSubmit: runsguardbefore a new prompt is accepted.PreToolUse: runsguardbefore tool execution, using the daemon's latest state.
Default state lives under:
~/.cache/quota-sentry/
Files:
state.json: latest quota decision.quota-sentry.pid: daemon pid.quota-sentry.log: daemon output.
Set this environment variable to bypass synchronous blocking:
export QUOTA_SENTRY_DISABLE=1Run tests:
PYTHONPATH=src python3 -m unittest tests/test_quota_sentry.py -vRun autonomous E2E tests:
./scripts/autonomous-testThe autonomous harness runs one live codexbar smoke poll, then uses synthetic codexbar binaries for quota-edge scenarios. It writes a report under .quota-sentry-runs/.
For clean clones without installed Codex hooks, the global hook scenario is skipped by default. Use ./scripts/autonomous-test --skip-live --require-global-hook when you specifically need to verify that this checkout is installed in ~/.codex/hooks.json.
See CONTRIBUTING.md for development workflow, test expectations, hook-safety guidance, AI-generated code expectations, and guidance for adding other harnesses such as Claude Code or OpenCode.
Apache License 2.0. See LICENSE.