Skip to content

Environment variables

Every environment variable Ratchet and its deploy kit read, grouped, with its default, where it matters and what it does.

Ratchet reads its settings from environment variables. This page lists all 190 rows of the configuration tables, grouped as in the configuration guide, which has the longer explanations. It is built from docs/CONFIGURATION.md and checked against the lists in ratchet/config.py (KNOWN_ENV, DEPLOY_ENV, MOCK_ONLY_ENV, TOOL_ENV, RESERVED_SETTINGS) and ReleasePolicy’s variables, exported by python docs-site/scripts/export-reference.py.

  • Mock mode (the default, RATCHET_MODE=mock): nothing. No keys, no network, an in-memory ledger.
  • Live mode (RATCHET_MODE=live): NEBIUS_API_KEY (Token Factory), and RATCHET_API_KEYS (or RATCHET_ALLOW_UNAUTHENTICATED=1 when a proxy such as the Caddy guard checks callers). Add RATCHET_STUDENT_BASE and RATCHET_STUDENT_KEY only while the GPU endpoint runs; without them the hosted fallback answers student calls. TAVILY_API_KEY gives Scout real web search. Keep the Scout budget guard on.
  • Night School in live mode: RATCHET_SYNC_CMD, RATCHET_TRAIN_CMD (or its default) and the deploy kit variables for the bucket, image and endpoint.

The Where column says where a variable matters:

Where Meaning
both Read by the gateway in mock and live mode (some only change live behaviour; the meaning says so)
mock only Read only in mock mode; the startup check warns when one is set in live mode
live Read by live mode tools such as python -m ratchet.live
deploy kit Read only by deploy/*.sh and the demo VM, never by the package
live-run tool Read by the live-run harness (python -m ratchet.liverun)
reserved Declared for a feature not built yet: any value but the default stops startup

From Gateway and cascade (ratchet/config.py) in the configuration guide.

Variable Default Where Meaning
RATCHET_MODE mock both mock: offline demo with mock models and an in-memory ledger. live: real Token Factory teacher and a SQLite file
RATCHET_DB ratchet.db both SQLite ledger path (live mode only; mock mode always uses :memory:)
RATCHET_TEACHER_BASE https://api.tokenfactory.nebius.com/v1 both OpenAI-compatible base URL for the teacher, judge and fallback student (and the fallback teacher, unless RATCHET_TEACHER_FALLBACK_BASE is set)
NEBIUS_API_KEY empty both Token Factory API key (sent as Authorization: Bearer …)
RATCHET_TEACHER_MODEL nvidia/Nemotron-3-Ultra-550b-a55b both Teacher model. Must be in the license registry and distillable, or startup fails with LicenseError
RATCHET_JUDGE_MODEL nvidia/nemotron-3-super-120b-a12b both Judge for free-text golden evaluation (LiveEvaluator)
RATCHET_FALLBACK_STUDENT nvidia/NVIDIA-Nemotron-3-Nano-30B-A3B both Hosted, untuned model used for student calls when RATCHET_STUDENT_BASE is empty. Reported as fallback_student in /ratchet/stats and /scout/status; the pages label a student answer with this model “Nano 30B · hosted”, never as our adapter (FR-7.40)
RATCHET_STUDENT_BASE empty both Base URL of your vLLM endpoint, e.g. https://<endpoint>/v1
RATCHET_STUDENT_KEY empty both Token for the student endpoint
RATCHET_STUDENT_BASE_MODEL nvidia/NVIDIA-Nemotron-3-Nano-4B-BF16 both Base model that adapters are trained on (also used by the deploy scripts)
RATCHET_CONFIDENCE_THRESHOLD 0.80 both Fallback threshold, used only when a version has no calibrated threshold in its eval (and for the hosted, untuned fallback student)
RATCHET_SAMPLES 3 both Student samples per request (self-consistency) and per golden row. A request for more choices (n) draws n samples, but its confidence is still scored on the first RATCHET_SAMPLES of them
RATCHET_AUDIT_RATE 0.05 both Probability that a student-served answer is also sent to the teacher. Mock mode raises it to at least 0.10. An admin can replace it at runtime, without a restart (PUT /ratchet/admin/settings or python -m ratchet.admin flag audit_rate 0.2; API.md); controls.audit_rate in /ratchet/stats shows the override, null while this value applies
RATCHET_CANARY_AUDIT_RATE unset both Audit focusing: the audit probability for answers a canary serves, so its release evidence arrives sooner; live answers keep RATCHET_AUDIT_RATE. More than 0 and at most 1 (0 would leave a canary without audits, so it could never be promoted, rolled back or retired); anything else stops startup. Unset or empty: the canary is audited at RATCHET_AUDIT_RATE. Still one random draw per served answer; the rate used is logged as requests.label_p
RATCHET_GOLDEN_FRACTION 0.10 both Share of new examples assigned to the golden (held-out) split
RATCHET_MIN_TASK_GOLDEN 20 both Calibration rows (the even half of a task’s golden rows) a task needs before its own threshold may go below the version’s global one (per-task calibration, FR-14.1). With fewer it gets the higher of the two and calibrated: false. A whole number, 1 or more; anything else stops startup (gateway, simulator, python -m ratchet.live)
RATCHET_PER_TASK_CALIBRATION 1 both 0 switches per-task calibration off: Night School writes no per-task records, so each new version keeps one pooled threshold and the golden gate checks only the pooled numbers, as in v0.4. Versions already scored with records keep them until a night re-scores them. Any other value leaves it on. The reference workloads (make reference) run with it off, so they reproduce v0.4.0 exactly
RATCHET_TEACHER_REASONING_TOKENS 300 both Extra output tokens assumed for the teacher in baseline estimates (and added by the mock teacher)

From Request limits and OpenAI compatibility in the configuration guide.

Variable Default Where Meaning
RATCHET_MAX_BODY_BYTES 2097152 both Largest request body, in bytes (2 MiB), on every POST, PUT and PATCH. A larger body gets 413 request_too_large: at once when Content-Length says so, or as soon as a chunked body passes the limit. 0 = no limit
RATCHET_MAX_MESSAGES 256 both Most messages in one /v1/chat/completions request; more is a 400 with param: messages. 0 = no limit
RATCHET_MAX_INPUT_CHARS 120000 both Most characters of message text in one request: content strings, text and refusal parts, name, refusal, tool_call_id, and tool call ids, function names and arguments, added up (everything forwarded to the teacher except non-text parts, which only RATCHET_MAX_BODY_BYTES bounds); more is a 400 with code context_length_exceeded. About 30,000 tokens of English. 0 = no limit
RATCHET_MAX_N 4 both Most choices (n) one request may ask for, 1 to 128; more is a 400 unsupported_value with param: n (API.md). Each choice past RATCHET_SAMPLES is one more student sample on every such request, and an escalated one asks the teacher for n choices, which it bills as n answers. 1 restores the v0.4 behaviour of one choice per request. A value outside 1 to 128 stops the gateway at startup with ValueError
RATCHET_MERGE_SYSTEM 0 both 1: merge consecutive leading system messages (after developer becomes system) into one, joined by a blank line, for models whose chat template takes a single system message. It changes the stored form of such requests, so set it before collecting training data, not halfway
RATCHET_TEACHER_MODALITIES text both Content part types the teacher accepts besides text, comma-separated, e.g. text,image_url (also input_audio, file). A request with such a part goes to the teacher only (route multimodal): no student call, no audit, nothing stored as a training example. Any other non-text part is a 400 unsupported_content_type. Set it only when the teacher model reads those parts; otherwise the teacher’s refusal comes back as a 400 with its own message (API.md)

From Retries and idempotency in the configuration guide.

Variable Default Where Meaning
RATCHET_IDEMPOTENCY_CACHE 10000 both Most answers kept by Idempotency-Key, 0 to 1,000,000; the least recently used goes first, and the answers kept never exceed 64 MiB together, each counted as its body plus 2 KiB for the entry that holds it (so at most about 32,000 small answers, whatever this says). 0 turns idempotency off: the header is ignored (not even checked) and every request runs
RATCHET_IDEMPOTENCY_TTL_S 600 both Seconds an answer is kept after it finished, 0 to 86,400; a request with the same key after that runs again. 0 keeps none: only a request that arrives while the first is still running shares its answer. Answers hold request-derived text, so they are never written to disk (INV-12)
RATCHET_SEEN_DEDUP_S unset: 300 in live mode, 0 in mock mode both Seconds within which the same API client’s repeat of a stored example counts once toward the frequent-request rule (seen, FREQUENT = 3, INV-3), 0 to 86,400; a repeat after the window counts again. Without API keys every caller is one client. Up to 10,000 (example, client) pairs are remembered, the least recently counted forgotten first. A request whose x-stainless-retry-count is above 0 never counts, whatever this says. 0: every repeat counts, as in v0.4; mock mode’s default, because the simulator’s and the demo’s repeats are traffic, not retries (internal calls, such as Scout’s, the simulator’s and the warm-up’s, count every repeat in any mode). The demo VM’s .env.vm.example sets 300, so the public mock demo counts a visitor’s quick repeats once, as live mode does

From Generation parameters and token caps in the configuration guide.

Variable Default Where Meaning
RATCHET_TEACHER_PARAMS empty (every standard field) both Request fields the teacher gets when its answer is served (escalation, cold start, pinned, teacher-only), comma-separated, in any case: max_tokens (also for max_completion_tokens), temperature, top_p, stop, seed, presence_penalty, frequency_penalty, logit_bias, response_format, tools, tool_choice, parallel_tool_calls, logprobs, top_logprobs, reasoning_effort. Empty means the default: every standard field. tools, tool_choice and parallel_tool_calls are in it since v0.5 (FR-1.41): only a tool request has them, the teacher answers it alone and its tool calls come back to the client (API.md); leave them out (name the other fields) and the teacher answers tool requests in prose, still teacher-only and never stored. logprobs and top_logprobs reach the teacher only when a client sends them, and its token logprobs come back in the response (v0.5, FR-1.14); leave them out if the teacher refuses logprobs (scripts/day1_check.py reports whether it returns them), and teacher-served choices then carry logprobs.content: null. none forwards nothing; all stands for the whole list, and all,top_k adds a vendor field the client sends (otherwise unknown fields are never forwarded). Startup stops on model, messages, n, stream, stream_options, user, safety_identifier, store, metadata, service_tier, functions or function_call, on a name that is not an identifier, and on a near miss of a standard field (max_token, stops), which is a typo; any other name is taken as a vendor field. Audits and arbitrations take the same fields, minus top_p, seed, the penalties, logit_bias and logprobs, at temperature 0. A served answer written under a client’s logit_bias, a non-zero penalty, a temperature above 1 or a vendor field is not stored
RATCHET_STUDENT_PARAMS empty (max_tokens,stop,seed,response_format,logit_bias,top_logprobs) both Request fields the student gets, same syntax. Its n (RATCHET_SAMPLES), temperature (0.7) and logprobs are fixed by the cascade whatever this says, so its confidence stays calibrated. Remove logit_bias when clients send OpenAI token ids, which mean other tokens to Nemotron. A request with tools never reaches the student (the teacher answers it alone, FR-1.41), so tools and tool_choice here only matter for a golden row stored with them; add them only when the student’s vLLM runs with --enable-auto-tool-choice and a --tool-call-parser (deploy/student_endpoint.sh does not), since without them vLLM answers 400. A golden row the student refuses this way scores as not served in the nightly eval
RATCHET_TEACHER_MAX_TOKENS 8192 both Most output tokens per teacher call (reasoning included, as Token Factory counts them). A client’s larger max_tokens is capped to this; with none, this is sent. 0 = no cap
RATCHET_STUDENT_MAX_TOKENS 1024 both Most output tokens per student sample, the same way. 0 = no cap
RATCHET_TEACHER_REASONING_HEADROOM 0 both Tokens added to a client’s max_tokens for the teacher (still at most RATCHET_TEACHER_MAX_TOKENS), for reasoning it writes before the answer: without it a reasoning teacher can spend a tight limit on its reasoning and be cut off. When the teacher gets more than the client asked for, a visible answer longer than the client’s max_tokens (about 4 characters a token) is returned with finish_reason: "length" and not stored. Set it near RATCHET_TEACHER_REASONING_TOKENS for a reasoning teacher whose clients send small limits

From Upstream timeouts and retries in the configuration guide.

Variable Default Where Meaning
RATCHET_TEACHER_TIMEOUT_S 120 both Read timeout for teacher and judge calls on Token Factory, in seconds: how long the model may take to start answering
RATCHET_TEACHER_RETRIES 2 both Extra attempts for a failed teacher or judge call (0 = no retries). Retried: connection failures and HTTP 408, 409, 429, 500, 502, 503, 504, with full-jitter backoff (0.5 s base, 8 s cap) or the server’s Retry-After. A read timeout is retried once at most, because the tokens may already be billed; any other 4xx, and a 2xx body that cannot be read, never. A server wait over 8 s is not waited for: the 429 goes back to the client with it
RATCHET_TEACHER_DEADLINE_S 180 both Upper bound on one teacher call, attempts and waits together, in seconds. A retry whose wait would end past it is not started, and later attempts get only the time that is left as their timeout
RATCHET_STUDENT_TIMEOUT_S 15 both Read timeout for student calls (the vLLM endpoint, or the hosted fallback when RATCHET_STUDENT_BASE is empty), in seconds. On the request path a student call is never retried: a failure escalates to the teacher at once. Night School’s golden eval retries it like the teacher, since no teacher stands behind it there
RATCHET_STUDENT_CONNECT_TIMEOUT_S 2 both Connect timeout for student calls, in seconds, so an endpoint that is down costs a request two seconds rather than the teacher’s five
RATCHET_STUDENT_BREAKER_FAILURES 5 both Student circuit breaker: endpoint failures in a row (a timeout, a connection error, an unreadable or 5xx answer, 408, 429; another 4xx is the endpoint answering and resets the count) after which student calls are skipped and requests go straight to the teacher (route student_breaker), so they stop waiting on a dead endpoint. Live and canary on one endpoint share a breaker; shadow calls have their own. 0 = no breaker (ARCHITECTURE.md)
RATCHET_STUDENT_BREAKER_COOLDOWN_S 30 both Seconds an open student breaker waits before one request probes the endpoint again. A failed probe doubles the wait, up to 300 s (or this value, if larger); a successful probe closes the breaker and resets it. It may be shorter than the student’s timeouts: another request probes only once the probe has been out for the longer of the wait and the student call’s longest time (connect, write, read and pool timeouts plus 5 s: 2 + 10 + RATCHET_STUDENT_TIMEOUT_S + 5 + 5 = 37 s by default), and a probe that fails after that still reopens the breaker and doubles the wait

From When the teacher is down in the configuration guide.

Variable Default Where Meaning
RATCHET_TEACHER_BREAKER_FAILURES 5 both Teacher circuit breaker: failed teacher calls in a row, each counted after its retries (a timeout, a connection error, an unreadable or 5xx answer, 408, 429; a 400 such as context_length_exceeded, a 401 or a tool-call answer is the teacher answering and resets the count), after which the teacher is not called. While it is open, a request that needs the teacher’s answer gets 503 teacher_circuit_open at once, with the time until the next probe as Retry-After (1 to 60 s), and audits and arbitrations are skipped. The fallback teacher has a breaker of its own with the same settings. 0 = no breaker. A negative or non-integer value stops the gateway at startup
RATCHET_TEACHER_BREAKER_COOLDOWN_S 30 both Seconds an open teacher breaker waits before one request probes the teacher again. A failed probe doubles the wait, up to 300 s (or this value, if larger); a successful one closes the breaker. Must be a positive number
RATCHET_ON_TEACHER_FAILURE error both What an escalated request gets when the teacher (and the fallback teacher, if set) is unavailable. error: the mapped error (502, 503 or 504). serve_student: the student’s own answer, below its threshold, when it gave at least one valid sample, with route degraded, ratchet.degraded: "teacher_unavailable" and X-Ratchet-Degraded: teacher_unavailable; never stored, audited or shadowed, so it never counts toward a release. Never for a 400, 413 or 422 about the request, a tool-call answer, a request with tools, a pinned or teacher-only request, a cold start, or a request whose student call failed. Case and spaces are ignored, empty means error, anything else stops the gateway at startup
RATCHET_TEACHER_FALLBACK_MODEL empty both A second teacher that answers a call whose answer is served (escalation, cold start, pinned, teacher-only) when the teacher is unavailable: its retries failed or its breaker is open. Never for audits or arbitrations, a 400 about the request or a tool-call answer. Must be in the license registry and distillable, or startup fails with LicenseError (invariant 1). Its answers are served with route fallback_teacher and its own model id, priced with its own price (Settings.price). When it fails too, the client gets the teacher’s error. Empty = none
RATCHET_TEACHER_FALLBACK_BASE empty (RATCHET_TEACHER_BASE) both OpenAI-compatible base URL for the fallback teacher. It always uses NEBIUS_API_KEY and the teacher’s timeouts and retries. Empty or equal to RATCHET_TEACHER_BASE: the teacher’s client is used
RATCHET_STORE_FALLBACK_TEACHER 0 both 1: store the fallback teacher’s answers as training examples (under the usual rules), each with the fallback model and its own license in its provenance and the BOM. 0: serve them, store nothing, so golden labels stay the teacher’s

From Privacy and security in the configuration guide.

Variable Default Where Meaning
RATCHET_REDACT_PII 1 both Replace emails, phone numbers, card numbers (Luhn-checked), IBANs (mod-97), Aadhaar (Verhoeff), US SSNs, Indian PANs, IPv4 addresses and API secrets with [LABEL] placeholders before a request and the teacher’s answer are stored as a training example. The teacher still receives the original. 0 stores examples verbatim. Names and street addresses are not detected
RATCHET_STORE_EXAMPLES 1 both 0 is zero retention (FR-13.1): every request is answered, audited and logged as usual, but no teacher answer is stored as a training example, and Night School skips every night (storage disabled), so examples kept from before are not trained on. A task whose spec changed is still re-scored on the stored golden rows when no release is in flight (that writes no example), so it does not stay on the teacher for good. Requests are logged with store_opt_out global. Accepts 1/0, true/false, yes/no, on/off in any case; anything else stops startup, so a typo cannot mean “store”
RATCHET_NO_STORE_TASKS empty both Tasks whose teacher answers are never stored, comma-separated (invoice-extract,hr-notes): the same as store: false in their specs (Tasks). Requests are logged with store_opt_out task. A name need not be registered, but one that is not a task name (a space-separated list) stops startup. Examples stored before stay (FR-13.1)
RATCHET_FEEDBACK_CORRECTIONS 1 both Whether a correction sent with an incorrect verdict (POST /v1/ratchet/feedback, FR-13.30) may be stored as a human-labelled training example. 0 keeps every verdict (task agreement, human precision, the human_alert event) and stores no correction (not_stored: corrections_off), for deployments whose API clients should not write labels. The storage opt-outs above and pinned tasks apply either way. Accepts 1/0, true/false, yes/no, on/off
RATCHET_END_USER_KEY empty both The HMAC key end users are hashed with (FR-13.2), at least 16 characters (openssl rand -hex 32). The request’s safety_identifier, else its user, is stored only as HMAC-SHA256 under this key, scoped to the API key name, cut to 16 hex digits. Empty: 32 random bytes are generated on first start and kept in the ledger’s meta table, so hashes survive restarts, but anyone with a copy of the database file then has the key too; set this from a secrets manager to keep it out of the file and its backups. Changing it unlinks every earlier hash: no-train registrations stop matching (an end_user_key event says how many), so those end users must register again. A shorter value stops startup
RATCHET_EXAMPLE_RETENTION_DAYS 0 both Whole days a stored example is kept after it was last stored or seen again; 0 keeps it forever. Past the window its messages, answer and conditions are removed (golden examples too) and the row stays as a tombstone with its hash, so Night School’s counts and an erasure still see it; a later duplicate that may be stored brings the text back with its own teacher and license. Applied hourly by the live gateway, at the start of every live night and by python -m ratchet.live purge. 0 to 36500; anything else stops startup
RATCHET_REQUEST_RETENTION_DAYS 0 both Whole days a request row (metadata only) is kept (FR-13.4); 0 keeps it forever. Older rows are folded into the daily_rollup table (per day, task, client, route and opt-out: the sums every stats reader and the cost report add back; no end user) and deleted, except rows logged since a release stage in flight began and the rows a version in shadow or canary served or shadowed in an earlier stage. Distinct end users per client then count only the rows still kept. Use at least 1, so today’s rows (the daily quota counts them) stay. 0 to 36500; anything else stops startup
RATCHET_ERASURE_SHARED delete both What erasing a client or an end user (FR-13.3) does with an example another client also sent: delete purges it too (the text is the same, so the erased party’s data was in it); keep keeps it for the other client and unlinks the erased party (the other client becomes its first sender, without an end user). Erasure by hashes or by text purges whatever it selects. Anything else stops startup
RATCHET_API_KEYS empty both name:key,name:key. When set, /v1/* needs Authorization: Bearer <key> or X-API-Key: <key>; anything else gets 401. Names: letters, digits, _, ., - (up to 64). Keys: at least 16 characters; generate with openssl rand -hex 24. A bare key without name: is named keyN. The ledger stores the name per request, never the key. End-user hashes and no-train registrations are scoped to the name (API.md): rotate a key under the same name; renaming one unlinks its end users’ earlier hashes, and its clients’ no-train registrations match nothing until the name is back (a no_train_unmatched event at startup; an admin’s registration for every client is not affected). A key also reads its own savings receipts and their proofs, never another client’s (API.md). A malformed value stops the gateway at startup
RATCHET_API_KEY_DAILY_REQUESTS 0 both Chat completions per key per UTC day; past it a 429 insufficient_quota (code daily_quota_exceeded) with Retry-After until 00:00 UTC and X-Should-Retry: false (API.md). 0 = unlimited. RATCHET_KEY_LIMITS overrides it per key (Spend and rate limits). Counted by the spend meter, which reads today’s requests from the ledger at startup, so it survives restarts in live mode
RATCHET_ADMIN_KEYS empty both Admin keys for management calls (PUT and DELETE /ratchet/tasks/{name}, POST /ratchet/tasks/validate, API.md; POST /ratchet/cost/endpoint; every route of the admin API under /ratchet/admin/, reads included, API.md; and the training-set proofs, POST /ratchet/versions/{id}/proof and GET /ratchet/versions/{id}/heldout, API.md, which are a membership oracle for the training data; and every savings receipt, the gateway’s and each client’s, API.md), in the RATCHET_API_KEYS syntax: name:key,name:key, keys at least 16 characters. Sent as Authorization: Bearer <key> or X-API-Key; a missing or wrong key gets 401, an API key 403. The ledger and the event log record the name, never the key. A key may not be in both variables (startup error). Empty: the admin API is off in live mode (403 admin API disabled: set RATCHET_ADMIN_KEYS) and open in mock mode (the admin is mock-admin). Not the Caddy guard’s RATCHET_ADMIN_TOKEN
RATCHET_DASHBOARD_KEYS empty both Read-only keys for the dashboard API (API.md), in the RATCHET_API_KEYS syntax. A dashboard key reads everything an admin key reads and writes nothing. A key may not also be an API key or an admin key (startup error), so each key has one role. Give one to whoever watches a live gateway’s dashboard
RATCHET_PUBLIC_DASHBOARD 1 in mock mode, 0 in live mode both 1: the dashboard API (GET /ratchet/stats, GET /ratchet/cost, POST /ratchet/redact, GET /ratchet/tasks and /ratchet/tasks/{name}, the BOM endpoints and the other reads API.md lists) needs no key. 0: it needs an admin or dashboard key, as Authorization: Bearer <key> or X-API-Key; without one it is 401, with an API key 403, and with neither RATCHET_ADMIN_KEYS nor RATCHET_DASHBOARD_KEYS set every read is 403. The pages, /healthz, /ratchet/bom/public-key and Scout are always public. The dashboard page sends no key yet, so with 0 it shows no data: read the API with a key, or set 1 (the demo VM does)
RATCHET_PUBLIC_BOM 0 both 1: GET /ratchet/bom and GET /ratchet/versions/{id}/bom stay public while the dashboard API is private, so auditors can check an adapter’s provenance without a key
RATCHET_SCRUB_STATS unset both What a reader of the dashboard API sees. Unset: an anonymous read of a public dashboard in live mode is scrubbed: client names in /ratchet/stats and in task allow-lists (GET /ratchet/tasks) become client-1, client-2, … (by sorted name, the same in both), event details lose every http(s):// URL (<url>), and an error message after an exception’s class is cut (ConnectError: ... becomes ConnectError; v0.4 ledgers hold such events). A reader with an admin or dashboard key sees everything. 1: every read is scrubbed, with a key or without, in either mode. 0: none is. security.scrubbed in /ratchet/stats says which a reader got
RATCHET_OPENAPI 1 in mock mode, 0 in live mode both 1: FastAPI serves /docs, /redoc and /openapi.json. 0: they do not exist (404), so a live gateway does not hand anyone a map of its routes
RATCHET_ALLOW_UNAUTHENTICATED 0 both Live mode refuses to start without RATCHET_API_KEYS, because /v1/* would answer anyone, on your teacher credits. 1 lets it start, for a gateway something else guards: the demo VM’s Caddy guard (RATCHET_API_GUARD=guarded) or a private network. Mock mode ignores it
RATCHET_CSP empty both A Content-Security-Policy for every response. Empty sends none, so no page can break by default. Printable ASCII only (anything else stops startup). Recommended, which the React build and the lite pages work with: default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; connect-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'self' (the pages load nothing from other origins; 'unsafe-inline' is for the theme script in the React page and the lite pages’ inline scripts). It also blocks /docs, whose Swagger UI comes from a CDN
RATCHET_BOM_SIGNING_KEY empty both Ed25519 private key as the base64 of its 32-byte seed. Signs each adapter’s bill of materials and every savings receipt (same key, same public key). Generate with python -m ratchet.bom keygen, which also prints the public key to publish. Needs the sign extra (pip install "ratchet-distill[sign]", included in the gateway image). An invalid value stops the gateway at startup. Empty = BOMs and receipts are stored with a SHA-256 but unsigned

From Spend and rate limits in the configuration guide.

Variable Default Where Meaning
RATCHET_KEY_LIMITS empty both Per-key overrides of the defaults below, by key name: acme:daily_requests=10000,daily_usd=5,monthly_usd=100,rpm=60,concurrency=4,tasks=ticket-triage|invoice-extract,store=1;globex:daily_usd=1. Entries are separated by ;, fields by ,. daily_requests, rpm and concurrency are whole numbers, daily_usd and monthly_usd plain decimals (US dollars, at most 1,000,000,000), 0 turns a limit off for that key. tasks lists the task names the key may send, separated by | (any other task, default included, is a 403 task_not_allowed; without tasks every task its own clients allow). store=0 keeps the key’s requests out of the training set: they are served, audited and logged, never stored (store=1, the default, stores as usual). A name that is not in RATCHET_API_KEYS, an unknown field, a field or a key given twice, or a bad value stops startup; the message lists the key names and never prints what may be a key pasted by mistake (acme:<key>, in the RATCHET_API_KEYS syntax): an unknown name is not repeated, and an item, field or value is quoted only when it is shorter than any key (16 characters)
RATCHET_API_KEY_DAILY_USD 0 both Every key’s US dollar budget per UTC day (0 = none; at most 1,000,000,000). Past it the key gets 429 insufficient_quota (code budget_exceeded) until 00:00 UTC, with X-Ratchet-Budget-Remaining-USD: 0, Retry-After, X-Ratchet-Budget-Reset and X-Should-Retry: false. A request in flight can overshoot by its own cost, because the check reads what was spent before it. A key with a dollar budget gets X-Ratchet-Spend-Today-USD and X-Ratchet-Budget-Remaining-USD on every answer
RATCHET_API_KEY_MONTHLY_USD 0 both Every key’s US dollar budget per UTC month (0 = none), refused the same way until 00:00 UTC on the 1st. With a monthly budget set, the gateway reads this month’s spend from the ledger at startup (a pass over the requests index; with none, only today’s)
RATCHET_API_KEY_RPM 0 both Every key’s requests a minute (0 = no limit): a token bucket that holds max(1, rpm // 6) requests (ten seconds’ worth) and refills continuously. Past it a 429 rate_limit_error (code rate_limit_exceeded) with Retry-After (seconds until one more request passes, which OpenAI SDKs honour) and X-RateLimit-Limit-Requests, X-RateLimit-Remaining-Requests and X-RateLimit-Reset-Requests. Checked before the body is read, so a request refused later (400, 403, 429) has still used its token
RATCHET_API_KEY_CONCURRENCY 0 both Every key’s requests in flight (0 = no limit), counted once a request’s body has arrived. One more is refused at once (429 rate_limit_exceeded, Retry-After: 1), never queued
RATCHET_DAILY_BUDGET_USD 0 both The gateway’s own US dollar budget per UTC day for /v1 chat requests, all keys (and requests without a key) together (0 = none; at most 1,000,000,000). A scrubbed /ratchet/stats read does not show it. What happens past it is RATCHET_BUDGET_MODE. Scout is not counted: it has RATCHET_SCOUT_DAILY_BUDGET_USD
RATCHET_BUDGET_MODE block both block: past the gateway’s budget every chat request gets 429 insufficient_quota (code gateway_budget_exceeded) until 00:00 UTC (/v1/models and request lookups cost nothing and still answer). student_only: confident student answers are still served, with no audit and no shadow; a request that needs the teacher (an escalation, a cold start, a pinned or unregistered task, a request with tools) gets that 429 without a teacher call, and what its student samples cost is recorded. Without audits, canary promotion pauses; a rollback still acts on the audits already recorded. Any case; empty means block
RATCHET_BUDGET_ALERT_PCT 50,80,100 both The shares of a dollar cap (a key’s daily or monthly budget, the gateway’s daily budget) that write a budget event the first time spend reaches them in the cap’s UTC day or month (acme reached 80% of $5.00 daily budget, the gateway reached 100% of $20.00 daily budget). Whole percentages from 1 to 100, comma-separated; empty = no alerts. The gateway reads the period’s budget events at startup, so a restart does not write one again; the events go to the log like every other (ledger_event), where an alert rule can catch them
RATCHET_IP_RPM unset: 0 in mock mode, 120 in live mode both Requests a minute per client IP on /v1/chat/completions of a gateway without RATCHET_API_KEYS (with keys, each key has its own limit and this is off), as a token bucket like RATCHET_API_KEY_RPM. The IP is the connection’s, or the first X-Forwarded-For hop with RATCHET_TRUST_PROXY=1 (on the demo VM uvicorn already takes it from Caddy). At most 10,000 addresses are remembered; past that the least recently seen is forgotten. 0 = no limit
RATCHET_MAX_INFLIGHT 32 both Chat requests in flight across the gateway before the next gets a 503 overloaded with Retry-After: 1 instead of waiting for a worker thread (the pool has 40, so the dashboard and health checks keep answering under a burst). A request counts once its body has arrived, so slow uploads hold no slot. 0 = no limit

From Scout, the multi-agent demo in the configuration guide.

Variable Default Where Meaning
TAVILY_API_KEY empty both Tavily Search key for Scout’s searcher. In live mode without it, Scout returns 503. The Scout CLI (python -m ratchet.scout) also reads it; without it the CLI uses simulated results
RATCHET_API_KEY unused both Scout CLI only (python -m ratchet.scout): the gateway API key it sends as Authorization: Bearer, for a gateway with RATCHET_API_KEYS set. --api-key overrides it. The gateway itself never reads this variable
RATCHET_SCOUT_DAILY_BUDGET_USD 3.00 both Live mode: most Ratchet spend on Scout runs per UTC day. Once reached, new runs get 429. Mock mode has no budget
RATCHET_SCOUT_RUNS_PER_HOUR 6 both Runs per client IP per rolling hour. Mock mode allows 10 × this value
RATCHET_SCOUT_MAX_RUNS_PER_DAY 30 both Live mode: most runs per UTC day, for all clients together. Caps Tavily credits (about 3 searches per run, so 90 credits a day). Mock mode has no cap
RATCHET_SCOUT_MAX_RESULTS 4 both Tavily results per query. With 3 queries, at most 12 results are triaged
RATCHET_TRUST_PROXY 0 both 1: take the client IP for the per-IP limit from the first X-Forwarded-For entry. Only set it when a proxy you control overwrites that header; otherwise clients can fake their IP. Not needed on the demo VM, where uvicorn runs with --proxy-headers

Scout, the multi-agent demo: Judge access and Tavily credits

Section titled “Scout, the multi-agent demo: Judge access and Tavily credits”

From Scout, the multi-agent demo: Judge access and Tavily credits in the configuration guide.

Variable Default Where Meaning
RATCHET_SCOUT_JUDGE_CODE empty both The access code for evaluators; empty turns judge access off. 16 to 256 printable ASCII characters with no spaces: use openssl rand -hex 16. Set it if and only if RATCHET_SCOUT_JUDGE_RUNS_PER_DAY is above 0. Judges send it once (POST /scout/judge) and get a signed cookie; never put it in a URL, the project page or the video
RATCHET_SCOUT_JUDGE_RUNS_PER_DAY 0 both Runs per UTC day held back for judges, 0 to RATCHET_SCOUT_MAX_RUNS_PER_DAY. The public gets the run cap minus this; judges get their share plus whatever public room is left. Equal to the run cap: judges only, and the public gets 429 (allowed)
RATCHET_SCOUT_JUDGE_BUDGET_USD unset both USD per UTC day held back for judges, 0 to RATCHET_SCOUT_DAILY_BUDGET_USD. Unset: the daily budget × judge runs / run cap, rounded down to the cent (7 of 22 runs of $3.00: $0.95). Above 0 only with judge access on
RATCHET_SCOUT_JUDGE_SESSION_S 604800 both How long a judge cookie lasts, 60 s to 30 days (7 days: a judge who comes back does not need the code again). Rotating the code ends every session
RATCHET_TAVILY_MONTHLY_CREDITS 0 both Tavily credits per cycle (the free plan gives 1,000 a month; the Nebius Builders Program may add more, unverified). 0 counts credits without a cap. A basic search costs 1 credit, an advanced one 2; the meter charges what Tavily reports in usage.credits
RATCHET_TAVILY_JUDGE_CREDITS unset both Credits per cycle held back for judge runs, at most the monthly credits, above 0 only with judge access on. Unset: monthly × judge runs / run cap, rounded down (1,000 × 7 / 22 = 318)
RATCHET_TAVILY_CYCLE_DAY 1 both Day of the month (1 to 28) the credit cycle starts, at 00:00 UTC. Tavily’s own reset day is not documented (unverified): set the day your dashboard shows
RATCHET_TAVILY_PACE_UNTIL unset both A date (YYYY-MM-DD, UTC). While it falls in the current cycle and is today or later, the public’s daily credit allowance spreads what is left until that date instead of the cycle’s end; unused credits roll forward. Recommended: 2026-12-15, the last day of judging

From Mock-mode demo in the configuration guide.

Variable Default Where Meaning
RATCHET_MOCK_WARMUP_DAYS 0 mock only Simulated days of mixed traffic, each followed by a night, run at startup and on every demo reset, so the demo opens with a trained student. 4 takes about 2 s and leaves a live student that answers about 80–90% of Scout’s LLM calls (simulation). Writes a warmup event
RATCHET_MOCK_WARMUP_REQUESTS 1500 mock only Requests per warm-up day
RATCHET_MOCK_PACE 0.25 mock only /scout/stream waits this share of each call’s simulated latency (mock Ultra 2.4 s → 0.6 s), so the page shows agents working. 0 = no waiting. /scout/run never waits
RATCHET_MOCK_STRICT 0 mock only 1: the mock models answer only the demo’s own requests (synthetic tickets and Scout’s research calls), and anything else gets 400 mock mode only answers demo requests, as before the generic mock world. 0: any other request gets a deterministic answer from the generic world (sim/generic.py): free text, an instance of its response_format schema, or a tool call to the mock teacher. Night School’s mock trainer and golden eval read stored rows either way. With 1, POST /ratchet/demo/day refuses the schema and tools workloads (400), which only the generic world answers
RATCHET_MOCK_ENDPOINT_HOURS 24 mock only Hours a day the simulated student endpoint runs, 0 to 24: each simulated day (the demo, the warm-up, python -m sim.simulate) records one endpoint interval of this length from the start of the day, on the synthetic clock, for the cost report (Cost accounting). 0 = no endpoint (as with the hosted fallback). Anything outside 0 to 24 stops startup. Simulation assumption, not a measurement
RATCHET_MOCK_TEACHER_REASONING_MEAN unset mock only The mock teacher’s mean billed reasoning tokens. Unset, it bills exactly RATCHET_TEACHER_REASONING_TOKENS (300), the formula’s assumption, so every number is as before. Set (more than 0, at most 100,000; anything else stops the gateway and python -m ratchet.live at startup, in live mode too, where nothing reads it), each request bills round(mean × exp(0.3 z − 0.045)) reasoning tokens, z a standard normal drawn from the request’s text (the same request always costs the same), so the savings receipts have a gap between the formula and the bills to measure: with 420, ticket-triage’s calibrated ratio is about 1.3 to 1.4 (simulation; Savings receipts). The simulator takes --teacher-reasoning-mean instead

From Demo VM: Caddy (deploy/vm/) in the configuration guide.

Variable Default Where Meaning
RATCHET_DOMAIN required deploy kit Site name Caddy serves and gets a certificate for, e.g. ratchet.dualmindlab.tech or <public-ip>.sslip.io. First boot fills in the sslip.io name if it is still the placeholder
RATCHET_API_GUARD open deploy kit open: every path is public. guarded: /v1/*, /ratchet/demo/* and /ratchet/admin/* return 403 unless the request has a matching X-Ratchet-Admin-Token header (the admin API also needs an admin key, RATCHET_ADMIN_KEYS, in live mode). Pages, /scout*, /ratchet/stats and /ratchet/bom stay public at the edge; whether the gateway serves the dashboard API without a key is RATCHET_PUBLIC_DASHBOARD. In mock mode, guarded also disables the dashboard’s demo buttons. In live mode without RATCHET_API_KEYS, the gateway starts only with RATCHET_ALLOW_UNAUTHENTICATED=1
RATCHET_ADMIN_TOKEN empty deploy kit Token for guarded. Hex, at least 32 characters (openssl rand -hex 32). Shorter or empty blocks the guarded paths for everyone. Caddy strips the header before it reaches the gateway
RATCHET_VM_NAME ratchet-demo deploy kit The VM’s name (create_vm.sh refuses a name that exists)
RATCHET_VM_PLATFORM cpu-e2 deploy kit Nebius platform; cpu-e2 exists only in eu-north1, elsewhere use cpu-d3
RATCHET_VM_PRESET 2vcpu-8gb deploy kit Nebius preset, for example 4vcpu-16gb
RATCHET_VM_DISK_GB 30 deploy kit Boot disk size in GB
RATCHET_SSH_USER ubuntu deploy kit The login user cloud-init creates (Nebius reserves root and admin)
RATCHET_REPO_URL https://github.com/harshbhx/ratchet.git deploy kit What the VM clones into /opt/ratchet
RATCHET_BACKUP_DIR /var/backups/ratchet deploy kit backup.sh: the host folder for ledger backups
RATCHET_BACKUP_KEEP 14 deploy kit backup.sh: local copies to keep

From Live Night School (ratchet/live.py) in the configuration guide.

Variable Default Where Meaning
RATCHET_DATA_DIR data live Local folder synced to the bucket, laid out as the training job sees the bucket at /data: night/train.jsonl, boms/student-vN.json, and adapters/<name>/ratchet_bom.json and NOTICE.md (written after a night that trained, next to where the job wrote the weights; an adapter name that is not one folder name gets the boms/ copy only). python -m ratchet.live export copies adapters/<name>/ from here when the weights are here too (a bucket mount, or synced down)
RATCHET_SYNC_CMD empty live Command that uploads RATCHET_DATA_DIR to the bucket, e.g. aws s3 sync ./data s3://my-bucket --endpoint-url https://storage.eu-north1.nebius.cloud (skipped if empty). Run before the training job and again after a night that trained, so the adapter’s BOM and NOTICE.md reach its bucket folder; a failure of the second run is a sync_failed event and a non-zero exit. It must only upload: an option that deletes remote files missing locally (--delete) would delete the adapter weights
RATCHET_TRAIN_CMD bash deploy/train_job.sh {version} live Command that runs training and waits for it. {version} and {data} are substituted
RATCHET_ADAPTER_ROOT /data/adapters live Adapter folder as the vLLM endpoint sees it (lora_path = <root>/<version>). Also read by the gateway in live mode, which reloads an adapter from there when vLLM answers 404 for it

From Live-run harness in the configuration guide.

Variable Default Where Meaning
RATCHET_LIVERUN_KEY empty (required) live-run tool The harness’s gateway API key: the key of the liverun:<key> entry in RATCHET_API_KEYS (--client names another entry). Export it in the harness’s shell only; never a flag, so it stays out of shell history and the process list, and it is never written or printed (results carry the name)
NEBIUS_API_KEY_LIVERUN empty (NEBIUS_API_KEY) live-run tool A separate Token Factory key for the harness’s own arms (the control arm and the untuned-Nano arm), so a runaway run cannot drain the key the gateway and the judge demo serve with. The gateway’s own teacher calls keep NEBIUS_API_KEY. Results record which variable was used, never its value
RATCHET_GIT_SHA empty live-run tool The code’s commit when the image has no .git (git rev-parse HEAD comes first). 40 or 64 hex characters; anything else is ignored. Results carry a SHA-256 over the ratchet and sim sources either way

From Deploy scripts (deploy/) in the configuration guide.

Variable Default Where Meaning
DRY_RUN 0 deploy kit Used by both. 1: train_job.sh and student_endpoint.sh create pass --dry-run (nebius validates the request and creates nothing); start and stop, which have no --dry-run, print the command instead of running it; the read-only nebius ai endpoint list still runs, and no uptime is recorded. Any value but 0 or 1 is refused (exit 2), so DRY_RUN=true never starts a paid GPU
RATCHET_BUCKET_ID required (job; endpoint create) deploy kit Used by both. Nebius Object Storage bucket ID, mounted at /data
RATCHET_SUBNET_ID empty (the project’s default subnet) deploy kit Used by both. --subnet-id for the job and for create
RATCHET_TRAIN_IMAGE required deploy kit Used by train_job.sh. Training image built from deploy/Dockerfile.train
RATCHET_TRAIN_PLATFORM gpu-l40s-a deploy kit Used by train_job.sh. Nebius GPU platform
RATCHET_TRAIN_PRESET 1gpu-8vcpu-32gb deploy kit Used by train_job.sh. Nebius preset
RATCHET_REGISTRY_SECRET empty deploy kit Used by train_job.sh. --registry-secret: a MysteryBox secret with REGISTRY_USERNAME and REGISTRY_PASSWORD, for a private training image (Nebius Container Registry)
RATCHET_BUCKET_S3 empty deploy kit Used by train_job.sh. s3://bucket[/prefix]. When set, the script polls for adapters/<version>/adapter_model.safetensors (every 30 s, up to 2 h, the job’s --timeout) so it can be used as RATCHET_TRAIN_CMD
RATCHET_S3_ENDPOINT empty deploy kit Used by train_job.sh. S3 endpoint URL for Nebius Object Storage
RATCHET_STUDENT_KEY required (create) deploy kit Used by student_endpoint.sh. Token clients must send to the endpoint. Passed to --token, never printed (<RATCHET_STUDENT_KEY> in the echoed command)
RATCHET_ENDPOINT_NAME ratchet-student deploy kit Used by student_endpoint.sh. Name create gives the endpoint, and the name start, stop and status look up in nebius ai endpoint list --format json to find its id
RATCHET_ENDPOINT_ID empty deploy kit Used by student_endpoint.sh. The endpoint’s id (metadata.id). When set, start and stop use it without the list lookup, and status looks this id up instead of the name. Set it when the lookup cannot decide (two endpoints with the name, or a list with more pages)
RATCHET_PYTHON python deploy kit Used by student_endpoint.sh. Python 3 that reads the endpoint list (standard library only, -I) and runs python -m ratchet.cost endpoint up|down after create, start and stop to record the endpoint’s uptime in the ledger at RATCHET_DB (best effort: when recording fails, the deploy still succeeds and prints the command to run where the ledger is)
RATCHET_SERVE_PLATFORM gpu-l40s-a deploy kit Used by student_endpoint.sh. GPU platform for vLLM
RATCHET_SERVE_PRESET 1gpu-8vcpu-32gb deploy kit Used by student_endpoint.sh. Preset for vLLM
RATCHET_VLLM_IMAGE vllm/vllm-openai:v0.18.0-cu130 deploy kit Used by student_endpoint.sh. vLLM image. vllm/vllm-openai:v0.18.0 is the CUDA 12 build of the same release (both on Docker Hub, pushed Mar 20, 2026), for a host driver too old for CUDA 13
RATCHET_SERVE_MAX_LEN 8192 deploy kit Used by student_endpoint.sh. vLLM --max-model-len. The model card’s example uses 262,144 tokens; ticket prompts need far less, and a longer prompt gets vLLM’s 400 and escalates to the teacher
RATCHET_SERVE_MAX_SEQS 64 deploy kit Used by student_endpoint.sh. vLLM --max-num-seqs (concurrent sequences)
RATCHET_SERVE_TEMPLATE_KWARGS {"enable_thinking":false} deploy kit Used by student_endpoint.sh. vLLM --default-chat-template-kwargs (a JSON object, checked before create; no single quote), so the student answers without reasoning unless a request asks. Set but empty to leave the flag out (requests then carry their own chat_template_kwargs)
RATCHET_REASONING_PARSER_PLUGIN empty deploy kit Used by student_endpoint.sh. Absolute path in the container of the model card’s nano_v3_reasoning_parser.py (for example /data/nano_v3_reasoning_parser.py, uploaded to the bucket). When set, vLLM gets --reasoning-parser-plugin <file> --reasoning-parser nano_v3
RATCHET_STUDENT_BASE_MODEL nvidia/NVIDIA-Nemotron-3-Nano-4B-BF16 deploy kit Used by both. Base model

From Cost accounting in the configuration guide.

Variable Default Where Meaning
RATCHET_STUDENT_COST_MODEL per_token both Which savings the cost report’s headline (and /ratchet/stats cost.model) shows: per_token (the student priced per token at the hosted Nano price, as every figure since v0.1) or gpu_hours (the GPU-hours the student endpoint and the training jobs ran). The report always has both views, and each request’s cost_usd stays per token in both, so history never moves. Case and spaces are ignored; empty means per_token
RATCHET_STUDENT_GPU_USD_PER_HOUR 1.55 both USD per GPU-hour of the student endpoint (an L40S on-demand list price, nebius.com/prices, Oct 2026; unverified until the day-1 checks pass; 0 to 1,000). The default for python -m ratchet.cost endpoint up and POST /ratchet/cost/endpoint when they name no price, for the simulator’s intervals, and the price in the break-even
RATCHET_STUDENT_GPUS 1 both GPUs the student endpoint runs on (0 to 1,024) (1gpu-8vcpu-32gb in deploy/student_endpoint.sh). The endpoint costs this many times the per-GPU price per hour
RATCHET_TRAIN_GPU_USD_PER_HOUR 1.55 both USD per GPU-hour of a training job (the same L40S list price, unverified). Prices the training interval python -m ratchet.live night records around each training run, and the simulator’s
RATCHET_TRAIN_GPUS 1 both GPUs a training job runs on (RATCHET_TRAIN_PRESET)
RATCHET_PRICES_VERIFIED 0 both 1 once scripts/day1_check.py passed with a real key and the GPU rates above match your Nebius bill. Until then every report labels its prices “unverified list prices” (invariant 9); with 1 it says “prices confirmed by the operator”. Ratchet never sets it by itself

From Savings receipts in the configuration guide.

Variable Default Where Meaning
RATCHET_TAKE_RATE 0.25 both The fee’s share of a receipt’s billable lower bound (after spend outside requests), from 0 to 1. Stated in every receipt as a decimal string (billing.share). The fee is rounded down to a nano-USD and is 0 when the bound is negative or no task is calibrated
RATCHET_RECEIPT_MIN_AUDITS 30 both Audited answers a task needs, in one receipt, before its baseline is calibrated and its served answers are billed; a whole number from 2 to 1,000,000. Below it the task is insufficient_audits: its savings are reported at the formula and not billed. At a 10% audit rate, 30 audits take about 300 student-served answers of the task in a day (per client, for a client’s receipt)

Certified precision (Settings.cert_policy())

Section titled “Certified precision (Settings.cert_policy())”

From Certified precision (Settings.cert_policy()) in the configuration guide.

Variable Default Where Meaning
RATCHET_CALIBRATION point both How the threshold is chosen on the calibration half of the golden rows. point: the lowest threshold whose calibration answers reach 97% precision (v0.4’s rule; routing and the reference runs do not move). ltt: Learn-then-Test over the fixed grid 0.95, 0.90, …, 0.50, keeping the lowest threshold whose precision is above RATCHET_CERT_TARGET with probability at least 1 − RATCHET_CERT_DELTA (1.01, serve nothing, when the highest fails). Case is ignored; empty means point
RATCHET_CERT_TARGET 0.95 both The precision a certificate must show (certified when the lower bound reaches it), and Learn-then-Test’s target. Strictly between 0 and 1
RATCHET_CERT_DELTA 0.05 both The certificate’s error rate: the one-sided Clopper–Pearson bound holds with probability at least 1 − delta (the frontier’s rows at delta / 10 each). Strictly between 0 and 1

From Ledger and hot path in the configuration guide.

Variable Default Where Meaning
RATCHET_DB_SYNC NORMAL both How a ledger file is journaled, NORMAL or FULL (any case; empty means NORMAL). NORMAL: the WAL journal with synchronous=NORMAL. Readers never wait for the writer, the dashboard reads on a second, read-only connection, and a commit does not wait for the disk: a power cut or an operating-system crash (not a crash of the gateway process) can lose the last commits, never corrupt the file. FULL: the rollback journal with synchronous=FULL, v0.4’s behaviour, for a ledger on a filesystem without shared memory (a network or bucket mount, where WAL does not work) or when every commit must reach the disk before the client gets its answer. Give the gateway, the cron jobs and the cost CLI the same value: FULL cannot take a file out of WAL while another process has it open, and stops startup instead. Mock mode’s in-memory ledger has no journal to set (a bad value still stops startup)
RATCHET_TICK_INTERVAL_S unset: 5 in live mode, 0 in mock mode both Seconds between two release-gate ticks run from the request path (0 to 3600). A tick less than this after the previous one, or while another thread is ticking, is skipped, so requests pay for a tick at most once per interval and never wait for one. A rollback can wait this long; the cron python -m ratchet.live tick runs regardless. 0 ticks after every request (mock mode, so simulations and tests behave as before); the mock demo’s simulated days always tick
RATCHET_STATS_TTL_S unset: 2 in live mode, 0 in mock mode both Seconds /ratchet/stats serves one computed payload (0 to 3600). However many dashboards poll, it is computed at most once per TTL, by one caller at a time; the others get the previous payload. 0 computes it on every read

From Off-path quality checks in the configuration guide.

Variable Default Where Meaning
RATCHET_SIDECAR_WORKERS unset: 4 in live mode, 0 in mock mode both Threads that run requests’ audits and shadows after the answer is sent, 0 to 64. 0: every check stays on the request path, as before (mock mode’s default, so simulations, the reference runs and the demo are unchanged). Each worker holds at most one teacher call at a time (an audit, or an arbitration bounded to 60 s), so more workers spend the teacher’s rate limit faster, never more in total
RATCHET_SIDECAR_QUEUE 1000 both Jobs that may wait for a worker, 1 to 100,000. A tenth of the places (at least one, once there are two) is kept for jobs that carry an audit. Each job holds its request’s messages until it ends, so the request text queued and running jobs hold is bounded too, at 64 MiB (sidecar.MAX_BYTES, a tenth of it also kept for audits; at RATCHET_MAX_INPUT_CHARS’ default a job holds at most about 0.5 MB): past it the queue counts as full. A drawn audit is never dropped: with every place taken it runs on the request path instead (audits_inline). A shadow without a place does not run for that request (shadows_dropped), counted per version in /ratchet/stats sidecar and in ratchet_sidecar_full_total
RATCHET_SIDECAR_DRAIN_S 10 both Seconds the gateway’s shutdown waits for queued jobs, 0 to 3600, after the server stopped taking requests. Jobs still queued then never run: their rows stay pending (audited 1 with audit_agree NULL, shadow_version with shadow_serve NULL), which the release gate ignores, and one sidecar_dropped event counts them per version. Keep it under the process manager’s stop timeout: Docker sends SIGKILL 10 s after SIGTERM by default; the demo VM’s Compose file gives the gateway 20 s (stop_grace_period), so raise both together

From Observability in the configuration guide.

Variable Default Where Meaning
RATCHET_LOG_FORMAT unset: text in mock mode, json in live mode both How the ratchet logger writes to stderr: json (one object per line: ts, level, logger, event, then the fields) or text (<ts> <LEVEL> <event> key=value ...), any case. Lines carry ids, names, numbers and statuses, never prompt or answer text, URLs or keys
RATCHET_LOG_LEVEL unset: WARNING in mock mode, INFO in live mode both DEBUG, INFO, WARNING or ERROR, any case. INFO writes one chat line per chat request (request id, client request id, trace id, client name, task, served_by, route, version, confidence, escalated, audited, latency_ms, wall_ms, cost_usd, status; retry_count on a retry, idempotent_replay and replay_of on an answer sent again for an Idempotency-Key, whose cost_usd is 0, and overhead_pending when its checks run after the answer), one offpath line when those checks end (row, audited, audit_agree, shadow_version, shadow_serve, shadow_agree, stored, the cost_usd they added, pending_ms; the same request id, so the two lines’ costs add up to the row’s) and every release-log event (ledger_event, scrubbed of URLs and error messages); WARNING keeps the upstream_error lines (role, exception class, status), so mock mode and the tests stay quiet
RATCHET_METRICS_TOKEN empty both A bearer token that reads GET /metrics (and nothing else), for a Prometheus scraper, besides the admin and dashboard keys. At least 16 characters; it may not also be an API, admin or dashboard key (startup error). Compared as a constant-time digest, never stored or logged. Empty: only admin and dashboard keys read a private /metrics. A public dashboard (RATCHET_PUBLIC_DASHBOARD=1) makes /metrics public too

From Configuration checks in the configuration guide.

Variable Default Where Meaning
RATCHET_STRICT_CONFIG unset (off) both 1: a warning stops startup like an error, and python -m ratchet.config check exits 2 on it. 0 or unset: warnings start the gateway; each is kept in Runtime.config_warnings, logged once as a config_warning line (the variable and the message, never the value) and counted under checks.config in /readyz. Anything but 0 or 1 is an error

From Release policy (ratchet/release.py) in the configuration guide.

Variable Default Where Meaning
RATCHET_MIN_PRECISION 0.95 both Field min_precision. Golden gate and shadow: minimum precision of answers the candidate would serve
RATCHET_MIN_COVERAGE 0.25 both Field min_coverage. Golden gate: minimum share of golden traffic it would serve
RATCHET_TOLERANCE 0.02 both Field tolerance. Max allowed drop vs live (precision and coverage) in the golden gate, and coverage vs live in shadow
RATCHET_MIN_SHADOW 100 both Field min_shadow. Would-serve shadow answers needed before a shadow decision
RATCHET_MIN_AUDITS 20 both Field min_audits. Teacher audits needed in a canary stage before it is promoted, and before the Wilson rules roll back or alert. The anytime-valid rules have no minimum for a rollback or an alert
RATCHET_LIVE_FLOOR 0.92 both Field live_floor. Audited precision floor. The Wilson rule rolls back when the Wilson upper bound is below it; the e-processes test “precision at or above the floor”. Strictly between 0 and 1
RATCHET_MIN_TASK_TEST_N 10 both Field min_task_test_n. Held-out (odd-half) golden rows a task needs before the golden gate checks its own numbers (per-task calibration, FR-14.1). A whole number, 0 or more
RATCHET_TASK_MODE disable both Field task_mode. What the golden gate does with a task that fails its own check: disable it on the candidate (its threshold becomes 1.01, a task_disabled event; the version ships for its other tasks) or reject the candidate. Case and surrounding spaces are ignored; empty means the default
RATCHET_SEQUENTIAL 0 both Field sequential. 1 switches the canary to the anytime-valid rule: rollback when the e-value over every audit the canary has had reaches 1/alpha_rollback, with no minimum count; promotion on this stage’s audits (point estimate, or evidence with promote_evidence); retirement at max_stage_audits. 0: the Wilson rule above. 0 or 1
RATCHET_ALPHA_ROLLBACK 0.05 both Field alpha_rollback. Sequential rule: the chance of ever rolling back a version whose precision stays at or above the floor (threshold 1/alpha: 20). Strictly between 0 and 1
RATCHET_PROMOTE_EVIDENCE 0 both Field promote_evidence. 1 promotes a canary stage only when the e-value that precision is above the floor reaches 1/alpha_promote (56 audits that all agree at a 0.92 floor and 5%), instead of on the point estimate. Needs sequential=1. 0 or 1
RATCHET_ALPHA_PROMOTE 0.05 both Field alpha_promote. Sequential rule with promote_evidence: the chance that a version at or below the floor reaches live. Strictly between 0 and 1
RATCHET_MAX_STAGE_AUDITS 400 both Field max_stage_audits. Sequential rule: a canary stage with this many audits and no decision is retired (event inconclusive); 0 = never. It counts audits, not time. Must be at least min_audits, and with promote_evidence at least the audits a promotion needs (startup says how many)
RATCHET_ALERT_EPROCESS 1 both Field alert_eprocess. 1: the live alert fires when the e-value against “precision at or above the floor” over the audits since the version went live reaches 1/alpha_alert, with no minimum count. 0: the Wilson rule (at least min_audits audits and the upper bound below the floor). 0 or 1
RATCHET_ALPHA_ALERT 0.01 both Field alpha_alert. The live alert’s error rate: a live version at or above the floor is alerted on with probability at most this (threshold 1/alpha: 100). Strictly between 0 and 1
RATCHET_MIN_CERTIFIED_PRECISION 0.0 both Field min_certified_precision. Golden gate: reject a candidate whose certified lower bound on precision (recomputed from its certificate’s counts) is below this, or that has no certificate. 0: off. From 0 to 1
RATCHET_PAIRED_GATE 0 both Field paired_gate. 1: the golden gate’s regression check compares the candidate with the re-scored live version row by row on the same held-out rows (the candidate’s paired record), instead of the two point estimates within tolerance. It rejects only a regression that is both larger than tolerance (as a share of the rows) and significant (exact McNemar, regression_alpha), on coverage or on wrong answers, or a negative flip rate above max_nfr. Without a paired record against the live version it falls back to the unpaired rule. 0 or 1
RATCHET_REGRESSION_ALPHA 0.05 both Field regression_alpha. The paired gate’s error rate for each McNemar test: a candidate no worse than live is rejected with probability at most this. Strictly between 0 and 1
RATCHET_MAX_NFR 1.0 both Field max_nfr. The paired gate: reject when the 95% Wilson lower bound of the negative flip rate (answers live served right that the candidate serves wrong) is above this. 1: off. More than 0 and at most 1

From Reserved settings in the configuration guide.

Variable Default Where Meaning
RATCHET_TEACHER_PROBES 20 reserved Teacher watch (FR-16.7): stored labels re-asked per night
RATCHET_ADJUDICATE_MAX 50 reserved Teacher watch (FR-16.7): contested labels adjudicated per night
RATCHET_BATCH_API operations reserved Clean-room backfill (FR-16.8): the Token Factory batch API (operations or openai)
RATCHET_BATCH_DISCOUNT 0.5 reserved Clean-room backfill (FR-16.8): the batch price discount (unverified, like every price)
RATCHET_BACKFILL_MAX_TOKENS 2048 reserved Clean-room backfill (FR-16.8): the output cap the worst-case budget is computed from
RATCHET_DRIFT_ALARM 100 both Field drift_alarm. Drift alarm (FR-16.6): the test martingale’s alarm threshold (false-alarm probability at most 1/threshold per stream)
RATCHET_DRIFT_AUDIT_BOOST 1.0 both Field drift_audit_boost. FR-16.6: the audit-rate multiplier after an alarm (1: off)
RATCHET_DRIFT_EARLY_NIGHT 0 both Field drift_early_night. FR-16.6: 1 halves the new examples Night School needs after an alarm
RATCHET_TEACHER_NOISE_MAX 0.05 both Field teacher_noise_max. Teacher watch (FR-16.7): the teacher disagreement rate it tolerates
RATCHET_ALPHA_TEACHER 0.01 both Field alpha_teacher. FR-16.7: the teacher watch’s error rate

From Tasks in the configuration guide.

Variable Default Where Meaning
RATCHET_TASKS_FILE empty both A file of task specs (Adding a task), JSON, or YAML for a .yaml or .yml file (needs PyYAML: pip install pyyaml, or the yaml extra). Read when the gateway starts (and on a mock demo reset) and by python -m ratchet.live. A file task may replace a built-in one. A bad file stops startup with every error and its path (tasks[2].fields.total.abs_tol: must be a number >= 0); a YAML file without PyYAML is an error that says so
RATCHET_UNKNOWN_TASKS distill both What a request naming a task that is not registered gets. distill (v0.4): a task without fields made up for the name, distilled like any other. teacher: the teacher answers (route unknown_task), the student is not called and nothing is stored. reject: 400 unknown_task, listing the registered tasks the key may use. Under teacher and reject an X-Ratchet-Task header that is not a valid task name is a 400 unknown_task too (under distill it means default, as in v0.4). Case-insensitive; anything else stops startup
RATCHET_MAX_AUTO_TASKS 200 both Most auto tasks (derived from a request’s response_format json_schema, Structured outputs) the registry holds, counted from the stored and new ones. Past it a request with a new schema gets an unregistered task of its auto name, which RATCHET_UNKNOWN_TASKS decides about (under reject, a 400 until an admin deletes auto tasks), and one auto_task_cap event is written. 0 turns auto tasks off: a json_schema request then keeps the task it names (an unregistered name follows RATCHET_UNKNOWN_TASKS), or default when it names none, and the schema only binds its answers, as before auto tasks; no request is refused for having a schema. A whole number from 0 to 500 (the registry’s size); anything else stops startup
RATCHET_SCHEMA_REPAIR 1 both 0: no repair call. Otherwise a complete teacher answer that breaks its request’s response_format gets one more call to the same teacher, shown its answer and the schema errors; the repaired answer is served (unless it was cut off or is empty: the first answer is then kept) and, when valid, stored with the request’s own messages. Both calls are paid for in cost_usd; the baseline and the client’s usage.prompt_tokens count the request’s own prompt, and latency_ms both calls. Read in ratchet/config.py, used by ratchet/router.py (Ratchet._repair)
RATCHET_FIXTURES_DIR fixtures both Where fixture files a task spec names must live (taskspec.resolve_fixture: a path that resolves outside it, through .. or a symlink, is refused). For the reserved sql format

From Teacher licenses in the configuration guide.

Variable Default Where Meaning
RATCHET_TEACHER_LICENSES empty both A JSON file: a list of {"model", "license", "url", "note"} objects (note optional, at most 100 entries). Read at startup by the gateway (and on a mock demo reset), the simulator, python -m ratchet.live and python -m ratchet.admin, and merged into a copy of the built-in registry. The configured teachers can then be RATCHET_TEACHER_MODEL or RATCHET_TEACHER_FALLBACK_MODEL, Night School trains on their stored answers, and each adapter’s BOM and NOTICE.md name them with license_origin config. A bad file stops startup with every error and its place ([2].license: 'CC-BY-NC-4.0' is not an allowed license; ...). Empty = the built-in registry only

1 variable(s) the code reads have no row in the configuration guide yet: RATCHET_GATEWAY_LEASE. The traceability check (python scripts/reqtrace.py --check) is meant to catch this.