Environment Variables¶
TokenFuzz is designed to run without an environment file. Prefer command flags
for choices that belong to one run (--target, --backend, --model,
--strategy) and target.toml for choices that belong to one target.
The variables below are the operator-facing exceptions. Each one is here for the same reason: its default can produce something you would otherwise have to diagnose, such as a run that stops by itself, a session that restarts mid-thought, or a local model that never finishes a decision. The harness reads other variables internally; those are not a supported interface and you should not need them.
Worker pool¶
| Variable | Default | Use it for |
|---|---|---|
NUM_AGENTS |
unset | A flat pool of N workers. On a browser target this replaces the browser/shell split. |
BROWSER_AGENTS |
1 |
Browser-mode workers. Only applies when [runner].args declares a {PROFILE} page route; a browser-mode script engine gets shell workers only. |
SHELL_AGENTS |
2 beside browser workers, 3 otherwise |
Shell/generic workers when NUM_AGENTS is unset. The default is deliberately not sized to the machine: an ordinary run refills every slot to the wall, so the pool multiplies token spend directly, and a shared provider quota is a hard stop for the whole account rather than a pause. Raise it per run when the budget allows. |
WORK_CARD_CLAIM_TTL_SECONDS |
1800 |
How long a work-card claim stays valid without its hypothesis closing. Thirty minutes is a safety net so a killed agent does not hold its card for a shift; raise it only for cards you know take longer. |
A one-iteration smoke test always launches one worker, whatever these say.
Spend and time ceilings¶
| Variable | Default | Use it for |
|---|---|---|
AUDIT_WALL_BUDGET_SECS |
0 (off) |
Wall-clock ceiling for a continuous run. The loop stops launching new iterations once it is spent, the simplest way to leave an overnight audit running with a hard stop. Provider quota pauses do not count against it. |
STEWARD_INTERVAL_SECS |
300 |
Continuous runs only: seconds between steward ticks. A tick scores the generation, rotates starved strategy lanes, re-ranks the queue, and refreshes indexes without stopping any slot. Each tick is logged as an iteration. |
AGENT_TIMEOUT |
7200 seconds |
Hard ceiling for one agent launch, and, in cohort mode (fixed-lane, delta, ensemble, and --no-refill-workers runs), for one iteration's pool of them. An early-finished slot is relaunched while a cohort-era peer is still running (one overtime session per slot), so this also bounds how far those replacements can push post-iteration triage out: every session in the iteration is clamped to what remains of the ceiling measured from when the iteration's first sessions started. |
POOL_OVERTIME |
cohort-era |
Cohort mode only; an ordinary run refills every slot to the wall. Decides which in-flight peer lets a slot that finished after the initial cohort drained take its one extra session. cohort-era: only an initial session or a refill launched beside one, so an overtime session never justifies another. any-peer: any peer, including another slot's overtime; the per-slot cap and the AGENT_TIMEOUT clamp still bound the iteration at one extra session per slot. Measure it with the benchmark's Efficiency table (occupancy against confirmed per seat-hour) before making it a default. Any other value is refused. |
SHELL_SANITIZER_RUN_BUDGET |
60 |
Sanitizer runs one shell/generic agent may spend per iteration. |
BROWSER_SANITIZER_RUN_BUDGET |
25 |
The same budget for browser-mode agents. |
To bound an ordinary run, the positional iteration count is clearer than any of these:
When a run stops or restarts by itself¶
Two defaults end something on their own. Both announce themselves in the log, so this section is mostly here to explain what you are reading.
| Variable | Default | What it controls |
|---|---|---|
MAX_DRY_SESSIONS |
10 |
A continuous run stops once this many generations (steward ticks, or cohort iterations in cohort mode) in a row produce nothing and no hypothesis is still open, logging STALL_STOP. Raise it for a hard target you expect to be slow; a value too low to let S1 finish its longer dry runway is raised to nine. |
TURN_SOFT_CAP |
128 agent/tool turns |
Rollover target for a long audit session. Claude, Grok, and current Google Gemini CLI versions use native turn limits; Gemini retains a completed-tool fallback for older versions. Codex and OpenCode use completed tool events as the safe termination boundary. Antigravity (agy) has neither a native turn flag nor a stable completed-tool event contract, so its prompt carries the same cooperative target but only AGENT_TIMEOUT can hard-stop it. Capped sessions continue from structured state; the log says turn-capped; continuing from state, and the transcript ends with TURN_SOFT_CAP reached …. Set 0 to disable. |
CONTEXT_SOFT_CAP |
0 (off) |
Optional context-size rollover for a long audit session, in prompt tokens, on backends that report per-request usage in their stream (Claude, Grok). Every turn replays the whole transcript, so a session past this size pays more per step than a fresh one resumed from state; once reached, the session ends when no tool is in flight, exactly like a TURN_SOFT_CAP rollover, with the transcript ending TURN_SOFT_CAP reached at N context tokens …. Off by default because backends that report usage only at exit cannot be bounded this way, and a cap that fires for one benchmark condition and not another is not a fair comparison; set it only on a run where every compared backend reports per-request usage. |
Already checkpointed hypotheses and artifacts are preserved. The next iteration resumes them from structured state; work not checkpointed before a backend's turn boundary may need to be repeated.
The default is deliberately conservative: recorded Claude request curves modeled about 28% lower cache reads at 128 while interrupting fewer original sessions than a 100-turn cap. Use 100 as a more aggressive cost setting only after checking finding yield and incomplete-artifact rates on your workload:
Native model turns and completed-tool events are not identical units, so treat the value as a cross-backend rollover target rather than an exact request quota.
Model selection¶
Use --backend and --model for reproducible commands. These overrides are
for a shared shell, or a backend binary outside PATH.
| Variable | Default | Use it for |
|---|---|---|
AUDIT_BACKEND |
all |
Backend used when --backend is omitted. |
CLAUDE_MODEL_DEFAULT |
config/models.toml |
Default Claude model. |
CODEX_MODEL_DEFAULT |
config/models.toml |
Default Codex model. |
GEMINI_MODEL_DEFAULT |
config/models.toml |
Default Gemini model. |
GROK_MODEL_DEFAULT |
config/models.toml |
Default Grok model. |
CLAUDE_BIN / CODEX_BIN / GEMINI_BIN / GROK_BIN / OPENCODE_BIN |
the CLI's own name (agy for Gemini) |
Backend executable outside PATH. |
USE_GEMINI_CLI |
0 |
Use Google Gemini CLI instead of the default Antigravity CLI. |
CLAUDE_CODE_PROMPT_CACHE_TTL |
unset | Claude Code's prompt-cache write tier (5m or 1h). TokenFuzz sets 5m on every Claude launch it makes (agent sessions, validators, and decision calls), because a harness prefix is almost never idle for five minutes and the one-hour write costs 60% more; see the cost model. Set it yourself to override. Cost tier only; it never changes model behaviour. |
AUDIT_MODEL_PREFLIGHT |
1 |
Before starting, launch the selected model once through the real agent path, with the same granted directories as an audit session and the audit guide in the prompt, and require it to run a command that writes into the target tree. A backend that can reply but cannot act, a CLI that silently serves a different model, or a model whose safeguards refuse the audit workload fails here rather than spending the run. Set 0 only for an intentionally offline or mock run. |
AUDIT_MODEL_PREFLIGHT_TIMEOUT |
60 seconds (300 for Google Gemini CLI) |
Ceiling on each preflight attempt. Raise it when a slow local model loses the probe and the audit never reaches its first agent. |
AUDIT_MODEL_PREFLIGHT_ATTEMPTS |
3 |
How many times the preflight probe is retried on a transient failure before the run stops. |
Model precedence is --model, then the matching *_MODEL_DEFAULT, then
config/models.toml. The oss backend has no default: always pass the exact
served model name with --model.
Authentication variables such as GEMINI_API_KEY, GOOGLE_API_KEY, and
XAI_API_KEY belong to the backend CLI. TokenFuzz forwards selected
credentials only when bin/audit-container-shell --forward-credentials is
used. Keep keys out of target.toml, reports, and committed shell files.
Local model endpoint¶
| Variable | Default | Use it for |
|---|---|---|
AUDIT_LOCAL_BASE_URL |
http://127.0.0.1:8000/v1 |
OpenAI-compatible endpoint used by --backend oss. TokenFuzz appends /v1 when omitted. |
AUDIT_LOCAL_API_KEY |
EMPTY |
Token for a local endpoint that requires authentication. |
LLM_DECISION_TIMEOUT |
45 seconds hosted, 180 for oss |
Ceiling on each audit-time ranking, peer-mapping, triage, and validation decision. Setting it applies to every decision, including the two below. Stage deadlines may shorten it. |
RANK_WORK_LLM_TIMEOUT |
unset | Override LLM_DECISION_TIMEOUT for work-card reranking only. The bin/rank-work --llm-timeout flag takes precedence over both. |
RANK_WORK_LLM_MODE |
boost |
How far the rerank verdict reaches. boost adds a bounded increment to the deterministic score; primary sorts the ranked window by the model's score, with the deterministic score breaking ties, inside each buildability tier. In both modes the model reorders the cards it was shown (it cannot add or drop one), and in primary mode it cannot lift a card across a buildability tier; on timeout or malformed output the deterministic order stands. The bin/rank-work --llm-mode flag takes precedence. |
Every decision launches a full agent CLI rather than a single chat completion,
so its floor is a process launch plus a reasoning turn. A few decisions have
been observed to complete well past the ceiling above and get a longer
built-in default, scaled by the same hosted-to-oss ratio so a slow
local-inference host gets proportionally more room. Setting
LLM_DECISION_TIMEOUT replaces those defaults too.
For Ollama:
export AUDIT_LOCAL_BASE_URL=http://127.0.0.1:11434/v1
bin/audit --target <target> --backend oss --model <served-model>
A slow local model is where these bite. If the audit never gets past startup,
the model is losing the launch probe: raise AUDIT_MODEL_PREFLIGHT_TIMEOUT.
If agents work but findings sit unvalidated, decisions are timing out: raise
LLM_DECISION_TIMEOUT. Both are normal on CPU inference or a large model on
modest hardware, and neither means the model is misconfigured.
LLVM selection¶
| Variable | Default | Use it for |
|---|---|---|
LLVM_PREFIX |
auto-detected | Select an LLVM installation when the wrong clang, llvm-symbolizer, or sancov would otherwise be used. |
Homebrew LLVM and common Linux prefixes are detected automatically. Set this only on hosts with several installations:
Directed fuzzing¶
| Variable | Default | Use it for |
|---|---|---|
FUZZ_SEED_CORPUS_DIR |
unset | A local directory of extra seed inputs (an OSS-Fuzz or ClusterFuzz corpus you staged) to fill an empty S4 corpus alongside the target's own test data. Local only; nothing is fetched over the network. |
The path is read only when a harness's corpus is empty, and its inputs are bounded by the same size and count limits as the in-tree seeds.
FUZZ_SEED_CORPUS_DIR=/data/oss-fuzz-corpora/<project> bin/audit --target <target> --backend <backend>
Container runtime¶
bin/audit-container-shell has flags for its normal choices, and flags are
better in scripts because they are visible in the command under review.
| Variable | Flag equivalent | Purpose |
|---|---|---|
CONTAINER_RUNTIME |
--runtime |
Container CLI. The current helper accepts Docker. |
AUDIT_DOCKER_RUNTIME |
--docker-runtime |
OCI runtime passed to docker run; --gvisor selects runsc. |
AUDIT_FORWARD_CREDENTIALS |
--forward-credentials |
Set to 1 to forward supported credential variables and read-only Google ADC files into the container. Off by default. |
Inside the container helper, AUDIT_BUILD_SUFFIX is set for you so each image
gets its own build-asan-<image-id>/ tree, and IS_SANDBOX=1 is set because
the container is the boundary --agent-security external-bypass relies on.
bin/benchmark --isolate-build sets the suffix the same way, to
+bench-<input-hash>. Both are runtime state; do not set them by hand.
Build leases and source pins¶
Every process that executes a sanitizer build holds a shared lease on it, and every rebuild takes the matching exclusive one, so a build is never replaced while a run is using it. A run additionally pins the source state it is auditing, which is what catches two runs reading one checkout at different states, something a per-build lock cannot see.
Both are advisory kernel locks under targets/<slug>/.audit/
(build-locks/<build-dir>.lock and source-pins/<pid>.pin), released when
the holder exits and needing no cleanup. There is nothing to configure, and
they bind only harness commands; a build tool invoked by hand is outside them.
One-off probe selection¶
bin/probe normally uses the first enabled sanitizer in target.toml. For a
deliberate one-off comparison:
Valid values are asan, ubsan, msan, tsan, race, and runner, and
the sanitizer must be enabled for the target. Persistent policy belongs in
[sanitizer].enabled, not in the environment.
To compare ASan build configurations, select a ready named configuration or force the canonical control:
PROBE_BUILD_CONFIG=compact bin/probe .../scratch-1/testcase
PROBE_BUILD_CONFIG=primary bin/probe .../scratch-1/testcase
Normal audits assign this automatically, and a confirmed crash from an alternate build is compared against the primary without any override.
Probe output capture¶
bin/probe classifies a diagnostic before limiting its saved size. By
default, an output larger than 8 MiB is replaced with an explicit truncation
marker plus its first and last 256 KiB. For a deliberate full-capture rerun:
This can create a very large file. Use it only when the saved marker shows that the omitted middle contains context needed for review.