# Configuration, models, and cost This page is the reference for reviewer models, usage limits, repository policy, and file exclusions. For the first-run path, see the [README](../README.md). - [Settings locations](#settings-locations) - [Reviewer models](#reviewer-models) - [Routing and question counts](#routing-and-question-counts) - [Model calls, tokens, and limits](#model-calls-tokens-and-limits) - [Repository policy](#repository-policy) - [Project context](#project-context) - [Files Sphinx never reads](#files-sphinx-never-reads) - [Background preparation](#background-preparation) ## Settings locations | What | Where | | --- | --- | | Machine-wide settings | `~/.config/sphinx/config.json` | | OpenRouter key and OpenAI-compatible endpoint | `~/.config/sphinx/credentials.json` (mode `0600`) | | Machine-wide ignore patterns | `~/.config/sphinx/ignore` | | Skip and yolo log | `~/.config/sphinx/overrides.jsonl` | | Repository policy | `.sphinxconfig` (legacy `.sphinx.json` is read when `.sphinxconfig` is absent) | | Repository exclusions | `.sphinxignore` | | Project context | `.sphinxcontext.md` | `SPHINX_HOME` relocates all machine-wide settings, credentials, and assessment state. `sphinx config` shows effective settings and paths. A complete global example using the paid Haiku preset is in [examples/config.json](../examples/config.json). Model routes, credentials, and usage limits are machine-wide only. A repository cannot redirect review to another provider, supply credentials, or raise your limits. ## Reviewer models Sphinx picks one of three saved routes (small, medium, large) for each change. Presets fill all three; you can change them at any time without reinstalling: ```sh sphinx config --preset claude-economy sphinx config --preset openrouter-value --allow-paid sphinx config --small claude:haiku --medium claude:haiku --large claude:sonnet ``` | Preset | Small and medium | Large | Usage source | | --- | --- | --- | --- | | `codex-economy` | `codex:gpt-6-luna` | `codex:gpt-6-luna` | Your Codex CLI account | | `claude-economy` | `claude:haiku` | `claude:haiku` | Your Claude CLI account | | `openrouter-value` (experimental) | `openrouter:anthropic/claude-haiku-5.5` | `openrouter:anthropic/claude-haiku-5.5` | Paid OpenRouter credits | | `openrouter-deepseek` (experimental) | `openrouter:deepseek/deepseek-v3.2` | `openrouter:deepseek/deepseek-v3.2` | Paid OpenRouter credits | | `openrouter-free` | `openrouter:openrouter/free` | `openrouter:openrouter/free` | OpenRouter free availability and limits | Unattended installation needs an explicit preset or route; Sphinx does not silently choose a free model: ```sh sphinx install --yes --preset codex-economy sphinx install --yes --preset claude-economy sphinx install --yes --preset openrouter-value --allow-paid ``` Reinstalling keeps saved routes unless you choose a replacement. Updating Sphinx does not migrate saved routes. Changing a route invalidates prepared questions and completion records made under the previous route. ### Codex and Claude routes These use your signed-in Codex or Claude CLI and consume that account's allowance. You need a recent CLI with access to the selected model; see [Codex models](https://learn.chatgpt.com/docs/models) and [Claude model configuration](https://code.claude.com/docs/en/model-config). The economy presets keep the same economical model for all tiers; investigation effort and question count still scale with change size. The Claude `haiku` alias follows the available Haiku model. Neither preset upgrades to a more expensive model. **These routes bill your signed-in plan by default.** Sphinx removes `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `CODEX_API_KEY`, and similar variables from the reviewer CLI's environment, so a key in your shell cannot silently switch reviews to API credits. If the CLI is not signed in with a Claude or ChatGPT plan, the check stops with instructions. To let the CLIs use API keys instead, run `sphinx config --cli-billing api`. Each call is a fresh, isolated CLI invocation used as a model transport underneath the embedded [Pi SDK](https://pi.dev/docs/latest/sdk) reviewer. It does not reuse your coding conversation. See [architecture](architecture.md#independent-investigation-and-compaction). Pi, Cursor, and OpenCode integrations present checkpoints but do not supply a reviewer model. Their users pick a Codex/Claude CLI route, OpenRouter, or an OpenAI-compatible endpoint. ### OpenRouter routes **Every OpenRouter route requires an API key, including free models.** The installer accepts an existing `OPENROUTER_API_KEY` or prompts for one with hidden input; `sphinx auth` replaces it later. Create a key in [OpenRouter's key settings](https://openrouter.ai/settings/keys). The key is stored in a user-only local file, not an OS keychain, and never in project configuration. Filtered evidence goes to OpenRouter and its selected upstream provider, billed separately from your coding-agent plan. Paid routes need OpenRouter credits. - **Paid consent.** Guided setup labels paid choices. Noninteractive commands need `--allow-paid` or an existing `allowPaid: true` setting. Free routes send zero-price provider limits even when another route permits paid models. There are no automatic paid fallbacks. - **Free router.** `openrouter-free` is best-effort. Its model selection, rate limits, and tool support can interrupt a check; see [OpenRouter limits](https://openrouter.ai/docs/api_reference/limits). Sphinx does not switch providers or upgrade models after a failure. - **Endpoint compatibility.** Requests need endpoint support for tools and output parameters. Capability metadata is a compatibility check, not a guarantee; unusable output leaves the check pending. See OpenRouter [provider routing](https://openrouter.ai/docs/guides/routing/provider-selection) and [structured outputs](https://openrouter.ai/docs/guides/features/structured-outputs). ### OpenAI-compatible endpoints Any OpenAI chat-completions-compatible endpoint (OpenAI, Groq, Together, vLLM, Ollama, LM Studio, and others) can run reviews. It must support tool calls and JSON-schema structured output. ```sh sphinx auth --provider openai --base-url https://api.openai.com/v1 # prompts for the key (hidden) sphinx config --provider openai --model gpt-5-mini # or per size: --large openai: ``` The key is stored next to its URL and only ever sent there. Plain `http://` is allowed only for localhost, where a key is optional. For scripts, set `SPHINX_OPENAI_BASE_URL`, plus `SPHINX_OPENAI_API_KEY` unless the endpoint is localhost. Sphinx never reads `OPENAI_API_KEY`. ### Reference pricing and quality The paid value preset uses Haiku 5.5 with an 8,192-token output ceiling, including reasoning. Reference prices checked **October 15, 2026** start at $0.10 input / $0.50 output per million tokens below 100,000 input tokens; the higher context tier is $0.50 / $2.50. Rates vary by endpoint and over time; see [Haiku endpoints](https://openrouter.ai/api/v1/models/anthropic/claude-haiku-5.5/endpoints). At the lower rates, 30,000 input plus 2,000 output tokens costs about $0.004. A whole check makes several requests with repeated context. The [evaluation results](../eval/RESULTS.md) record measured question quality, grading failures, and corrections across Haiku, Qwen, DeepSeek, and GLM on synthetic changes. They are a limited development benchmark, not a reliability guarantee. The Haiku preset is experimental because it rejected a sufficient qualitative answer in a focused test; DeepSeek is an experimental open-weight preset. Price and tool support alone do not establish question quality. ## Routing and question counts Routing is deterministic and makes no model request. It counts **added plus deleted lines**, changed files, and consequential path terms. Ignored files do not count. | Tier | Default rule | | --- | --- | | Small | At most 80 changed lines and 3 files | | Medium | Between the small and large thresholds | | Large | At least 400 changed lines, 12 files, or a consequential path | Consequential paths contain `auth`, `permission`, `migration`, `billing`, `payment`, `crypto`, `security`, or `terraform`. A matching path makes even a tiny patch large. These are configurable heuristics, not a semantic risk classification. The tier and your chosen depth set the maximum number of initial questions: | Change tier | Relaxed | Standard | Thorough | | --- | --- | --- | --- | | Small | 1 | 1 | 1 | | Medium | Up to 2 | Up to 2 | Up to 3 | | Large | Up to 2 | Up to 3 | Up to 5 | - `relaxed`: observable behavior and the most consequential edge case. - `standard`: behavior, failure modes, and relevant system interactions. - `thorough`: also supported rollout, rollback, and compatibility assumptions. These are ceilings, not quotas: the reviewer asks fewer questions when the evidence supports fewer distinct behaviors, and never pads. A wrong answer adds a replacement question for the same concept, so a check can ask more than the initial count. Changing the model does not change the question count. ## Model calls, tokens, and limits **Model calls have no default cap** (`maxModelCalls: null`, `agentMaxTurns: null`). Every request is counted: background investigation, compaction, the question audit, grading, replacement audits, and failed requests. The questionnaire shows calls and tokens as the check runs, plus cost when the provider reports it. | Step | Typical requests | | --- | --- | | Investigation for a small / medium / large change | Aims for 5 / 7 / 8, including the question audit. These are planning targets, not stops. | | Each answer, learning request, or dispute | 1 | | A proposed replacement question | 1 more, for an independent source audit | | Status, help, config, pending, or pushing an already approved change | 0 | Set or clear an optional cap. This changes no routes and makes no model request: ```sh sphinx config --max-model-calls 30 # 1–100 sphinx config --max-model-calls unlimited # `none` is an alias ``` - Existing numeric caps stay in effect until changed. A check adopts an edited cap when resumed, preserving questions, progress, and counted calls. Lowering a cap below current usage blocks further calls. - An explicit cap reserves calls for grading and the final audit; a lone remaining request cannot start a question synthesis that would lack its audit. - `agentMaxTurns` (advanced) caps investigation, compaction, question generation, and auditing for one review attempt. Other limits always apply: | Setting | Default | Bounds | | --- | --- | --- | | `timeoutSeconds` | 180 | The whole investigation. Unlimited calls do not mean unlimited time. | | `maxContextBytes` | 100,000 | Serialized review context (prompts, tools, schemas), not the whole diff. Pi compacts before this; context that still does not fit is rejected before a model call. | | `toolResultBytes` | 16,000 | Each tool page. Pages shrink to leave room for batched reads. | | `maxOutputTokens` | 4,096 (8,192 in `openrouter-value`) | Every request, 512–16,384. Set with `sphinx config --max-output-tokens 8192`. | OpenRouter counts hidden reasoning within `maxOutputTokens`; a higher ceiling can prevent truncation and permits more billed output. Codex and Claude CLIs get concise-output instructions and local timeout and output-byte limits, but their interfaces have no equivalent hard token cap. Small and medium changes request low reasoning effort; large changes request medium effort where the CLI supports it. **Retries.** Provider failures never retry automatically and never switch providers. Cache warming is disabled. Without a call cap, the reviewer stops after three consecutive invalid responses. Correctable tool or question-validation errors are returned to Pi as feedback within any explicit cap. If a review fails, the questionnaire offers to continue from saved work; Pause is the default. From a terminal, `sphinx check --id ` resumes saved work, and `--retry-review` gives a failed, questionless review one further attempt (with an explicit cap, up to `maxModelCalls` additional requests). Setup, credential, stale-code, and evidence-loading failures must be fixed first. Call caps bound requests and byte limits bound evidence. Neither is a dollar or subscription ceiling. **Set provider-side spending limits for paid accounts.** ## Repository policy `sphinx init` creates `.sphinxconfig`, `.sphinxignore`, and `.sphinxcontext.md` when they are absent and never overwrites them. Edit the files directly afterwards. Commit them to share policy with collaborators. Start from `sphinx init` or [.sphinxconfig.example](../.sphinxconfig.example): ```json { "version": 1, "events": ["pre-push"], "branches": ["main", "release/*"], "level": "standard", "exclude": ["vendor/**"] } ``` | Key | Meaning | | --- | --- | | `enabled` | `false` disables Sphinx for this repository | | `events` | `pre-push`, `pre-commit`, or both | | `branches` | Push policies match the **destination** branch; commit policies match the current local branch | | `remotes` | Remote name patterns for pushes; default `*` | | `level` | `relaxed`, `standard`, or `thorough` | | `exclude` | Extra ignore patterns, added to machine-wide ones | | `backgroundPreparation` | `false` opts this repository out | Branch defaults come from machine-wide settings (initially `main` and `master`), not from the branch you happen to have checked out. Without prompts: ```sh sphinx init --yes --branches main --events pre-push --level standard ``` If both `.sphinxconfig` and legacy `.sphinx.json` exist, `.sphinxconfig` wins and they are not merged; `init` copies a legacy policy into `.sphinxconfig` and leaves the original. **Commit checkpoints.** Enable `pre-commit`. To run one by hand, `sphinx check --staged` assesses the index, including partial staging. **Manual push checks.** `sphinx check --remote origin --branch main` selects the destination; otherwise Sphinx uses the upstream. Multiple destination refs are assessed separately. Tag-only pushes and deletions do not trigger checks in v0.1. ## Project context `.sphinxcontext.md` describes what the project does, who uses it, important workflows, and architecture boundaries. It is included in every reviewer, compaction, and grading request. ```sh sphinx init --yes --context 'A booking service for shared equipment. Reservations must never overlap.' ``` - Keep it under 16,000 bytes and free of secrets. It respects `.sphinxignore`. - The reviewer checks its claims against code. It cannot override Sphinx policy or authorize reading ignored files. - Without context, the reviewer establishes purpose from documentation and source rather than inventing requirements. - Changing it invalidates prepared questions and completion records. ## Files Sphinx never reads Built-in exclusions apply recursively and cannot be undone by project negations: - `.env` and `.env.*`, including `.env.example`. - Private key and keystore names: `*.pem`, `*.key`, `*.p12`, `*.pfx`, `*.jks`, `*.keystore`, `id_rsa`, `id_ed25519`, and related SSH names. - Credential files: `.netrc`, `.npmrc`, `.pypirc`, `*credentials*.json`, `service-account*.json`, `secrets.json`, `secrets.yaml`, `secrets.yml`. Add project exclusions to `.sphinxignore`: ```gitignore # Project-specific private or generated files internal/customer-exports/ /config/production.json *.generated.ts dist/ ``` Supported syntax is `*`, `**`, `?`, root `/`, directory suffix `/`, `#` comments, and local `!` negations; escape a leading `#` or `!` with `\`. This is a small gitignore-like parser, not the full Git pattern language. Project rules cannot undo machine-wide (`~/.config/sphinx/ignore`) or built-in exclusions. Ignore-policy symlinks are rejected. `.gitignore` is not applied to tracked files. **Filtering happens before patch, line-count, and content retrieval, including searches of unchanged files.** Ignored files' contents are not read, saved as evidence, or sent to a model. Git may list their names and object IDs locally to identify changes. A change that touches only ignored files needs no assessment. Ignore rules match paths. They do not detect a secret inside an included source file. Add sensitive paths before your first assessment. Evidence comes from Git objects, not your working files: pre-commit reads the staged index, pre-push reads commits. `.sphinxcontext.md` is read from the working directory and its hash is bound to the assessment. Snapshot identity covers the full commit or index, so editing an ignored file alongside an assessed change can still invalidate the earlier completion. ## Background preparation After commits, merges, rewrites, and checkouts, Sphinx schedules a detached reviewer for the expected destination so questions are ready before you push. It uses local remote-tracking refs and never fetches. It never opens a questionnaire or approves a push. - `sphinx status` shows preparation progress; `sphinx prepare` schedules it explicitly; `sphinx prepare --retry` retries a failed job (failures never retry on their own). - Preparation and the push check share one assessment, lock, question set, and usage count. A change to source, destination, policy, ignore rules, or context discards prepared work. - Set `backgroundPreparation: false` in `config.json` or `.sphinxconfig` to opt out. A repository cannot re-enable preparation disabled machine-wide. - While yolo is on, preparation is paused: no new model request starts, although one already in progress may finish. - A first push, a branch without local tracking history, or a push to an unexpected destination needs a cold review at push time. Pre-commit checks always review on demand. Run `git fetch` if remote history is missing.