Configure Your Model (Bring Your Own Keys)¶
Licensed commands. Every CortexBuild command except
authand the host-invokedhookrequires a valid licence. If you seelicense required, runcortexbuild auth activate --key <token>(orcortexbuild auth refreshif a lease simply lapsed) and try again.--helpalways works.
In plain English
CortexBuild is model-agnostic and bring-your-own-keys. It never marks up tokens, never stores your keys, and LLM use is opt-in and off by default. Most of the pipeline runs with no model at all.
Not installed yet?
If you haven't installed the CLI yet, do the install first.
Do you even need a model?¶
The core CortexBuild workflow is deterministic, offline, and free — no LLM required:
| Command | What it does | Needs a model? |
|---|---|---|
cortexbuild init run . |
Brownfield onboarding (Passes 1–4) | No |
cortexbuild render |
Render rules into your AI tools | No |
cortexbuild render --check |
CI drift gate | No |
cortexbuild eval |
Offline conformance scoring | No |
cortexbuild conformance |
Maturity report | No |
cortexbuild feedback |
Deterministic feedback synthesis | No |
cortexbuild debt-heatmap |
Technical-debt heatmap | No |
cortexbuild ledger … |
Recurrence-ledger management | No |
A model is only needed for the opt-in LLM steps:
cortexbuild init run --with-rule-synthesis(convention inference)cortexbuild synthesize-rules(standalone rule synthesis)- The LLM-assisted review agent roles (Critic, Security, etc.) when invoked via the orchestrator
If you only use the deterministic path, stop here — you're done.
Turn on LLM features¶
LLM features are gated behind an environment variable. Set it before running any LLM-dependent command:
export CORTEXBUILD_LLM=1
$env:CORTEXBUILD_LLM = "1"
Without this variable, LLM code paths are never reached — even if a provider is configured.
Native providers¶
CortexBuild ships two native provider adapters:
Anthropic (default preference)¶
pip install --upgrade "cortexbuild-core[anthropic]" \
--find-links https://dist.cortexbuild.dev/index.html
Provide your API key via the provider's standard environment variable (see How it works for the full interface). Anthropic is the first-preference provider in the default routing table.
Google Gemini¶
pip install --upgrade "cortexbuild-core[gemini]" \
--find-links https://dist.cortexbuild.dev/index.html
Provide your API key via the provider's standard environment variable. See How it works for configuration details.
Both adapters support the ModelTier system (reasoning_heavy, balanced,
fast_cheap) so CortexBuild can route tasks to the right cost/capability tier
automatically.
Any other model via an OpenAI-compatible endpoint¶
Everything beyond the two native adapters — including local / self-hosted
models and cloud gateways — is reached through a single OpenAI-compatible
base_url seam.
Install the OpenAI-compatible extra:
pip install --upgrade "cortexbuild-core[llm]" \
--find-links https://dist.cortexbuild.dev/index.html
Then create .cortexbuild/llm-config.yaml in your repo:
# .cortexbuild/llm-config.yaml
schema_version: 1
provider: ollama
model: llama3
base_url: http://localhost:11434/v1
api_key_env: OLLAMA_API_KEY
locality: local
Key fields:
| Field | Purpose |
|---|---|
schema_version |
Always 1 (current). |
provider |
A human-readable label (e.g. ollama, vllm, lm-studio, bedrock-proxy). |
model |
The model name your endpoint expects. |
base_url |
The OpenAI-compatible endpoint URL. |
api_key_env |
Name of the environment variable holding the API key. Never put a raw key in this file — inline secrets are rejected at parse time (fail-closed). A keyless local endpoint may omit this field. |
locality |
local (loopback, no bytes leave the machine), self_hosted_lan (operator-controlled LAN host — off-box), or cloud. Recorded as data; the egress redaction choke-point wraps every endpoint regardless. |
Local / self-hosted models¶
Any server that exposes an OpenAI-compatible /v1/chat/completions endpoint
works:
| Server | Typical base_url |
|---|---|
| Ollama | http://localhost:11434/v1 |
| vLLM | http://localhost:8000/v1 |
| LM Studio | http://localhost:1234/v1 |
| text-generation-inference | http://localhost:8080/v1 |
Set locality: local for on-box servers (zero egress) or
locality: self_hosted_lan for a LAN-hosted GPU server.
Model gateways (LiteLLM, OpenRouter) and clouds behind them¶
CortexBuild ships no native AWS Bedrock, Google Vertex, or Azure OpenAI adapter. It does not need one: those clouds — and every other vendor — are reachable through an OpenAI-compatible gateway. CortexBuild talks to the gateway; the gateway talks to the vendors.
This is also how you get one model per tier from one endpoint and one key:
schema_version: 1
provider: litellm
model: openai/gpt-5-mini # the fallback when a tier is unset
base_url: http://localhost:4000/v1
api_key_env: LITELLM_API_KEY # env var NAME — never the value
locality: cloud
tiers:
reasoning_heavy: anthropic/claude-opus-4-7
balanced: openai/gpt-5-mini
fast_cheap: groq/llama-3.1-8b-instant
allocation:
objective: [cost, quality]
All three blocks live in the same file, and a gateway is the only place the
credentials for those three vendors appear. Swap base_url for
https://openrouter.ai/api/v1 and the model ids for OpenRouter's, and nothing
else changes.
A tier you leave out of tiers: resolves to the default client rather than
inheriting another tier's model, so a partial block is a valid configuration.
Two things a gateway does not exempt you from:
- Recorded egress consent.
locality: cloudis off-box, and a request is refused withEgressConsentErroruntil a scopedllm-assist-egressconsent is recorded in.cortexbuild/egress-consent.json. Pointing atlocalhost:4000does not make the bytes local when LiteLLM forwards them to three vendors. - Keys by reference only.
api_key_envnames an environment variable. An inlineapi_key:is a hard parse error, not a warning — and a gateway makes that key more valuable, not less, since it fronts every vendor at once.
This path is verified end-to-end offline, including that each model tier reaches the gateway with its own distinct model id.
Picking the right model per task (cost optimisation)¶
CortexBuild's model router (see How it works) defines three model tiers:
| Tier | Best for | Example models |
|---|---|---|
reasoning_heavy |
Planner, Critic, Security Compliance, PR Reviewer — authoring or gating high-consequence output | Claude Opus, GPT-5 |
balanced |
Builder, Tester Validator, Optimizer — most volume, cost matters | Claude Sonnet, GPT-5-mini |
fast_cheap |
Explore — read-only summarisation | Claude Haiku, GPT-5-nano |
The Critic's default tier is reasoning_heavy, same as the Planner it reviews —
but it never actually runs on the same model as the Planner. Routing
automatically resolves the Critic one tier down from whatever the Planner
resolves to (so reasoning_heavy becomes balanced by default), because
reviewing on the same model as the author would lose the independence
rule-critic-gate requires. The routing preview below always shows this
resolved tier, not the raw table entry above.
See the routing before you pay for it¶
cortexbuild orchestrate tiers --title "add payment_status column" --schema-change
No LLM call, no spend. It prints the tier each agent would run on and why:
planner reasoning_heavy changes the schema; planner authors or gates that work
critic balanced changes the schema; critic authors or gates that work
Add --objective cost,quality to try an objective without editing config —
comparing objectives is the main reason to reach for this command.
orchestrate run and orchestrate batch route on this same plan and report it:
run --json as tier_plan, batch --json as tier_plans — a list aligned with
outcomes, one entry per backlog row (a backlog mixes a typo fix with a
migration, so one figure for the batch answers nothing). "Why did that task cost
that much" is answerable from the run record.
Steer it with an allocation objective¶
# .cortexbuild/llm-config.yaml
allocation:
objective: [cost, quality] # or [speed, ...] or [quality, ...]
cost or speed first moves every agent one tier down; quality first moves
one tier up. One step, deliberately — collapsing every agent onto the cheapest
model would destroy the reviewer-differs-from-author guarantee.
The objective is applied to each role's raw capability tier and the Critic's
independence offset is re-applied afterwards, so no objective can absorb it.
(The other order is subtly wrong: a step saturates at the ceiling, so quality
would leave the Planner at reasoning_heavy while raising the Critic onto it.)
Two limits worth knowing¶
Risk sets a floor an objective cannot cross. On a task that touches
auth/RBAC/PII, changes the schema, adds a public API or a deployment target,
spans more than one system, or is marked medium/high risk, no agent drops to
fast_cheap — whatever the objective says. An objective is a preference; risk is
a constraint.
That floor can cost you cross-model review. On a risky task under a cost
or speed objective, the Planner steps down to balanced and the Critic is
held up at balanced by the floor — so both land on one model. This is the only
combination that collapses them. CortexBuild says so rather than silently
accepting it:
⚠ Critic and Planner resolved to the SAME tier — cross-model review is lost
for this task (rule-critic-gate).
It warns; it does not block. Drop the objective for that task, or accept that the plan is reviewed by its own model.
The Planner proposes subtasks and models; governance disposes¶
CortexBuild has no model of its own — it is a governance platform. The judgement about what the subtasks are and which model each deserves comes from your LLM: the Planner agent, which is already a gated, paid-for turn. CortexBuild supplies the rails and checks the result.
- Own-orchestrator mode — the Planner's verdict may include
subtasks, each with asuggested_tierand the risk signals that justify it. Governance validates every suggestion: a risky subtask suggestedfast_cheapis raised to the floor with the reason recorded, a missing or invalid suggestion degrades to the cheapest tier governance allows, and a malformed entry is dropped and counted — a partial plan says it is partial. The governed plan lands inorchestrate run --jsonassubtask_plan, with the LLM's original ask (llm_suggested_tier) kept on record next to the governed answer. - Rendered-host mode — the Planner persona instructs your host's model to
produce a
## Subtasks & Model Plantable inplan.mdunder the same rules, and to cross-check againstcortexbuild orchestrate tiers(offline, no spend).
No new model call is added in either mode: the decomposition rides inside the Planner turn you were already paying for. A Planner that emits no subtasks (an older model, a dry run) changes nothing — the deterministic tier plan above remains the routing answer. Proposals refine it; they never replace the floor.
The recommended operating pattern¶
- Use cheaper / local models for narrow, low-risk, deterministic-adjacent steps (exploration, documentation drafts).
- Use stronger cloud models for Planner, Security Compliance, and PR Reviewer — the roles that author or gate high-consequence output. The Critic is deliberately not on this list: it sits one tier below the Planner it reviews, because independence beats raw capability for a reviewer.
- Validate outputs with the deterministic gates (
eval,conformance,render --check) — these are free and catch regressions regardless of which model produced the change. - Fall back to a stronger model when a cheaper model's output fails validation.
You can override the default tier routing per project and per agent. See How it works — the governed workflow roles for the routing table.
This applies to own-orchestrator mode
Tier routing governs CORTEXBUILD_LLM=1 runs, where CortexBuild picks the
model. In rendered-into-host mode the host tool picks; CortexBuild writes the
tier into each agent file as a model: request the host may honour or
ignore. See Install — Per-agent model tiers.
Privacy & egress¶
Your keys are yours, by-reference only (environment variables), and are never persisted or logged by CortexBuild. The system is offline by default — nothing leaves your machine unless you explicitly opt into an LLM call or an explicit egress action. Every LLM endpoint (including local ones) is wrapped by the egress redaction choke-point, which scrubs sensitive tokens before any request is sent.
Next¶
- Onboard Your Repo — the step-by-step walkthrough.
- CLI Reference — the full command set.