Skip to content

Configuration Reference Open-Core ​

Environment variables, workspace settings, and proxy configurations for the Intutic platform.


1. Environment Variables ​

Proxy ​

The proxy (intutic-proxy) reads these at startup unless a row says otherwise.

Core ​

VariableDefaultDescription
CONFIG_PATHconfig.yaml in the working directoryThe config.yaml to load. The container image sets /etc/intutic/proxy-config.yaml
PORT4000The port the proxy listens on
INTUTIC_PROXY_BIND127.0.0.1; 0.0.0.0 with INTUTIC_GATEWAY_REQUIRE_VK and in the container imageThe addresses the proxy listens on: one IP address, or several separated by commas. The default answers only this machine. Open it for clients elsewhere: 0.0.0.0 for every interface, or a list such as 127.0.0.1,172.17.0.1 to add the Docker bridge for an intutic exec --sandbox on Linux (Docker Desktop reaches loopback already). Keep a loopback address in the list when Windsurf or Cursor traffic is intercepted. A CONNECT from another machine is refused unless the listener is open and the request carries an Intutic key in Proxy-Authorization (Bearer vk_…, or the key as the proxy URL's user name) that the control plane accepts. A value that is not an IP address stops the proxy at startup
RUST_LOGintutic_proxy=info,tower_http=infoLog filter, in tracing syntax (intutic_proxy=debug, warn, …)
CONTROL_PLANE_URLunsetUnset, the proxy runs standalone: no control plane, and rules, budgets and allowlists come from local files. Set to a control plane's address, it runs managed: Valkey becomes required (startup fails if it cannot connect, rather than accepting requests unauthenticated), and every request is checked against the workspace's policy first, failing closed (403 policy_denied) when the check fails or times out unless intutic_settings.policy.fail_closed is false
VALKEY_URLredis://127.0.0.1:6379Valkey for the auth and budget cache, bandit state and the response cache. Standalone, the proxy tries it for 1.5 seconds and runs without it if it does not answer. With Valkey but no control plane, requests are handled exactly as standalone: a request's own provider key passes through, and for a virtual key (vk_…) the provider key in the proxy's environment is used upstream. A Valkey that requires a password takes it in the URL (redis://user:password@host:6379); the proxy masks the password when it logs the URL
INTUTIC_STANDALONEunset1 or true: run standalone without probing for Valkey. Refused together with CONTROL_PLANE_URL
INTUTIC_CHAOS_PLANunsetSet only by intutic chaos run on the proxy it starts for a repetition: the faults to inject, base64url-encoded JSON. A value that does not decode refuses to start the proxy
INTUTIC_CHAOS_EVENTSunsetSet with INTUTIC_CHAOS_PLAN: the file the proxy appends the run's fault, usage and plan events to. An unopenable path refuses to start the proxy
INTUTIC_WORKSPACE_IDunsetThe workspace for requests that do not name one (no x-workspace-id header and no workspace in the key). Also the workspace a centrally distributed egress policy file must name to be loaded
INTUTIC_REGIONunsetA region code (eu, …). Rewrites the hosted control plane's policy-check address to that region's control plane (api.<region>.…), and the in-cluster control-plane.intutic.svc to control-plane.intutic-<region>.svc. Any other address is left alone
OTEL_EXPORTER_OTLP_ENDPOINTunsetExport traces and metrics over OTLP/gRPC to this collector. Unset, nothing is exported. See OpenTelemetry
OTEL_SERVICE_NAMEintutic-proxyThe service name on exported traces and metrics

Provider upstreams and keys ​

VariableDefaultDescription
UPSTREAM_URLunsetOne upstream for every provider, such as a LiteLLM gateway. A provider's own variable below takes precedence. See Standalone
INTUTIC_UPSTREAM_WIREmodelHow a request's upstream is chosen. model: from the model name, as described below this table; a request whose route the chosen provider does not serve is translated (an OpenAI-format request for a Claude, Bedrock, Vertex AI or Gemini model) or refused with 400 unsupported_route. passthrough: every request on /v1/messages, /v1/chat/completions and /v1/responses goes unchanged, in the format it arrived in, to the upstream for that format: UPSTREAM_URL, or ANTHROPIC_UPSTREAM_URL for /v1/messages and OPENAI_UPSTREAM_URL for the other two when set. Use it behind a gateway that serves every route for every model it routes, such as LiteLLM, so its own model names (qwen3-coder on /v1/messages, vertex/claude-opus-4-1 on /v1/chat/completions) reach it as sent. A request with an Intutic key (vk_…) uses the key for that format's provider (ANTHROPIC_API_KEY on /v1/messages, OPENAI_API_KEY otherwise, or the workspace's own); a caller's own key is passed through. The Gemini API's /v1beta route is not passed through. Any other value stops the proxy at startup
ANTHROPIC_UPSTREAM_URLhttps://api.anthropic.comWhere requests for Anthropic models go
OPENAI_UPSTREAM_URLhttps://api.openai.comWhere requests for OpenAI models go
GEMINI_UPSTREAM_URLhttps://generativelanguage.googleapis.comWhere requests for Gemini models go. A gemini-* model asked for on /v1/messages, /v1/chat/completions or /v1/responses is translated to the Gemini API's generateContent, with the requested model and the Gemini key in x-goog-api-key. Requests on the Gemini API's own /v1beta route are not supported
MISTRAL_UPSTREAM_URLhttps://api.mistral.aiWhere requests for Mistral models go
OPENROUTER_UPSTREAM_URLhttps://openrouter.ai/apiWhere requests for OpenRouter models go
DEEPSEEK_UPSTREAM_URLhttps://api.deepseek.comWhere requests for DeepSeek models go
TYPESAFE_API_KEY, FASTINO_API_KEYunsetThe decision-model provider key the proxy uses for a decision call made with an Intutic key (vk_…) when the workspace has not provisioned its own TypeSafe or Fastino key. Same rules as the provider keys below
ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, MISTRAL_API_KEY, OPENROUTER_API_KEY, DEEPSEEK_API_KEYunsetThe provider key the proxy uses when a caller authenticates with an Intutic key (vk_…) and the workspace has not provisioned its own key for that provider. A caller that sends its own provider key uses that key, and the proxy sends it to that provider only, never to the control plane. A gateway with INTUTIC_GATEWAY_REQUIRE_PROVISIONED_KEY set refuses instead of falling back
ENCRYPTION_KEYunsetOpens the workspace provider keys a control plane stores encrypted in Valkey: the same value the control plane has. Without it, the proxy never sends an encrypted value upstream: it treats the key as not provisioned and logs why. A key the proxy captures from a request is stored encrypted when this is set. With Valkey, the proxy announces the ids of the keys it holds (none, without this), and the control plane encrypts stored keys only once every running proxy holds its key
ENCRYPTION_KEY_PREVIOUSunsetWhile ENCRYPTION_KEY is being rotated: the key it replaces, or several separated by commas. Values sealed under them still open

The proxy picks the provider from the model name, so these are the only way to point a first-party provider somewhere else; INTUTIC_UPSTREAM_WIRE=passthrough picks it from the route instead. For a single upstream used by every provider, see Standalone.

Cloud providers ​

Models named bedrock/…, vertex/… and azure/… go to AWS Bedrock, Google Vertex AI and Azure OpenAI. A request with an Intutic key uses the credential the workspace provisioned (Settings → Provider Keys); otherwise, and for any other caller, the proxy uses intutic_settings.providers and then these variables. See AWS Bedrock, Google Vertex AI and Azure OpenAI.

VariableDefaultDescription
AWS_REGION, AWS_DEFAULT_REGIONunsetThe Bedrock region. Required for Bedrock unless providers.bedrock.region is set
AWS_BEARER_TOKEN_BEDROCKunsetA Bedrock API key. Unset, requests are SigV4-signed with the AWS credential chain: AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/AWS_SESSION_TOKEN, static keys in the shared credentials file (AWS_PROFILE, AWS_SHARED_CREDENTIALS_FILE), an IAM Identity Center profile in the config file (AWS_CONFIG_FILE, the sign-in aws sso login cached), a profile that assumes a role (role_arn with source_profile or credential_source; MFA profiles are refused), web identity (AWS_WEB_IDENTITY_TOKEN_FILE with AWS_ROLE_ARN), container credentials (ECS, EKS Pod Identity), then the EC2 instance role (AWS_EC2_METADATA_DISABLED=true skips it)
GOOGLE_CLOUD_PROJECT, ANTHROPIC_VERTEX_PROJECT_IDunsetThe Vertex AI project. Required for Vertex AI unless providers.vertex.project is set
GOOGLE_CLOUD_LOCATION, CLOUD_ML_REGIONglobalThe Vertex AI location (global, us, eu, or a region such as us-east5)
GOOGLE_APPLICATION_CREDENTIALSunsetA service-account or authorized_user key file, or a workload identity federation configuration (external_account). Unset, Application Default Credentials continue with gcloud's application-default login, then the metadata server (Compute Engine, Google Kubernetes Engine Workload Identity, Cloud Run)
AZURE_OPENAI_ENDPOINTunsetThe Azure OpenAI or Azure AI Foundry resource, https://<resource>.openai.azure.com or https://<resource>.services.ai.azure.com
AZURE_OPENAI_API_KEYunsetThe resource's API key. Without one, AZURE_TENANT_ID, AZURE_CLIENT_ID and AZURE_CLIENT_SECRET sign in to Microsoft Entra ID with client credentials
GCE_METADATA_HOSTmetadata.google.internalThe Google metadata server Application Default Credentials ask for a token when no key file is found
IDENTITY_ENDPOINT, IDENTITY_HEADERset by Azure App ServiceWith providers.azure.managed_identity, the managed identity endpoint to ask for a token; unset, the instance metadata service is asked

Rules, budgets and memory ​

VariableDefaultDescription
INTUTIC_SOPS_DIRunsetAbsolute path to a directory of .md SOP files, read like .intutic/sops: the files directly in it and one folder down. Overrides the default search, which walks up from the proxy's working directory looking for .intutic/sops. Set this when the proxy does not run beside a workspace — a container, or a shared gateway. A blank value counts as unset. A path that is set but is not a directory is not silently replaced by the walk: the proxy reports it and loads no SOPs, so a typo cannot be answered with policy from somewhere else. When the resolved SOP set is empty the proxy warns at startup, naming each control that is consequently inactive — including when the directory exists but is empty, which enforces exactly as much as no directory at all. The bundled Kubernetes manifests set this to /etc/intutic-sops and mount the proxy-sops ConfigMap there; see SOPs → where the proxy looks.
INTUTIC_WASM_DIR~/.intutic/wasmThe local WASM rule directory; takes precedence over intutic_settings.wasm_local_dir
INTUTIC_DISABLE_REGO_RULESunset1: refuse Rego rules (OPA builds) at load, from the rules directory and the control plane. Native WASM rules are unaffected. The MCP proxy reads it too
INTUTIC_WASM_MANIFEST_ROOTunset (off)The directory WASM rules may read files from: when a tool call names a manifest (kubectl apply -f k8s/deploy.yaml), the proxy reads that file under this root and hands its contents to the rule. Unset, rules see only the path. ~/ is expanded
WASM_CONTEXT_SNAPSHOT_RATE0.05The fraction of requests (0–1) whose rule-evaluation context is attached to the trace, so a new rule can be replayed against real traffic before it ships. The context holds the request's tool calls — each one's name and its arguments' top-level keys and size, not the argument values unless the workspace sets storeToolArguments — tool names and descriptions, DLP finding names and session counters, not the message text. Every string in it is redacted for secrets and all five PII detectors, email and phone included. Traces go to the control plane when one is connected, and to ~/.intutic/logs otherwise. 0 turns it off
INTUTIC_LOCAL_BUDGET_ENFORCEon0, false or no: keep counting spend against the local daily cap but stop refusing requests over it
INTUTIC_LOCAL_VAULTSunsetoff turns off the local notes-vault search /fix uses. With a control plane, the sync daemon sets it from the workspace's policy
OFFLINE_PRICING_PATHthe bundled price listA JSON price list to use for cost estimates instead of the one built in. A file that does not parse is logged and ignored
JUDGE_FINALIZE_DEADLINE_MS5000How long the end of a judged streamed response may wait for the judge before the client gets its final event. 0 or a negative value waits as long as the judge takes

Egress control ​

The proxy decides what to do with each CONNECT it receives when clients use it as their HTTPS proxy: AI provider hosts are decrypted and governed; other hosts follow the egress policy. Cloud model endpoints (AWS Bedrock, Vertex AI, Azure OpenAI) are not intercepted, because a Bedrock request's signature covers its body; agents reach them governed through the proxy's own routes with a bedrock/, vertex/ or azure/ model name, and a direct connection to them follows the egress policy like any other host.

VariableDefaultDescription
INTUTIC_EGRESS_MODEoff (or intutic_settings.egress.mode)off tunnels every other host. monitor tunnels them but logs and counts the ones enforce would refuse. enforce refuses any host not on the allow list. Any other value stops the proxy at startup with an error naming the three; the mode in force is logged at startup and shown at GET /intutic/egress
INTUTIC_EGRESS_ALLOWnoneComma-separated hosts (example.com), suffixes (.example.com) and IP ranges (10.0.0.0/8) to allow, added to intutic_settings.egress.allow
INTUTIC_EGRESS_POLICY_FILE~/.intutic/hooks/egress-policy.jsonThe central egress policy the sync daemon writes for the workspace. Its mode overrides the local one and its allow list is added to the local list. A missing, corrupt or other-workspace file is ignored
INTUTIC_EGRESS_RELOAD_SECS30How often the central policy file is re-read
INTUTIC_EXTRA_AI_HOSTSnoneComma-separated hosts to treat as AI providers (decrypted and governed), such as an internal model gateway

Shared gateway ​

Settings for a proxy deployed as a shared or self-hosted gateway.

VariableDefaultDescription
INTUTIC_GATEWAY_REQUIRE_VKfalsetrue: accept only Intutic keys (vk_…); any other bearer is refused with 401
INTUTIC_GATEWAY_REQUIRE_PROVISIONED_KEYfalsetrue: refuse (402) a workspace that has not provisioned its own provider key instead of using the gateway's. paid: only for workspaces on a paid plan
INTUTIC_GATEWAY_IDunsetThe gateway's id (gw_…) from registration. With INTUTIC_GATEWAY_TOKEN and CONTROL_PLANE_URL, turns on heartbeats
INTUTIC_GATEWAY_TOKENunsetThe gateway token (gwk_…) from registration
INTUTIC_GATEWAY_ORG_IDunsetSet by Intutic on a managed gateway cell dedicated to one organization: the organization it serves
INTUTIC_GATEWAY_HEARTBEAT_INTERVAL_SECS30Seconds between heartbeats
INTUTIC_GATEWAY_ROTATION_INTERVAL_DAYS30Days between automatic token rotations; 0 turns rotation off
INTUTIC_GATEWAY_TOKEN_STATE_FILEunsetA file where a rotated token is kept, so a restart does not fall back to the original
INTUTIC_GATEWAY_K8S_SECRET_NAMEunsetIn Kubernetes, the Secret a rotated token is written back to
INTUTIC_GATEWAY_K8S_SECRET_KEYINTUTIC_GATEWAY_TOKENThe key in that Secret
INTUTIC_GATEWAY_LOCAL_JUDGEfalsetrue: judge responses with your own model server instead of the control plane's, so content stays on your infrastructure. Deprecated since 3.0, removed in 4.0, like the five below
LITELLM_LOCAL_URLhttp://litellm:4000The local judge's model server. Its host is allowed as self-hosted; a hosted decision API is refused
LITELLM_LOCAL_API_KEYunsetBearer token for it, when it has one
LITELLM_LOCAL_JUDGE_MODELnone (required)The judge model's name on that server
LITELLM_LOCAL_TYPED_JUDGE_MODELLITELLM_LOCAL_JUDGE_MODELA separate model for the two typed questions
INTUTIC_GATEWAY_LOCAL_JUDGE_TYPED_LO, INTUTIC_GATEWAY_LOCAL_JUDGE_TYPED_HIunsetThe band, in log-odds. With both set, the judge is the decide rule local-judge with the band {no_below: σ(LO), yes_at: σ(HI)}: below LO is COMPLIANT, at or above HI a VIOLATION, between them AMBIGUOUS. HI must be above 0. Without a band the free-text verdict decides (deprecated)

The local judge's local-judge rule holds its state to INTUTIC_DECIDE_MAX_RESPONSE_STATE_BYTES, as the gateway's on: response rules do (Decide rules).

Decide rules ​

The engine the proxy asks its SOPs' decide rules on, read once when the proxy starts: ~/.intutic/decide/engine.json in the proxy's home directory (which intutic decide configure writes), overridden by these. With no model the engine is not configured, and an enforcing decide rule refuses with GOVERNANCE_UNAVAILABLE. Pins are read from ~/.intutic/decide/evals/ in the same home directory, and ~/.intutic/decide/disabled runs every rule as shadow.

VariableDefaultDescription
INTUTIC_DECIDE_ENGINE_URLurl in engine.json, else http://127.0.0.1:11434The self-hosted engine. A hosted decision API, or a host that is not loopback, private or listed below, is refused, and the engine is unavailable
INTUTIC_DECIDE_ADAPTERadapter in engine.json, else logprobslogprobs, systemone or decisions
INTUTIC_DECIDE_MODELmodel in engine.json; none otherwiseThe model the engine serves
INTUTIC_DECIDE_TIMEOUT_MStimeoutMs in engine.json, else 5000Per-call timeout
INTUTIC_DECIDE_PARALLELparallel in engine.json, else 1 for Ollama and 8 otherwiseMost engine requests in flight at once
INTUTIC_DECIDE_API_KEYunsetThe engine's key, if it needs one. Never logged
INTUTIC_DECIDE_MODEL_DIGESTunsetThe weights digest, for a server that cannot report one. Pins are keyed by it
INTUTIC_SELF_HOSTED_DECISION_HOSTSunsetComma list of host names (or .suffixes) the engine may run on besides loopback and private addresses
INTUTIC_DECIDE_BUDGET_MS7300How long one tool call's decide rules, or one response's, may take, in milliseconds. A rule its engine cannot answer within it is unavailable, which refuses an enforcing rule
INTUTIC_DECIDE_MAX_RESPONSE_STATE_BYTES32768The most bytes an on: response rule's state (the SOP text and the response) may hold, 1 to 1048576. A larger one is never truncated: the rule is unknown, which is AMBIGUOUS. A tool call's state keeps its own 16,384-byte limit. A value out of range leaves the engine unavailable

Connected services ​

VariableDefaultDescription
EMBEDDING_GENERATOR_URLhttp://localhost:8085/v1/embeddingsThe OpenAI-compatible embeddings endpoint the semantic response cache uses
TURBOVEC_URLhttp://localhost:8083The base address of the vector index the semantic cache searches

CLI ​

VariableDefaultDescription
CONTROL_PLANE_URLunsetSet when intutic start runs, the proxy it starts is managed (see above)
INTUTIC_CONTROL_PLANE_URLa workspace's init --dev setting, else the URL a control-plane login saved; none otherwise (this release has no default control plane)The control plane every command talks to. A --control-plane-url or --dev flag takes precedence
INTUTIC_DEVunset1: talk to a local control plane at http://localhost:3001 instead of the saved or hosted one. INTUTIC_CONTROL_PLANE_URL takes precedence
VALKEY_URLredis://127.0.0.1:6379Passed to the proxy the CLI starts
INTUTIC_PROXY_URLhttp://localhost:4000The proxy intutic exec points agents at. Its port is the one intutic start (without --port) runs the proxy on, the one intutic budget and intutic doctor probe, and the one Windsurf's proxy setting points at. PORT is not read for this
INTUTIC_SNAPSHOT_RULES~/.intutic/hooks/policy-snapshot.rulesWhere the CLI writes the policy snapshot the hook gate reads
INTUTIC_APPROVED_BYPASSES~/.intutic/hooks/approved-bypasses.jsonlThe approved-bypass list the hook gates read, which intutic chaos run copies into each repetition with the snapshot
INTUTIC_WASM_DIR~/.intutic/wasmWhere intutic policy install puts WASM rules
INTUTIC_OPA_BINopa on the PATHThe OPA binary intutic rules build compiles Rego with
N8N_URLhttp://localhost:5678The n8n instance intutic init looks for
N8N_API_TOKENunsetIts API key
INTUTIC_FC_KERNELnone (required)For intutic exec --sandbox firecracker: the guest kernel image
INTUTIC_FC_ROOTFSnone (required)The guest root filesystem
INTUTIC_FC_TAPtap-intuticThe TAP device
INTUTIC_FC_HOST_IP172.16.0.1The host's address on it
INTUTIC_FC_GUEST_IP172.16.0.2The guest's address
INTUTIC_FC_PREFIX30The network's prefix length
INTUTIC_FC_VCPUS1Guest vCPUs
INTUTIC_FC_MEM512Guest memory, in MiB
INTUTIC_GRAPH_IDunset (a new graph)Set by intutic exec on the agent it starts, and read by a nested intutic exec: the agent graph the agent belongs to
INTUTIC_NODE_IDunsetLikewise: the agent that ran the nested intutic exec, which becomes its parent
INTUTIC_DEPTH0Likewise: how deep in the graph that agent is
INTUTIC_LOOP_BASE_COMMITthe commit intutic loop start recorded, else HEADThe ref intutic loop verify diffs the run's changes against when --base is not given
INTUTIC_DECIDE_ENGINE_URLurl in ~/.intutic/decide/engine.json, else http://127.0.0.1:11434The self-hosted engine intutic decide asks (and the gates that call intutic decide check). Overrides engine.json
INTUTIC_DECIDE_ADAPTERadapter in engine.json, else logprobslogprobs, systemone or decisions
INTUTIC_DECIDE_MODELmodel in engine.json; none otherwiseThe model the engine serves. With none, the engine is not configured and enforcing decide rules refuse their tools
INTUTIC_DECIDE_TIMEOUT_MStimeoutMs in engine.json, else 5000Per-call timeout
INTUTIC_DECIDE_PARALLELparallel in engine.json, else 1 for Ollama and 8 otherwiseMost engine requests in flight at once
INTUTIC_DECIDE_API_KEYunsetThe engine's key, if it needs one. Read from the environment only: never written to engine.json, never logged
INTUTIC_DECIDE_MODEL_DIGESTunsetThe weights digest, for a server that cannot report one (any engine but Ollama). Pins are keyed by it
INTUTIC_SELF_HOSTED_DECISION_HOSTSunsetComma list of host names (or .suffixes) the engine may run on besides loopback and private addresses. Hosted decision APIs are refused whatever this says
INTUTIC_DECIDE_MAX_RESPONSE_STATE_BYTES32768The most bytes an on: response rule's state (its rule text and the response) may hold, 1 to 1048576; a larger one makes the rule unknown, never truncated. A tool call's state keeps its 16,384-byte limit

Gate SDK ​

Read by @intutic/gate. The MCP daemon and the Python intutic-clawde gate read INTUTIC_API_KEY too.

VariableDefaultDescription
INTUTIC_API_KEYfrom a control-plane loginThe workspace key (vk_…)
INTUTIC_WORKSPACE_IDfrom a control-plane loginThe workspace
INTUTIC_CONTROL_PLANE_URLnone (this release has no default control plane)The control plane
INTUTIC_PROXY_URLhttp://localhost:4000The proxy the Vercel AI SDK helper points models at
INTUTIC_SESSION_IDnoneThe session id reported with each verdict. GateClient.fromEnv() throws without it or a sessionId; the OpenAI Agents and dsh installers generate one
INTUTIC_SNAPSHOT_RULES~/.intutic/hooks/policy-snapshot.rulesThe local policy snapshot
INTUTIC_GUARD_DISABLEunset1 turns the local snapshot guard off
INTUTIC_DECIDE_BUDGET_MS7300How long the decide tier, or one decide() call that passes no budgetMs, may spend, in milliseconds; the Python gate reads it too. A rule its engine cannot answer within it is unavailable, which refuses an enforcing rule. A rule the engine's p95 (which intutic doctor stores) says cannot fit is not asked: an enforcing one escalates

decide() finds its engine in ~/.intutic/decide/engine.json, which INTUTIC_DECIDE_ENGINE_URL, INTUTIC_DECIDE_ADAPTER, INTUTIC_DECIDE_MODEL, INTUTIC_DECIDE_TIMEOUT_MS and INTUTIC_DECIDE_PARALLEL override. The key is INTUTIC_DECIDE_API_KEY, a weights digest for a server that cannot report one INTUTIC_DECIDE_MODEL_DIGEST, and INTUTIC_SELF_HOSTED_DECISION_HOSTS lists host names the engine's self-hosted guard allows.

Sync daemon ​

Read when Intutic writes harness files: by intutic gates install, and by the sync daemon on a control plane.

VariableDefaultDescription
CONFIG_CAPTURE_INTERVAL5Capture the harness rules files for the config history every this many polls (a poll is 30 seconds by default)
INTUTIC_SKIP_GLOBAL_HOOKSunsetAny value: do not write Intutic's hooks and deny rules into ~/.claude/settings.json; the project's .claude/settings.json is still written

The hook gates it writes read INTUTIC_SNAPSHOT_RULES, INTUTIC_APPROVED_BYPASSES, INTUTIC_GUARD_DISABLE and, under intutic chaos run, INTUTIC_CHAOS_PLAN and INTUTIC_CHAOS_EVENTS, as the CLI and the gate SDK do.

VariableDefaultDescription
INTUTIC_APPROVED_PLANS~/.intutic/hooks/approved-plans.jsonlThe approved-plans cache the hook gates read for plan_approval: (scope and plan)
INTUTIC_OUTCOME_STATE_DIR~/.intutic/hooks/state/outcomesWhere the hook gates keep each session's test outcomes for requires_before: action:run_tests[ok] (post-tool outcome)

MCP proxy / MCP daemon ​

Read by the MCP proxy (intutic-mcp-proxy) and the MCP daemon (intutic-mcp-daemon). The proxy reads most of its settings from the environment first, then from ~/.intutic/env/runtime.env; MCP governance has the full rules.

VariableDefaultDescription
INTUTIC_EVENTS_FILE~/.intutic/events/hook-events.jsonlThe local file every MCP event is also appended to
INTUTIC_MCP_FAIL_OPENtruefalse: a check that cannot complete refuses the call. The workspace's mcpProxyFailBehavior wins once the proxy has loaded it
INTUTIC_MCP_INJECTION_ACTIONwarnblock: refuse a call, or withhold a result, that matches a prompt-injection pattern
INTUTIC_MCP_ANOMALY_MODEenforcewarn reports anomaly findings without blocking; off skips detection
INTUTIC_MCP_ANOMALY_OVERRIDESnoneA JSON object of anomaly detector id → steer, reask, kill or off, capped at each detector's ceiling
INTUTIC_MCP_DLP_DETECTORSnoneA JSON object of PII detector id → off, redact or block; it may only make the workspace's setting stricter
INTUTIC_MCP_SESSION_SCOPEderivedThe session scope sibling proxies share their anomaly window under
INTUTIC_VALKEY_URLnone (VALKEY_URL is also read)The Valkey sibling proxies share their anomaly window and call-budget counters through
INTUTIC_WASM_DIR~/.intutic/wasmThe local WASM rule directory, ahead of runtime.env's INTUTIC_WASM_LOCAL_DIR
INTUTIC_WASM_MANIFEST_ROOTunset (off)The directory WASM rules may read files from, as for the proxy
INTUTIC_DISABLE_REGO_RULESunset1: refuse Rego rules at load
INTUTIC_CHAOS_PLANunsetSet by intutic chaos run: the fault plan the proxy injects
INTUTIC_CHAOS_EVENTSunsetSet with it: the file each injected fault is recorded in
MCP_DAEMON_SOCKET~/.intutic/mcp-proxy.sockThe MCP daemon's Unix socket, for the daemon and the proxies that call it
MCP_DAEMON_POLICY_TTL_MS300000How long the daemon serves a cached policy before refetching it
MCP_DAEMON_MAX_CACHE_ENTRIES500Workspaces kept in the daemon's policy cache
MCP_DAEMON_STATUS_REPORT_MS60000How often the daemon reports its status and the MCP servers it found
MCP_DAEMON_TELEMETRY_FLUSH_MS1000How often the daemon flushes the events it batched to the control plane
INTUTIC_POLICY_SNAPSHOT~/.intutic/hooks/verified/policy-snapshot.jsonThe verified policy snapshot the daemon seeds its cache from at start
REDIS_URLredis://localhost:6379The daemon's Valkey when VALKEY_URL is unset

Both also read INTUTIC_API_KEY, INTUTIC_WORKSPACE_ID and INTUTIC_CONTROL_PLANE_URL (the daemon: CONTROL_PLANE_URL), and the daemon exports traces to OTEL_EXPORTER_OTLP_ENDPOINT under the service name OTEL_SERVICE_NAME (default mcp-daemon). The remote-bridge headers (INTUTIC_REMOTE_HEADERS) are on MCP governance.

Clawde SDK ​

Read by the TypeScript @intutic/clawde-sdk and the Python intutic-clawde client.

VariableDefaultDescription
INTUTIC_BASE_URLhttp://localhost:4000The proxy the client sends model calls to, when baseUrl (base_url) is not passed
INTUTIC_DEBUGunsettrue: log retries and circuit-breaker trips to the console
GIT_BRANCHunsetThe branch reported with each call when the sync daemon is not running
PD_INCIDENT_IDunsetA PagerDuty incident reported with each call, likewise
INTUTIC_DECIDE_BUDGET_MS7300Milliseconds decide() may spend on one call, when budgetMs (budget_ms) is not passed. The engine comes from the same configuration as the Gate SDK's decide()

They also read INTUTIC_CONTROL_PLANE_URL, INTUTIC_WORKSPACE_ID and INTUTIC_SESSION_ID; the Python gate reads the Gate SDK's variables above, and the TypeScript client the agent-graph variables intutic exec sets (INTUTIC_GRAPH_ID, INTUTIC_NODE_ID, INTUTIC_DEPTH). Without the sync daemon, the CI run id comes from the variable GitHub Actions, Buildkite or CircleCI sets. See Clawde SDK.

AgentCore interceptor ​

Read by the AgentCore Gateway interceptor Lambda, besides INTUTIC_CONTROL_PLANE_URL and INTUTIC_API_KEY, which it requires.

VariableDefaultDescription
INTUTIC_TIMEOUT_MS3000The control-plane call timeout
INTUTIC_FAIL_OPENfalsetrue: allow tool calls when the control-plane check itself fails
AGENTCORE_GATEWAY_IDunsetAttached to requests for log correlation; never affects the verdict

TrueForge bridge ​

Read by the TrueForge server bridge, besides INTUTIC_API_KEY, INTUTIC_WORKSPACE_ID and INTUTIC_CONTROL_PLANE_URL.

VariableDefaultDescription
TRUEFORGE_BASE_URLnone (required)The TrueForge server
TRUEFORGE_API_KEYunsetIts bearer token, when the server has OIDC configured
TRUEFORGE_SESSION_IDSunset (discover)Comma-separated session ids to watch
TRUEFORGE_RECONNECT_DELAY_MS2000The wait before re-subscribing to a dropped turn stream

2. Local Sandbox Development Stack ​

The open-source workstation components run against a lightweight, local Valkey cache service.

bash
# Start the local development Valkey service
docker compose up -d

# Valkey port mapping:
# Valkey: 6379

Test stack ​

To execute the unit and integration tests under isolated conditions, spin up the test compose file:

bash
# Start isolated test services
docker compose -f docker-compose.test.yml up -d

# Valkey test port mapping:
# Valkey-test: 6380

3. Workspace Settings ​

Workspaces are the top-level organizational unit. Each workspace has:

SettingTypeDescription
Workspace IDws_*Auto-generated unique identifier
NamestringHuman-readable workspace name
Planenumfree, free_trial, enterprise_trial, self_serve, biz_org, ent_adv (Enterprise), ent_lic (Self-host)
allowedModelsstring[]Approved-models allowlist. Absent or empty means unrestricted. Enforced by the proxy at request time — a request naming a model outside this list is rejected before it reaches a provider. See Settings → Security → Approved Models
allowedModels (standalone)string[]The same allowlist for a proxy with no control plane, read from ~/.intutic/config.json (allowed_models accepted as an alias) on a 60-second cache. Same absent-or-empty-means-unrestricted rule. See Settings → Standalone allowlist
maxDailyBudgetUsd (standalone)numberThe proxy's local daily cap, read from the same file on the same cache. Defaults to 10
upstreamRetryobjectThe workspace's retries and fallbacks: enabled, maxAttempts, initialBackoffMs, maxBackoffMs, budgetMs, onStatus and fallbacks, each overriding the proxy's routing.retry / routing.fallbacks value. Absent fields keep the proxy's value; null clears it

Budget Tiers ​

Each session carries a budget tier label: JUNIOR (the default), SENIOR, STAFF or PRINCIPAL. It is shown with the session and sets no spending limit; spend is limited by the workspace caps and by budgets on virtual keys and members (see Budgets).

Execution Modes ​

Each session also carries an execution-mode label, shown with the session. It records how the session was opened and changes no enforcement.

ModeDescription
STANDARDThe default
SANDBOXOpened by intutic exec --sandbox
HOOK_NATIVEA harness's own session, recorded from its hook events
PROXYA session the proxy recorded for requests that named none

ID Conventions ​

IDs the control plane mints are a short prefix, an underscore and 21 random characters (ws_V1StGXR8_Z5jdHi6B-myT). The common prefixes:

PrefixEntity
ws_Workspace
mbr_Member
sp_SOP
key_API key record
ses_Session, when the control plane opens it; a harness's own session id is kept as sent

Trace ids are UUIDs the proxy assigns. An API key itself starts vk_ and is not in this format.


4. Proxy config.yaml (intutic_settings) ​

The proxy reads a LiteLLM-shaped config.yaml (path from CONFIG_PATH). Every key is optional, and keys the proxy does not know are ignored.

Of LiteLLM's own keys, only model_list does anything here, and two things: when it is non-empty, a routing.candidate_models entry it does not name (as model_name or litellm_params.model) is dropped at startup; and an entry whose litellm_params.model names a cloud model (bedrock/…, vertex/… or vertex_ai/…, azure/…) makes its model_name an alias for it, so a client asking for claude-sonnet-4-5 can be served from Bedrock without changing what it sends. Other entries do not route; first-party upstreams and keys come from the environment.

yaml
model_list:
  - model_name: claude-sonnet-4-5-20250929
    litellm_params:
      model: bedrock/us.anthropic.claude-sonnet-4-5-20250929-v1:0

litellm_params.api_key, litellm_params.api_base and general_settings (including master_key and database_url) are ignored: the proxy does not authenticate callers with a master key.

Intutic's options live under intutic_settings:

SettingTypeDefaultDescription
wasm_local_dirstring~/.intutic/wasmDirectory scanned for locally installed WASM rules. INTUTIC_WASM_DIR takes precedence
workflow.default_budget_usdnumbernoneA spend ceiling applied to any loop run that arrives without one, so the workflow budget detector can fire without a control plane. Unset leaves runs uncapped
commands.non_blockingbooleanfalsetrue: /fix adds its synthesis to your prompt and forwards the turn to the model instead of answering locally
memory.enabledbooleantrueSearch local notes vaults (Obsidian, Logseq, Foam) for /fix
memory.vaultsstring[]noneVault directories to search; a vault found above the working directory is searched as well
response_gate.enabledbooleantrueRefuse a tool call in the model's response that the role's deny list forbids, before the client can run it
response_gate.fail_closedbooleantrueWhen a deny list applies and the response will not parse, refuse it rather than forward it unchecked
response_injection_snippet.enabledbooleantrueKeep a short, DLP-scrubbed excerpt around a prompt-injection pattern found in a response, so a finding can be reviewed
response_injection_snippet.window_bytesnumber200The excerpt's width, capped by the proxy

Cloud providers (intutic_settings.providers) ​

Where Bedrock, Vertex AI and Azure OpenAI requests go when no workspace credential applies. Each value falls back to the environment variable beside it. A secret is never written into this file: secret fields take an environment reference, os.environ/NAME, and a literal value stops the proxy at startup. Unknown keys are refused too, so a misspelt setting cannot be silently ignored.

yaml
intutic_settings:
  providers:
    bedrock:
      region: us-east-1
    vertex:
      project: my-project
      location: global
    azure:
      endpoint: https://my-resource.openai.azure.com
      api_key: os.environ/AZURE_OPENAI_API_KEY
SettingTypeDefaultDescription
bedrock.regionstringAWS_REGIONThe AWS region
bedrock.api_keyenv refAWS_BEARER_TOKEN_BEDROCKA Bedrock API key; without one, the AWS credential chain signs requests
bedrock.runtime_endpointURLhttps://bedrock-runtime.<region>.amazonaws.comThe Bedrock Runtime endpoint, such as a VPC interface endpoint
bedrock.mantle_endpointURLhttps://bedrock-mantle.<region>.api.awsThe endpoint for Claude Opus 4.7 and later
vertex.projectstringGOOGLE_CLOUD_PROJECTThe Google Cloud project
vertex.locationstringglobalThe location
vertex.credentials_filepathApplication Default CredentialsA service-account or authorized_user key file
vertex.endpointURLby locationThe API endpoint, such as a Private Service Connect address
azure.endpointURLAZURE_OPENAI_ENDPOINTThe resource URL
azure.api_keyenv refAZURE_OPENAI_API_KEYThe resource's API key
azure.tenant_id, azure.client_idstringAZURE_TENANT_ID, AZURE_CLIENT_IDMicrosoft Entra ID client credentials, with client_secret
azure.client_secretenv refAZURE_CLIENT_SECRETThe Entra ID client secret
azure.managed_identitybooleanfalseAuthenticate with the host's managed identity (App Service, or the instance metadata service on VMs and AKS); client_id picks a user-assigned identity

Policy check (intutic_settings.policy) ​

SettingTypeDefaultDescription
control_plane_urlstringCONTROL_PLANE_URLWhere the pre-request policy check goes. CONTROL_PLANE_URL takes precedence
fail_closedbooleantrueRefuse the request (403 policy_denied) when the check fails or cannot be reached. false lets it through. It does not cover a custom rule that reaches no verdict, which refuses with 403 GOVERNANCE_UNAVAILABLE either way: an agent can cause that by padding its input
timeout_msnumber3000How long the check may take

DLP (intutic_settings.dlp) ​

enabled, scan_input, scan_output, stream_holdback_bytes, custom patterns and the PII detectors: see Policies › Enforcement.

Egress (intutic_settings.egress) ​

SettingTypeDefaultDescription
modestringoffoff, monitor or enforce; any other value stops the proxy at startup. INTUTIC_EGRESS_MODE takes precedence. See Egress control
allowstring[]noneHosts, .suffixes and IP ranges to allow; INTUTIC_EGRESS_ALLOW adds to it

Decision traffic (intutic_settings.decision_traffic) ​

Customer calls to decision models on /v1/systemone and /v1/decisions. See Decision Traffic.

SettingTypeDefaultDescription
modestringenforceenforce refuses a call to an unpinned model (403 policy_denied); shadow forwards it and logs would_refuse_unpinned
allow_unpinnedbooleanfalseAdmit a model with no pinned version, such as jev-latest or jev-preview
floorsmapnoneThe lowest acceptable top probability per question name, * for every question, each between 0 and 1 (another value stops the proxy at startup). A question answered below its floor is named in x-intutic-decision-abstain
consequential_modelsstring[]noneModels whose every call is answered with x-intutic-decision-requires-human: 1
systemone_upstreamURLUPSTREAM_URL, else https://api.typesafe.aiWhere /v1/systemone calls go
decisions_upstreamURLUPSTREAM_URL, else https://api.openai.comWhere /v1/decisions calls go

Gateway (intutic_settings.gateway) ​

SettingTypeDefaultDescription
require_vkbooleanfalseAs INTUTIC_GATEWAY_REQUIRE_VK, which takes precedence
require_provisioned_keybooleanfalseAs INTUTIC_GATEWAY_REQUIRE_PROVISIONED_KEY=true
provisioned_key_paid_onlybooleanfalseWith require_provisioned_key, apply it to paid workspaces only (INTUTIC_GATEWAY_REQUIRE_PROVISIONED_KEY=paid)
local_judgebooleanfalseAs INTUTIC_GATEWAY_LOCAL_JUDGE. Deprecated since 3.0, removed in 4.0

Tool-output compaction (intutic_settings.snip_compactor) ​

Shrinks long tool output in non-streamed JSON responses after the DLP scan, and records the bytes saved on the trace.

SettingTypeDefaultDescription
enabledbooleantrueMaster switch
max_tool_output_tokensnumber8192Truncate text longer than this (estimated at 4 characters a token)
collapse_repetitions_abovenumber3Collapse a line repeated more than this many times
import_dedupbooleantrueDrop repeated import lines
stack_trace_dedupbooleantrueCollapse repeated stack frames
whitespace_normalizebooleantrueCollapse runs of blank space
json_max_array_itemsnumber3Keep this many items of a JSON array and summarize the rest
json_max_string_value_charsnumber20Cut longer JSON string values…
json_entropy_thresholdnumber0.85…unless they look like identifiers (entropy above this, 0–1), which are kept whole
code_skeleton_enabledbooleantrueReduce long code blocks to their signatures, types and imports
code_skeleton_min_linesnumber10The shortest block that is reduced
code_skeleton_incremental_cachebooleanfalseReuse the reduction of an identical block on the same thread

Model Routing (intutic_settings.routing) ​

Contextual bandit routing picks a model per request via Thompson sampling over a candidate pool. It is experimental and opt-in: nothing is routed until enabled or mode: shadow (standalone) or the workspace's ff_bandit_routing flag turns it on. See Intelligent Model Routing for which candidates a request can reach.

SettingTypeDefaultDescription
enabledboolean—Enables bandit routing in standalone mode. Unset defers to the control plane; standalone, unset routes only under mode: shadow
candidate_modelsstring[]claude-sonnet-5-5, gpt-4.1, gemini-3.8-flashCandidate model pool for Thompson sampling. A request is routed only when its model is a candidate or a dated snapshot or -latest alias of one; others bypass the bandit entirely. A workspace's routingCandidates setting replaces this list for that workspace. Each request only chooses among the candidates it can reach: one its format can be translated to, that the allowlists admit, within budget, with a credential, and listed by the workspace's key when that key's models are known. With a non-empty model_list, names it does not list are dropped at startup
modestringenforceenforce serves the routed model; shadow records what it would have picked and serves the requested one, and standalone turns routing on by itself unless enabled is false (which logs a warning at startup); off does not route
mirror_sample_ratenumber0Fraction of eligible non-streamed requests (at most 0.05) also sent to the routed or mirror candidate, scored off the critical path. The copy goes to the candidate's own provider with that provider's credential; a candidate the request cannot reach as written, or has no credential for, is skipped and counted in routing_targets_skipped. Each mirrored request is paid for twice
mirror_candidate_modelstring—A model to mirror-test against live traffic, whether or not it is a candidate
anthropic_model_overridestring—When set, any Anthropic-bound model is rewritten to this ID after routing. Unset leaves the routed model untouched
sop_pin_max_age_secsnumber600How long a session's injected SOP text stays fixed, so the prompt prefix stays cacheable. 0 re-renders it on every request
cache_guard_max_age_secsnumber300How recent a prompt-cache observation must be for routing to keep a warm session on its model. 0 turns the guard off
cache_guard_min_read_bpnumber5000The cache-read share (basis points) that counts as warm
cache_guard_cold_start_prompt_bytesnumber20000On a session's first turn, a prompt larger than this stays on the requested model. A provider that reports no cache fields still ends the first turn, so later turns route. 0 turns this off

Precedence: when a control plane manages the workspace, the Valkey ff_bandit_routing feature flag is authoritative, and ff_shadow_routing decides shadow mode in place of mode: shadow. routing.enabled applies only to standalone deployments where no control plane manages the workspace.

Retries (intutic_settings.routing.retry) ​

How the proxy retries a provider call that failed before any response reached the client. On by default. See Retries and fallbacks for the rules.

SettingTypeDefaultDescription
enabledbooleantruefalse makes one call per model; configured fallbacks still run after it fails
max_attemptsnumber3Calls per model, the first included. At most 5
initial_backoff_msnumber500Upper bound of the first wait. Each wait is random between zero and a bound that doubles per attempt
max_backoff_msnumber8000Cap on that bound. At most 60000
budget_msnumber30000Time for the whole request: every call, wait and fallback. A retry or fallback that cannot start inside it is not made (time_budget on the trace). At most 120000
on_statusnumber[][429, 500, 502, 503, 504, 529]Statuses retried. Timeouts and failed connections are always retried

Fallbacks (intutic_settings.routing.fallbacks) ​

Ordered targets per model, tried when that model's retries run out on a retryable failure. Empty by default. Each key is the model that was sent upstream; each target has a model, a provider (anthropic, openai, gemini, mistral, openrouter, deepseek, bedrock, vertex_ai or vertex, azure_openai or azure), or both. The workspace setting takes the same providers. Up to five targets per model.

A target that names only a provider sends the same model there. Between Anthropic's API, Bedrock and Vertex AI the model id is rewritten into the target's scheme: claude-sonnet-4-5-20250929 becomes vertex/claude-sonnet-4-5@20250929 on Vertex AI and, on Bedrock, the cross-region inference profile for the configured region (bedrock/us.anthropic.claude-sonnet-4-5-20250929-v1:0; eu., apac. or global. elsewhere), and an undated id such as claude-opus-4-7 becomes bedrock/anthropic.claude-opus-4-7. Name the model as well when your account uses another inference profile.

yaml
intutic_settings:
  routing:
    fallbacks:
      claude-sonnet-4-5-20250929:
        - provider: bedrock
        - provider: vertex_ai

A workspace's upstreamRetry setting overrides any of these fields; the fields it leaves out keep the values here.

Reward Loop (intutic_settings.routing.reward) ​

Rewards are computed only from signals the proxy already observes — upstream success, latency versus SLO, token anomaly, and cost ratio. No LLM judge is involved.

SettingTypeDefaultDescription
enabledbooleantrueEnables the local deterministic reward loop
latency_slo_msnumber30000Latency SLO; responses slower than this are penalised proportionally. Includes full stream duration for streaming responses
latency_penaltynumber0.3Maximum reward deduction for exceeding the latency SLO
token_anomaly_penaltynumber0.2Reward deduction when the token-anomaly detector fires
cost_penaltynumber0.2Maximum reward deduction when the routed model costs more than the requested model would have
yaml
intutic_settings:
  # Directory scanned for locally installed WASM rules
  # (INTUTIC_WASM_DIR takes precedence over this value).
  wasm_local_dir: "~/.intutic/wasm"

  routing:
    enabled: true
    candidate_models: ["claude-sonnet-5-5", "gpt-4.1", "gemini-3.8-flash"]
    reward:
      enabled: true
      latency_slo_ms: 30000
      latency_penalty: 0.3
      token_anomaly_penalty: 0.2
      cost_penalty: 0.2
    retry:
      max_attempts: 3
      budget_ms: 30000
    fallbacks:
      claude-opus-4-1:
        - model: claude-sonnet-4-5
        - model: deepseek-chat
          provider: deepseek

The circuit breaker for AI agents