CLI Reference
Every command, flag, and resolution rule. Install and operate tracker from the terminal.
Install
# Go install (binary includes embedded workflows)
go install github.com/2389-research/tracker/cmd/tracker@latest
# Homebrew
brew install 2389-research/tap/tracker
# Or build from source
git clone https://github.com/2389-research/tracker
cd tracker && make install
# Verify installation
tracker doctor
# Stay current (checks automatically, or run manually)
tracker updateCommands
Running Pipelines
tracker <pipeline>build_product.dip, build.dipx), bare name (build_product), or path with slash. .dipx bundles are SHA-256-verified at load time and the bundle identity is threaded through every audit surface. .dipx v0.26.0 Opens TUI dashboard by default.tracker -r <id> <pipeline>-r 7813b is enough if unambiguous. A run that halted at a fail-closed dead end it reached by fail-routing (a node whose only continuation is the exit — e.g. build_product's Setup → AbortRun) rewinds to the node that failed, so fixing the cause and resuming retries that step instead of re-running the terminal. A fail-routed node with real onward routing (a Fix step that loops back to Test) is retried in place. --from <node> re-enters at an explicit node; --resume-no-rewind resumes exactly at the checkpoint's current node.tracker --no-tui <pipeline>tracker --json <pipeline>--no-tui. For CI/programmatic consumption.Workflow Management
tracker workflowsexplain, quickfix) come first, tagged ★ start here (WorkflowInfo.StartHere). v0.81.0tracker init <name>./name.dip in the current directory, together with its whole prompts/name/ and scripts/name/ subtrees (including sourced scripts/name/lib/ helpers, minus the *_test.sh fixture suites) plus every file its prompt_file / command_file directives reference elsewhere — the same set an embedded run materializes, so ${graph.workflow_dir} resolves the copy identically (and a starter SPEC.md for workflows that need one). Refuses to overwrite existing files.Validation & Simulation
tracker validate <pipeline>.dip, .dot, and .dipx bundles. .dipx v0.26.0tracker simulate <pipeline>tracker validate. Supports bare names. Accepts .dip, .dot, and .dipx bundles. .dipx v0.26.0tracker estimate <pipeline>build_product → $0.65–$10.02, expected ~$3.56). No LLM calls; supports bare names. A deliberately wide range — actual cost depends on how many turns each agent uses and how many times loops run. Reads only the config .env (like tracker version), never the current directory's, so the TRACKER_OPENAI_AUTH switch is visible to pricing; an openai node prices at $0 when it's set to chatgpt, noted in the output v0.80.0.tracker verify-tests [dir] [--race] [--coverage]dir (default cwd) and flags groups that are byte-for-byte identical or identical except for literal values, so a “distinct” test that copies another's body can't hand out false coverage credit. Exits 1 when any duplicate group is found — drop it into a VerifyMilestone tool node. With --race, also runs go test -race ./... and fails on a detected data race or a suite that won't pass under the race detector; the race pass is opt-in and Go-only — skipped (not failed) when there is no go.mod/go.work or no go toolchain, and reported as a skip when cgo or the race detector is unavailable on the platform. It also prints an advisory v0.69.0 structural near-duplicate report — reordered/renamed copies calling the same production symbols that the literal-strip hash misses — which never affects the exit code. With --coverage, an opt-in, advisory per-test coverage-attribution pass additionally flags tests that execute zero production code (assert on a copy / path guarded out) and test-local functions that re-implement uncovered production logic; it is heavyweight (one go test run per test), Go-only, skips cleanly like --race, and never fails the gate.Headless & Integration
tracker --webhook-url <url> <pipeline><url>; the pipeline blocks until a callback arrives at the local callback server. Slack bots, email approval, mobile push. Mutually exclusive with --autopilot and --auto-approve. v0.17.0tracker --param key=value <pipeline>vars (available as ${params.key}). Repeatable. Unknown keys hard-fail at startup. v0.19.0tracker --export-bundle <path> <pipeline>git bundle create --all). Clone with git clone <bundle> on any machine to inspect every commit and checkpoint tag. v0.17.0tracker --gateway-url <url> <pipeline>/anthropic, /openai, /google-ai-studio, /compat). Equivalent to TRACKER_GATEWAY_URL. Per-provider *_BASE_URL env vars still win. v0.17.0Autopilot
tracker --autopilot <persona> <pipeline>lax, mid (default), hard, mentor.tracker --auto-approve <pipeline>Diagnostics
tracker doctor [pipeline].ai/ writability, disk space, .gitignore hygiene, a warning when .env is tracked by git, and environment warnings with provenance (TRACKER_PASS_ENV=1 (from shell), TRACKER_GATEWAY_URL=… (from ~/.config/tracker/.env), and every name a .env file tried to set that its tier doesn’t allow, reported as ignored) v0.78.0. Live per-provider auth validation with a 1-token call runs by default; pass --probe=false to skip it. Under TRACKER_OPENAI_AUTH=chatgpt, the openai line reports the ChatGPT subscription sign-in instead — plan and signed-in state, plus a refreshed access token under the live probe, never OPENAI_API_KEY, OPENAI_BASE_URL or a gateway URL, and never the account ID or email v0.80.0. Its notes that those settings don’t apply to openai (a gateway still routes the other providers) and that dollar ceilings don’t count subscription calls are hints, so they never cause exit code 2. Also takes --backend (the agent backend to check), --git / --allow-init (evaluate a git preflight policy), --env-files, and -w / --workdir. Optional pipeline arg runs full lint and warns when a node pins a model that dippin marks retired on its first-party provider API (still billable via a Bedrock/Vertex passthrough) — suppressed when a gateway is configured (TRACKER_GATEWAY_URL/TRACKER_GATEWAY_KIND), since the model then routes to a passthrough. v0.63.0 Exit code 2 on warnings-only. v0.17.0 With a pipeline, the provider-key check passes when no agent node needs the native backend (all claude-code, or auto with claude available), and claude is required when a node needs it (#716). A missing dippin binary is a warning: it is only needed to lint or edit .dip files. Bare tracker doctor with Claude Code and no API key warns instead of failing and says which workflows need a key; doctor --backend claude-code with no pipeline passes. Doctor shows the resolved claude path and its source (TRACKER_CLAUDE_BIN or PATH), warns when several claude binaries are on PATH (listing each version), and fails on a broken TRACKER_CLAUDE_BIN when a node needs claude. v0.81.0tracker diagnose [runID]status.json + activity.jsonl. Shows tool output, stderr, errors, timing anomalies, actionable suggestions (deterministic failure pattern, escalation hit, suspicious timing, budget halt). Without ID, analyzes the most recent run.tracker status [runID]tracker audit <runID>tracker listtracker run-json [runID]run.json manifest for a run directory from its captured audit log — goal, terminal status, per-node kind/attempts/outcome/turns/usage, run totals, tool-call and event counts, and spec identity. v0.50.0 Works after the fact, so a SIGKILLed run (which ran no in-process finalizer) or a run archived before the manifest existed both get one. Without an ID, targets the most recent run.Setup
tracker setup~/.config/tracker/.env. OpenAI's page has an Auth choice v0.80.0: API key, or ChatGPT subscription, which signs in with a device code — open the link setup shows on any device and enter the code within 15 minutes. Setup saves the sign-in to ~/.config/tracker/chatgpt-auth.json (mode 0600) and writes TRACKER_OPENAI_AUTH=chatgpt; picking API key later writes api-key. Sign in only with your own ChatGPT account, on your own machine.tracker version~/.config/tracker/.env only — this command never loads a .env from the current directory v0.78.0.tracker update.bak rollback. Detects Homebrew and go install and advises accordingly.Flags
Flags can appear before or after the pipeline argument.
| Flag | Description | Default |
|---|---|---|
| Execution | ||
-w, --workdir | Working directory for the pipeline run | Current directory |
-r, --resume | Resume a previous run by ID (prefix match). If the run halted at a fail-closed dead end it reached by fail-routing, resume rewinds to the node that failed | — |
--from | With -r: re-enter the run at this node, re-running it and everything downstream. Must be a node the run reached (completed or current); refused otherwise | — |
--resume-no-rewind | With -r: resume exactly at the checkpoint's current node (no automatic rewind past a fail-closed terminal) | Off |
--force-bundle-mismatch | Allow resume when the .dipx bundle identity differs from the original run | Off |
--git | Git preflight policy: auto (default) | off | warn | require | init | auto |
--allow-init | Latch permitting --git init to initialize a repo in the working directory | Off |
--artifact-dir | Override node state directory v0.19.0. -r looks the run up here and fails if it is not there, so resume with the same --artifact-dir (and -w) the run used; the printed resume command includes both | Derived from run |
--param | Override workflow vars (repeatable): --param key=value v0.19.0 | — |
--format | Pipeline format override: dip or dot | Auto-detect from extension |
--backend | Agent backend: native, claude-code, or acp. An explicit value also overrides backend: auto nodes; auto itself is a node value only (--backend auto is rejected). | native |
| Output | ||
--json | Stream events as NDJSON to stdout | Off |
--no-tui | Disable TUI dashboard, use console mode | TUI on (if TTY) |
--verbose | Show raw provider stream events | Off |
--export-bundle | After the run, write a portable git bundle of run artifacts to the given path v0.17.0 | — |
| Gate handling | ||
--autopilot | LLM judge persona: lax, mid, hard, mentor | Off (human gates) |
--autopilot-model | Model the --autopilot judge uses for gate decisions; requires --autopilot. Set it to a model your ChatGPT plan serves when TRACKER_OPENAI_AUTH=chatgpt v0.80.0 | The default provider's autopilot model |
--auto-approve | Deterministic auto-approve (no LLM) | Off |
--webhook-url | POST gate prompts to this URL and wait for callback v0.17.0 | — |
--gate-callback-addr | Local addr for the inbound callback server | :8789 |
--gate-timeout | How long to wait for a webhook callback per gate | 10m |
--gate-timeout-action | What to do on gate timeout: fail or success | fail |
--webhook-auth | Authorization header on outbound webhook POSTs | — |
| Budget ceilings v0.17.0 | ||
--max-tokens | Halt if total tokens exceed this | — |
--max-cost | Halt if total cost (cents) exceeds this | — |
--max-wall-time | Halt if wall-clock runtime exceeds this (e.g. 30m) | — |
--sleep-aware-budget | Exclude detected OS-suspend spans (e.g. a closed laptop) from --max-wall-time and stall budgets | off |
| Provider routing & tool safety | ||
--gateway-url | Route every provider through a Cloudflare AI Gateway root URL; equivalent to TRACKER_GATEWAY_URL. See the gateway routing guide for the AWS Bedrock recipe. v0.17.0 | — |
--gateway-kind | Gateway path convention: cf-aig (default) or bedrock | cf-aig |
--tool-allowlist | Restrict tool commands to glob patterns. Repeatable; each value can be a comma-separated list. Additive with the tool_commands_allow graph attr. Never overrides the denylist. v0.23.0 | — |
--tool-denylist-add | Extend the built-in tool-command denylist with extra glob patterns. Repeatable; each value can be a comma-separated list. Additive only — cannot remove built-ins. Pairs with the tool_denylist_add graph attr. --bypass-denylist still disables everything. v0.24.1 | — |
--bypass-denylist | Disable the built-in denylist for dangerous tool commands (eval, pipe-to-shell, curl | sh). Loud stderr warning on startup. Use only in sandboxed environments where dangerous patterns are intentional. v0.23.0 | Off |
--max-output-limit | Hard ceiling (bytes) on per-stream tool output size; caps per-node output_limit attrs. When a stream exceeds its cap, tracker keeps the tail (last limit bytes) so routing markers like printf 'tests-pass' emitted at end-of-output survive truncation. tracker diagnose surfaces a tool_output_truncated suggestion. v0.23.0 tail-window v0.27.0 | 0 (effective 10 MB) |
--env-files | Which .env files tracker run / tracker doctor load: all (config file, then project file), config (~/.config/tracker/.env only), or none. The shell-only TRACKER_ENV_FILES is the env equivalent; the flag wins. See Environment variables for what each file may set. v0.78.0 | all |
| Exit codes | ||
--fail-on-override | Exit code 2 when the run terminates as validation_overridden. Default behavior exits 0 (an override is a deliberate operator decision). Equivalent to TRACKER_FAIL_ON_OVERRIDE=1; the flag wins. See the Exit codes section. v0.35.0 | Off |
| Misc | ||
--help | Common flags only — the short reference for everyday runs | — |
--help-all | Full flag reference, grouped by concern (budget, gateway, gates, artifacts, tool safety) v0.66.0 | — |
--version | Show version info | — |
Exit codes v0.35.0
tracker run uses three distinguishable exit codes so CI integrations can branch on terminal status without parsing stdout.
| Code | Meaning |
|---|---|
0 | Run completed. Terminal status is either success or validation_overridden. |
1 | Run failed or was halted by a budget guard. Terminal status is fail or budget_exceeded. |
2 | Run completed as validation_overridden and --fail-on-override (or TRACKER_FAIL_ON_OVERRIDE=1) was set. Lets CI distinguish operator-accepted overrides from clean successes without scraping output. |
Generic failures dominate --fail-on-override: a run that fails after an override exits 1, not 2. Without the flag, override runs exit 0 — an override is a deliberate operator decision and the default treats it as audit-positive. CI pipelines that should NOT auto-deploy on overrides must opt in:
tracker --fail-on-override workflow.dip && deploy.shTool safety in pipeline files v0.23.0
The denylist, allowlist, and per-stream output ceiling are enforceable from a pipeline file as well as CLI flags. CLI values and graph attrs union; the denylist always wins.
| Graph attribute | Notes |
|---|---|
tool_commands_allow | Comma-separated globs restricting every tool node's command to match at least one pattern. Unions with --tool-allowlist; cannot override the denylist. |
tool_denylist_add | Comma-separated globs added to the built-in denylist for every tool node. Unions with --tool-denylist-add; strictly additive (cannot remove built-ins). v0.24.1 |
Example, DOT form:
digraph G {
// Only git and make commands are allowed in tool nodes.
graph [tool_commands_allow="git *,make *"];
Setup [handler="tool", tool_command="git init"];
Build [handler="tool", tool_command="make build"];
Setup -> Build;
}As of dippin-lang v0.23.0+, both attributes are exposed via a defaults: block
in a .dip file (defaults: tool_commands_allow: "git *,make *"). The DOT form above and the
library API (graph.Attrs["tool_commands_allow"]) remain equivalent ways to set them.
Name resolution
When you run tracker build_product (bare name, no path, no extension), the resolver
checks in this order:
Explicit file path
If the name contains
/or ends in.dip/.dot/.dipx, treat as a filesystem path. No further resolution.Local .dip file
Check if
build_product.dipexists in the current directory. Local files always win.Bare file
Check if
build_productexists as a file in the current directory.Embedded workflow
Look up
build_productin the built-in workflow catalog. If found, load fromgo:embed.Error
Print "unknown pipeline" with a list of available built-in workflows.
This applies uniformly to tracker run, tracker validate, and tracker simulate.
Environment variables
Provider keys
| Variable | Provider | Notes |
|---|---|---|
ANTHROPIC_API_KEY | Anthropic | Required for claude-* models |
ANTHROPIC_BASE_URL | Anthropic | Custom endpoint (proxies, etc.) |
OPENAI_API_KEY | OpenAI | Required for gpt-*, o* models |
OPENAI_BASE_URL | OpenAI | Custom endpoint |
GEMINI_API_KEY | Gemini | Required for gemini-* models |
GOOGLE_API_KEY | Gemini | Alternative to GEMINI_API_KEY |
GOOGLE_BASE_URL | Gemini | Not read by Tracker; stripped from claude and (with TRACKER_STRIP_ACP_KEYS=1) ACP children with the other base URLs |
OPENROUTER_API_KEY | OpenRouter | Not read by Tracker; stripped from ACP children with TRACKER_STRIP_ACP_KEYS=1 |
GEMINI_BASE_URL | Gemini | Custom endpoint |
OPENAI_COMPAT_API_KEY | OpenAI-compat | Required for the openai-compat provider (any OpenAI-compatible endpoint) |
OPENAI_COMPAT_BASE_URL | OpenAI-compat | Endpoint for the openai-compat provider. Unset, the adapter default is OpenRouter (https://openrouter.ai/api). Like every per-provider *_BASE_URL, it wins over TRACKER_GATEWAY_URL. |
Variables come from three sources with different trust, and each source may set only the names its trust allows (v0.78.0, env trust policy):
- Shell environment — may set anything; a shell value is never overwritten by a file.
~/.config/tracker/.env(XDG config; written bytracker setup) — provider*_API_KEYs, per-provider*_BASE_URLs,TRACKER_GATEWAY_URL/TRACKER_GATEWAY_KIND,TRACKER_OPENAI_AUTH, and the cost / UX knobs (TRACKER_ACP_CACHE_READ_RATIO,TRACKER_DEBUG,TRACKER_NO_NOTIFY,TRACKER_NO_UPDATE_CHECK,TRACKER_HERDR,TRACKER_CODEGEN_*,TRACKER_SPRINT_WRITER_*)..envin the working directory — provider*_API_KEYs only. Any committer, a prior unjailed agent, or a model-run command can write this file, so it cannot pick endpoints or flip switches. For a key both files set, the project file wins.
Every other name — TRACKER_PASS_ENV, TRACKER_PASS_API_KEYS, TRACKER_STRIP_ACP_KEYS, TRACKER_CLAUDE_BIN,
TRACKER_FAIL_ON_OVERRIDE, TRACKER_AUDIT_DIR, XDG_STATE_HOME, HERDR_*,
PATH, HTTPS_PROXY, SSL_CERT_FILE, LD_PRELOAD, and any name tracker does not read —
is shell-only: a file that sets one is skipped for that key with a single stderr line naming the file, the key and
where it belongs, and tracker doctor lists the attempt. A symlinked .env and a group/world-writable
.env (config or project) are skipped whole. tracker version reads the config file only, never the current directory.
The full registry is internal/envpolicy in the source tree.
Tracker runtime knobs
| Variable | Default | Notes |
|---|---|---|
TRACKER_GATEWAY_URL | — | Equivalent to --gateway-url. Tracker appends per-provider suffixes (/anthropic, /openai, /google-ai-studio, /compat). Per-provider *_BASE_URL still wins. v0.17.0 |
TRACKER_GATEWAY_KIND | cf-aig | Equivalent to --gateway-kind: the gateway path convention, cf-aig (Cloudflare AI Gateway suffixes) or bedrock. The flag wins. Config .env or shell. v0.36.0 |
TRACKER_OPENAI_AUTH | api-key | openai auth mode: api-key (default) or chatgpt — bill openai calls to your ChatGPT subscription after signing in with tracker setup. Config .env or shell. v0.80.0 |
TRACKER_CLAUDE_BIN | unset | Absolute path of the claude binary for every claude-code use: --backend claude-code, backend: claude-code / auto nodes, the claude-code autopilot and tracker doctor. Overrides the PATH lookup, so a stale claude earlier on PATH no longer wins (#719). It must be an executable file; a wrong value fails with its path and never falls back to PATH (under backend: auto the node refuses to start instead of moving to an API key). Every run names the binary it used, and tracker doctor warns when several claude binaries are on PATH. Shell-only: a .env file cannot set it. v0.81.0 |
TRACKER_PASS_API_KEYS | unset | --backend claude-code only (and the claude-code autopilot). Set to exactly 1 to keep Tracker's five provider keys (ANTHROPIC_API_KEY, OPENAI_API_KEY, OPENAI_COMPAT_API_KEY, GEMINI_API_KEY, GOOGLE_API_KEY) and their base URLs (ANTHROPIC_BASE_URL, OPENAI_BASE_URL, OPENAI_COMPAT_BASE_URL, GEMINI_BASE_URL, GOOGLE_BASE_URL) in the claude subprocess env. By default exactly those ten names are removed so the CLI bills to Max/Pro subscription auth instead of the API key, and doesn’t send that login to a gateway set for the native backend (#677). Routing claude through a gateway on purpose takes this switch: key and base URL together. This is a billing control, not a confinement boundary: every other variable passes through, and the Bash commands, hooks and MCP servers claude starts inherit what claude received (see CLAUDE_CODE_SUBPROCESS_ENV_SCRUB). The ACP backend does not read this variable — see TRACKER_STRIP_ACP_KEYS. Shell-only: a .env file cannot set it. v0.13.0 |
TRACKER_STRIP_ACP_KEYS | unset | --backend acp only. Set to exactly 1 to remove eleven provider key and base-URL names (ANTHROPIC_API_KEY, OPENAI_API_KEY, OPENAI_COMPAT_API_KEY, GEMINI_API_KEY, GOOGLE_API_KEY, OPENROUTER_API_KEY, ANTHROPIC_BASE_URL, OPENAI_BASE_URL, OPENAI_COMPAT_BASE_URL, GEMINI_BASE_URL, GOOGLE_BASE_URL) from the ACP agent process and its --version probe. The default is full passthrough of Tracker's environment, because ACP bridges route their own credentials. The strip is exact-name: other credentials pass through in both modes. Terminal commands the agent asks Tracker to run get the TRACKER_PASS_ENV scrub, and this switch also strips its eleven names from them, even when TRACKER_PASS_ENV=1. v0.17.0 |
TRACKER_PASS_ENV | unset | Set to 1 to disable the sensitive-env scrub on tool subprocesses, native-backend agent bash commands, verify commands, ACP terminal commands and git subprocesses (names containing _API_KEY, _SECRET, _TOKEN, _PASSWORD; DOCKER_AUTH_CONFIG; and, under any name, a value that is a URL with a password, an http(s) URL with any userinfo, or a Docker auths JSON blob — #679). Proxy variables (HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, FTP_PROXY, NO_PROXY) skip the value check so commands behind an authenticated proxy keep network access. Default scrubs them out. Use only when a tool genuinely needs a secret. Shell-only: a .env file cannot set it. |
CLAUDE_CODE_SUBPROCESS_ENV_SCRUB | unset | --backend claude-code only. Read by Claude Code, not tracker: export 1 to have Claude Code strip credentials from the Bash commands, hooks and stdio MCP servers it starts, while claude keeps them for its own API calls. Tracker passes it through but never sets it. Claude Code's rule keeps GITHUB_TOKEN, GH_TOKEN and proxy settings. With Claude Code 2.1.280 under bypassPermissions (tracker's default for claude-code nodes), it also made claude refuse commands with $VAR expansions, env, sh -c and listings outside the working directory. A refused call fails a node left on that default (#676). Shell-only: a .env file cannot set it. |
TRACKER_ENV_FILES | all | Shell-only equivalent of --env-files: all loads the config .env then the project .env, config loads only ~/.config/tracker/.env, none loads neither. An explicit flag wins; an unknown value is an error. Cannot itself be set from a .env file. v0.78.0 |
TRACKER_FAIL_ON_OVERRIDE | unset | Set to exactly 1 (strict parsing) to exit code 2 when a run terminates as validation_overridden. Equivalent to --fail-on-override; the CLI flag wins when both are present. v0.35.0 |
TRACKER_SPRINT_WRITER_MODEL | unset (tool disabled when unset; the configured model name is used directly) | Model used by the write_enriched_sprint agent-runtime tool. When set, the tool registers, together with dispatch_sprints, in the native backend's tool registry. Pair with TRACKER_CODEGEN_MODEL for the full architect-side flow. v0.25.0 |
TRACKER_SPRINT_WRITER_PROVIDER | anthropic | Provider the write_enriched_sprint tool calls TRACKER_SPRINT_WRITER_MODEL on. Read only when that model is set. v0.25.0 |
TRACKER_CODEGEN_MODEL | unset (tool disabled when unset; the configured model name is used directly) | Model used by the generate_code tool to expand a contract into files. v0.25.0 |
TRACKER_CODEGEN_PROVIDER | openai | Provider the generate_code tool calls TRACKER_CODEGEN_MODEL on. Read only when that model is set. v0.25.0 |
TRACKER_RUN_ID / TRACKER_RUN_DIR / TRACKER_WORKDIR | set by tracker | Outputs, not inputs: tracker injects these into every locally-executed tool subprocess — the run ID, the absolute per-run artifact dir, and the absolute workdir — so a tool can cat "$TRACKER_RUN_DIR/<NodeID>/response.md" for an upstream agent's output. The run dir exists before the first node runs, so a start tool node can write into it. Operator-exported values of these names are overridden, never inherited. Present on the TRACKER_PASS_ENV=1 path too. v0.37.0 A tool node that writes $TRACKER_RUN_DIR/notice.txt leaves the user an end-of-run message, printed after the run summary (TUI and console; 4 KiB max, control characters stripped). v0.81.0 |
TRACKER_ACP_CACHE_READ_RATIO | unset | ACP cost estimate only. A fraction in (0, 1] of the estimated input tokens priced as cache reads instead of fresh input. The cache-read rate is model-specific — it comes from the model's catalog entry (e.g. gpt-4.1 and gpt-4o price cached input at 0.25× / 0.5×), falling back to 10% of the input rate only for models the catalog has no cache rate for. Unset, non-numeric or out-of-range values price all estimated input as fresh (no cache discount; the estimate can still be low, since it never sees the bridge’s own system prompt and tool schemas) and log one warning. v0.24.1 |
TRACKER_AUDIT_DIR | — | Absolute path that replaces the base directory of the secure run state: the live activity log and the authoritative checkpoint.json land under <dir>/<runID>/. A relative value is silently ignored so the working directory can never re-anchor the log. v0.28.0 |
XDG_STATE_HOME | ~/.local/state | When TRACKER_AUDIT_DIR is unset and this is an absolute path, the secure run state lives under $XDG_STATE_HOME/tracker/runs/<runID>/. Relative values are ignored. On Windows %LOCALAPPDATA%\tracker\runs is tried next. v0.28.0 |
XDG_CONFIG_HOME | ~/.config | Location of the config env file $XDG_CONFIG_HOME/tracker/.env. tracker setup writes it; tracker run and tracker doctor read it (after the shell, before the workdir .env); tracker version and tracker estimate read only this file, never the workdir .env. No other subcommand loads either .env file. A relative value is ignored, with a notice, and $HOME/.config is used. |
TRACKER_DEBUG | unset | Any non-empty value makes the Anthropic adapter log a 200-byte preview of the raw response body when a response comes back empty (0 output tokens, no text, no tool calls). |
TRACKER_NO_NOTIFY | unset | Any non-empty value disables desktop notifications (osascript on macOS, notify-send on Linux). v0.13.0 |
TRACKER_NO_UPDATE_CHECK | unset | Any non-empty value skips the background update check that tracker run performs. The check is also skipped when CI is set and in dev builds. v0.12.0 |
HERDR_ENV / HERDR_PANE_ID / HERDR_BIN_PATH | set by Herdr | Injected by a Herdr terminal pane. When HERDR_ENV=1 and both HERDR_PANE_ID and HERDR_BIN_PATH are set, tracker reports its run lifecycle (working / blocked / idle) to that pane by invoking the herdr CLI at HERDR_BIN_PATH. If any of the three is missing, reporting is a no-op. v0.76.0 |
TRACKER_HERDR | unset | Set to 0 to opt out of Herdr reporting even inside a Herdr pane. v0.76.0 |
Autopilot mode
Run pipelines fully autonomous. Human gates are answered by an LLM judge with a configurable decision-making persona.
# Balanced judgment (default persona)
tracker --autopilot mid build_product
# Move fast, approve everything reasonable
tracker --autopilot lax build_product
# High quality bar — pushes back on gaps
tracker --autopilot hard build_product
# Approves but writes detailed feedback
tracker --autopilot mentor build_product
# Deterministic auto-approve — no LLM, for CI
tracker --auto-approve build_productPersonas
| Persona | Approval Bias | Reasoning Style | Best For |
|---|---|---|---|
lax | Strong approve | Brief: "Looks fine, moving on" | Demos, prototypes, overnight runs |
mid | Balanced | Concise: one paragraph | General-purpose unattended runs |
hard | Prefers retry/adjust | Detailed: cites specific gaps | Pre-release quality sweeps |
mentor | Approve with notes | Verbose: 3-5 sentences of feedback | Learning, review artifacts |
How It Works
Gate Reached
Pipeline hits a human gate (ApprovePlan, EscalateMilestone, etc.)
LLM Consulted
The autopilot sends the gate's prompt, context, and available options to the LLM with the persona's system prompt.
Structured Response
LLM returns
{"choice": "approve", "reasoning": "..."}. Choice is matched against edge labels.Fallback on Error
If the LLM fails or returns an unmatchable choice, the default edge is taken with a warning.
Design Note
The autopilot reuses the pipeline's existing LLM client — no separate configuration. It picks the cheapest model from the configured default provider (falling back to claude-sonnet-4-6 if none is set) for cheap, fast gate decisions. All decisions are logged to the activity log for post-hoc review via tracker diagnose.
Agent backends
Three backends, one pipeline. Native is the default and works with every provider. Claude Code gives agents file editing,
terminal access, and MCP tool servers (subscription auth, no API key needed). ACP bridges tracker to third-party coding
agents like claude-agent-acp, codex-acp, and gemini --acp via JSON-RPC over stdio.
Side-by-Side Comparison
| Native (default) | Claude Code v0.12.0 | ACP v0.16.0 | |
|---|---|---|---|
| How it works | Wraps agent.Session — tracker's built-in turn loop | Spawns claude CLI as a subprocess, parses NDJSON output | Spawns ACP-compatible agents via JSON-RPC 2.0 over stdio |
| Providers | Anthropic, OpenAI, Gemini, OpenAI-compat | Anthropic (via Claude CLI) | Routed to matching ACP binary per provider |
| Tool access | Tracker's registered tool set; tool_access: read_only keeps exactly read / grep_search / glob (symlinks out of the workdir and secret-looking files refused) | File editing, terminal, MCP servers; read_only: --tools Read,Glob,Grep, dontAsk, --strict-mcp-config, --setting-sources user | Full agent toolset (file ops, terminal via ACP); refuses read_only |
| Best for | Standard LLM calls, multi-provider pipelines, cross-review | Implementation nodes that need file editing + terminal | Hosting third-party ACP coding agents inside a tracker pipeline |
| Environment | The agent's bash tool and verify commands get exec.CommandEnv: Tracker's environment minus names containing _API_KEY, _SECRET, _TOKEN or _PASSWORD, minus DOCKER_AUTH_CONFIG, and minus credential-bearing values such as a URL with a password (#679); TRACKER_PASS_ENV=1 passes everything. v0.77.0 Not native-only: workflow tool nodes get the same CommandEnv and git subprocesses the same credential patterns (gitSafeEnv, which also drops GIT_DIR-class redirect variables unconditionally) under every backend — only the agent process itself differs per column. | Full environment minus Tracker's five provider keys (ANTHROPIC_API_KEY, OPENAI_API_KEY, OPENAI_COMPAT_API_KEY, GEMINI_API_KEY, GOOGLE_API_KEY) and their *_BASE_URLs so the CLI bills to subscription auth; TRACKER_PASS_API_KEYS=1 keeps them. claude's own Bash/hooks/MCP children inherit the rest unless the operator exports CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1. | Agent process: full environment by default (bridges route their own credentials); TRACKER_STRIP_ACP_KEYS=1 strips eleven provider key / base-URL names. Terminal commands the agent asks Tracker to run get exec.CommandEnv, like native bash, with TRACKER_STRIP_ACP_KEYS=1 applied on top. |
| Error mapping | Provider HTTP status + SSE events | Claude CLI exit codes → pipeline outcomes; a result listing permission_denials fails a node left on bypassPermissions with no tool_access / disallowed_tools, even on exit 0 (#676) | ACP JSON-RPC error codes → pipeline outcomes |
| Per-node override | backend: native (or auto, when claude isn’t available) | backend: claude-code (or auto, when claude answers) | backend: acp + optional acp_agent: |
When to Use Which
Use Native When
- Your agents make standard LLM calls (analysis, planning, review)
- You need multi-provider pipelines (Claude + GPT + Gemini)
- Cross-review nodes that compare outputs from different models
- You want the fastest possible execution
Use Claude Code When
- Agents need to edit files on disk (implementation, fix nodes)
- Agents need terminal access (run tests, build commands)
- You want MCP tool servers available to agents
- You want Claude's built-in code intelligence
Usage
# Global: every agent node uses Claude Code
tracker --backend claude-code build_product
# The killer combo: autonomous + Claude Code
tracker --backend claude-code --autopilot mid build_product
# Native is the default — no flag needed
tracker build_product
# No flag and no API key: the starters use backend: auto (Claude Code if installed)
tracker explain --param question="what does this repo do?"Per-Node Selection in .dip
Mix backends within a single pipeline. Use Claude Code for implementation, native for everything else. Per-node backend: attrs always override the global --backend flag. backend: auto picks your Claude subscription when claude is installed (outside the working directory and answering --version), otherwise a configured API key, once per run, and announces the choice; an explicit --backend wins over it, and a resume reuses the recorded choice. With every agent node on auto, claude-code or acp, no API key is needed to start. tool_access: read_only limits a node to reading: read / grep_search / glob on the native backend (secrets and paths outside the workdir refused), --tools Read,Glob,Grep with dontAsk on Claude Code; ACP refuses it.
agent Implement
label: "Build the feature"
model: claude-sonnet-5
backend: claude-code
prompt: |
Implement milestone ${ctx.current_milestone} following SPEC.md.
agent Review
label: "Review the implementation"
model: gpt-5.4
provider: openai
# No backend attr — uses native (default)
prompt: |
Review the implementation for correctness and style.The acp backend (v0.16.0+) spawns ACP-compatible coding agents as subprocesses via JSON-RPC over stdio
(claude-agent-acp, codex-acp, gemini --acp). Override the chosen binary per-node via
the acp_agent node attribute.
Companion binaries
Two binaries ship alongside tracker but are not part of the product CLI — they
verify and benchmark the engine. tracker-conformance pins engine behavior against version drift;
tracker-swebench evaluates the agent against SWE-bench. For how these fit into tracker's
verification story, see How we verify tracker.
tracker-conformance v0.47.0+
Emits a normalized, deterministic golden trace of an example workflow — event sequence, per-node
SessionStats, aggregate UsageSummary, and terminal status/class — via a stub
completer (no API keys, no wall-clock noise). The committed goldens are versioned in lockstep with the
tracker tag, so a downstream port pins a version and diffs for any engine-behavior drift.
This binary is a GoReleaser-published release asset for exactly that reason.
tracker-conformance golden <fixture.dip>cmd/tracker-conformance/testdata/golden/*.golden.json; regenerate after an intentional engine change with go test ./cmd/tracker-conformance -run TestGoldenTraces -update-golden.tracker-swebench v0.18.0+
Evaluates tracker's agent against the SWE-bench dataset. Orchestrates
per-instance Docker containers, a dataset JSONL parser, a resumable results writer, and an in-container
agent-runner that captures changes via git diff.
tracker-swebench --dataset <path.jsonl> [flags]--model, --provider, --gateway-url, --max-turns, --timeout, --instance, --results-dir, --docker-image, and forwarding of CF_AIG_TOKEN through the container for gateway auth.tracker-swebench analyze <results-dir>predictions.jsonl + run logs + empty-patch diagnostics and emits overall resolved/unresolved/empty/error counts, per-repo breakdown, top-10 empty-patch and longest-unresolved instances, and error-class distribution. Auto-detects SWE-bench evaluator resolved_ids; gracefully degrades when no evaluator report is present. v0.22.0# Analyze a completed run, pretty-printed
tracker-swebench analyze ./swebench-results/
# Structured JSON for downstream tooling
tracker-swebench analyze ./swebench-results/ --json > report.json
# Evaluate predictions against a specific ID file
tracker-swebench analyze ./swebench-results/ --predictions preds.jsonlTroubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| "no LLM providers configured" | Missing API keys | tracker setup or export env vars — or install and sign in to Claude Code (npm i -g @anthropic-ai/claude-code && claude /login): workflows whose agent nodes are all auto / claude-code (e.g. explain, quickfix) need no key |
An old or wrong claude runs (e.g. unrecognized_model) | Another claude is earlier on PATH | tracker doctor lists every claude on PATH with its version; set TRACKER_CLAUDE_BIN=/absolute/path/to/claude in the shell |
| “this run resolved backend: auto to …, which is no longer available” | A resume found the recorded backend gone | Restore that backend, or resume with --backend to switch deliberately; a resume never switches on its own |
| TestMilestone instantly escalates | Stale fix_attempts counter | rm .ai/milestones/fix_attempts |
| Node fails with no visible error | Tool stderr not surfaced | tracker diagnose shows full output |
| Pipeline loops forever | Unconditional fallback to loop target | Route fallbacks to escalation gates or Done |
Run halted with budget_exceeded | Hit --max-tokens / --max-cost / --max-wall-time | tracker diagnose prints the per-provider breakdown and the dimension that tripped |
| Tool retries same error 5 times | Deterministic command bug | tracker diagnose flags it — fix the command in the .dip file |
Diagnose intelligence
tracker diagnose doesn't just dump errors — it analyzes failure patterns
and generates actionable suggestions.
Deterministic Failure Detection
When a tool node fails multiple retries with identical errors, diagnose recognizes it as a deterministic bug in the command — not a transient issue that retrying might fix. This saves users from wading through 5 identical stack traces to realize the command itself is wrong.
✗ T1Init
Handler: tool
Duration: 3.2s
Attempts: 5 failures (all identical — deterministic)
Output:
The workspace name "." is invalid.
Workspace names must start with a letter.
─── Suggestions ───────────────────────────────────────────
→ T1Init: Failed 5 times with identical errors — this is a
deterministic bug in the command, not a transient failure.
Retrying won't help. Fix the tool command in the .dip file
and re-run.All Detection Patterns
| Pattern | Detection | Suggestion |
|---|---|---|
| Identical retries | Same error signature across 2+ failures | Deterministic bug — fix the command |
| Varying retries | 3+ failures with different errors | Flaky command or environment issue |
| Escalation hit | ESCALATE + fix attempts in output | Reset counter: rm .ai/milestones/fix_attempts |
| Silent failure | No stdout, stderr, or errors captured | Check activity.jsonl manually |
| Missing command/file | command not found or No such file | Check working directory and tool availability |
| Go test failures | FAIL + go test in output | Check known_failures exclusion list |
| Suspiciously fast | <50ms for non-tool nodes | Configuration issue or missing handler |
Quick reference
The commands you'll use most, at a glance.
# First time (Claude Code signed in: no API key needed)
tracker explain --param question="what does this repo do?"
tracker quickfix --param change="fix the README typo"
tracker setup # configure API keys interactively (no Claude Code)
tracker doctor # check setup: keys, claude, tools
# Run pipelines
tracker build_product # built-in workflow, no file needed
tracker my_pipeline.dip # local file
tracker --autopilot mid build_product # fully autonomous
tracker --backend claude-code my.dip # agents use claude CLI
# Full YOLO — Claude Code agents, autopilot gates, TUI dashboard
tracker --backend claude-code --autopilot lax build_product
# After a run
tracker diagnose # analyze most recent failure
tracker audit <runID> # full audit trail
tracker list # recent runs
# Manage pipelines
tracker workflows # list built-in workflows
tracker init build_product # copy to cwd for editing
tracker validate my.dip # lint + structure check
tracker simulate my.dip # dry-run all paths
tracker verify-tests . --race # flag duplicate tests + race check
# Maintenance
tracker update # self-update to latest release
tracker version # version + configured providers