Codex Reset Manager runs as a per-user macOS LaunchAgent and spends real Codex usage. This document states what it trusts, what it guarantees, and — just as importantly — what it does not.
Open an issue labelled security, or contact the maintainer privately if the
report itself would disclose the problem. There is no published response
timeline; this is a single-maintainer project.
- Node.js 22 or newer.
- macOS only (
launchd,plutil,osascript). - Codex CLI: see
TESTED_CODEX_CLI_VERSIONSinsrc/codex-command.ts.doctorwarns about an unlisted version. It does not block automatic anchoring, because the App Server protocol changes faster than this tool can be revalidated and a hard gate would break working installations on every Codex upgrade.
This tool audits none of the following. Each is trusted as it stands:
- The Codex CLI binary and its App Server. The manager speaks JSON-RPC to
codex app-server --stdioas a child process. It never readsauth.json, parses OAuth tokens, or makes network calls of its own. - The Codex sandbox. Anchor threads request
read-onlywithnetworkAccess: falseandapprovalPolicy: "never". Enforcement is upstream's. Treat the sandbox as a strong control, not an absolute one. - MCP servers the user configured in
~/.codex/config.toml. Starting a thread may initialize them, and that happens before any model turn. The anchor prompt forbids tool use and any tool-like item aborts the turn, but server startup is earlier than that abort.doctorreports whether any are configured. - macOS
launchdandosascript, and the local user account. Anything running as this user can already do everything this tool does.
- Rate-limit values and App Server notifications. Used only for scheduling
and verification. Anything unprovable resolves to
unverifiedorskipped, never to a second turn. state.jsonandconfig.json. A corrupt file falls back to defaults, and safety-relevant config fields are pinned toDEFAULT_CONFIGon load, so hand-editing the file cannot weaken the anchor policy or its verification.CODEX_RESET_MANAGER_CODEX. Re-validated at spawn time rather than trusted from install time.
- A reset generation is claimed and persisted before any turn starts, and is never retried. A crash, timeout, or RPC failure cannot produce a second turn for the same generation. Availability is deliberately traded for at-most-once.
- Anchor turns run in an ephemeral thread in a dedicated workspace, and are refused if that workspace is not empty.
- A tool-like item, an approval request, or a provider reroute interrupts the turn.
- Only an explicitly advertised model and reasoning effort is used; an unknown model is ineligible.
- The rate-limit snapshot is re-read immediately before the durable claim, so usage that appears during the coalesce window cancels the attempt.
verifiedrequires the target window's reset timestamp to have advanced and then held steady across several samples (see below).- Logs redact prompt-, response-, and credential-shaped keys. State, config, and logs are owner-only (0600 / 0700).
- The tool itself makes no network requests.
- That passive reads are free.
account/rateLimits/readis assumed not to consume quota. That is an assumption about the backend, not a guarantee. The daemon already issues this read on every poll; multi-sample verification adds two more reads per anchor, which is a small fraction of that existing volume. - Causation. Multi-sample verification proves that a window's reset timestamp advanced and then stopped moving with the clock. It does not prove that this turn caused the advance. If the timestamp advanced once for an unrelated reason before the first sample and then held steady, no external observation can distinguish that from a successful anchor. The check exists to eliminate the sliding-timestamp false positive, not to establish causation.
- That "steady" means fixed. Steadiness is judged over the sampling span
(4 samples across 45 seconds by default). If the backend served every sample
from a single cached snapshot lasting longer than that span, identical values
would prove nothing. This assumption cannot be eliminated from outside — any
span can be defeated by a coarser cache — so it is bounded rather than
removed: the configured span is pinned, the samples must genuinely be spread
across it, and the observed span is recorded as
spanMsin theanchor_verification_sampledlog entry so any verdict can be audited later. - That a refused window will recover on its own. A window the samples
cannot prove steady is refused as a scheduling baseline and stays unscheduled
until a later manual
test-anchorsucceeds. That is deliberate: scheduling against a timestamp that keeps receding would mean waiting for a boundary that never arrives.test-anchorandstatusname the refused windows. - That the backend's timestamps are correct or timely, or that every applicable limit is exposed. Windows the API does not expose are not managed; the tool does not guess at them.
- That MCP servers are not started by an anchor thread.
- Defence against a compromised Codex CLI, or against anything else running as this user.
- Notification delivery. macOS may suppress notifications.
This tool does not bypass, raise, or circumvent any usage limit. It issues one ordinary, minimal, fully metered request so that a rolling usage window begins at reset time rather than whenever the user happens to start working. If your account is governed by a Business or Enterprise agreement, confirm with your administrator before running it.