Skip to content

Configuration keys

Reference

Every key TelhaConfig accepts, its type, default, TELHA_* environment override, and a one-line description. This is a strict schema: unknown keys in a TOML file are rejected (deny_unknown_fields), and the environment provider only accepts the keys listed here.

Layering

Precedence, lowest to highest: built-in defaultsTOML config file (--config / TELHA_CONFIG) → TELHA_* environment variablesCLI flags. Nested keys use __ (double underscore) as the environment separator, e.g. rest.addr becomes TELHA_REST__ADDR. Only the keys in the tables below are read from the environment; unrelated TELHA_* variables (like TELHA_CONFIG itself, which belongs to the CLI) never leak into the config figment.

Gotcha: all-digit values parse as integers

The environment layer (figment) infers types from the string value. A value made entirely of digits, such as a grpc.token_key that happens to be all-numeric hex, is parsed as an integer and rejected because the field expects a string. Regenerate the key until it contains at least one letter (openssl rand -hex 32 almost always does, but check). See Operators › Configuration and the deployment runbook for the full rotation flow.

data_dir

Key Env Type Default Description
data_dir TELHA_DATA_DIR path ./data Directory holding RocksDB column families, vector partitions, and other engine state. Created on serve if missing.

[rest]

Key Env Type Default Description
rest.addr TELHA_REST__ADDR socket addr 127.0.0.1:7625 Socket address for the REST listener. Port 0 binds ephemerally.

[grpc]

Key Env Type Default Description
grpc.addr TELHA_GRPC__ADDR socket addr 127.0.0.1:7626 TCP socket address for the gRPC listener.
grpc.uds_path TELHA_GRPC__UDS_PATH path (optional) none Unix domain socket path, preferred over TCP for same-host app-layer traffic on Unix. Ignored with a warning on Windows.
grpc.token_key TELHA_GRPC__TOKEN_KEY string (optional) none Hex-encoded 32-byte HMAC key that signs and validates every internal service token (app, worker, mcp, clarify, admin, connector audiences). gRPC and MCP stay disabled until this is set. Must contain at least one non-digit character (see the gotcha above).

[log]

Key Env Type Default Description
log.level TELHA_LOG__LEVEL string info Tracing filter directive, e.g. info or telha_core=debug,info.
log.format TELHA_LOG__FORMAT enum: json|pretty json json for production (structured lines), pretty for local development.

[storage]

Key Env Type Default Description
storage.block_cache_mb TELHA_STORAGE__BLOCK_CACHE_MB u64 256 Shared RocksDB block cache size in MiB.
storage.sync_writes TELHA_STORAGE__SYNC_WRITES bool true Fsync the WAL on every write batch. Turning this off trades crash-durability of the most recent writes for throughput.

[global_scan]

Key Env Type Default Description
global_scan.horizon_days TELHA_GLOBAL_SCAN__HORIZON_DAYS u32 3653 (10 years) Iteration stops once a candidate's validTimeStart drops more than this many days below the queried instant. Records older than the horizon that are still valid would be missed, so size generously.
global_scan.max_rows_scanned TELHA_GLOBAL_SCAN__MAX_ROWS_SCANNED u64 1_000_000 Hard row-scan ceiling; exceeding it returns partial-with-warning.
global_scan.max_page_size TELHA_GLOBAL_SCAN__MAX_PAGE_SIZE usize 1_000 Upper bound on a single page of results.

[decay]

Key Env Type Default Description
decay.default_weight TELHA_DECAY__DEFAULT_WEIGHT f64, (0, 1] 0.7 Per-hop weight for edge types without an override.
decay.floor TELHA_DECAY__FLOOR f64, [0, 1) 0.05 Decay floor ε: paths are pruned (not expanded) below this value.
decay.fusion_alpha TELHA_DECAY__FUSION_ALPHA f64, [0, 1] 0.6 Fusion balance α: S = sim^α · decay^(1−α). Per-query override via vector.alpha.
decay.weights.<EDGE_TYPE> TOML only f64, (0, 1] none Per-edge-type weight overrides, e.g. weights.OWNS = 0.9. Not on the env allowlist; set via TOML.

[bitmap]

Key Env Type Default Description
bitmap.enabled TELHA_BITMAP__ENABLED bool false Master switch for the roaring-bitmap predicate accelerator. Enabling on an existing dataset requires telha index rebuild-bitmaps first.
bitmap.max_values_per_property TELHA_BITMAP__MAX_VALUES_PER_PROPERTY u32 10_000 Distinct eq-values per property before it overflows to a full scan.
bitmap.candidate_ratio TELHA_BITMAP__CANDIDATE_RATIO f64, [0, 1] 0.3 The bitmap path is chosen only when candidates < watermark × ratio.
bitmap.range_bands TOML only u8 16 Range bands for range predicates. v1 supports exactly 16; any other value fails validation.

[jobs]

Key Env Type Default Description
jobs.lease_ttl_secs TELHA_JOBS__LEASE_TTL_SECS u64 300 Lease TTL in seconds; a Heartbeat call extends it.
jobs.reaper_interval_secs TELHA_JOBS__REAPER_INTERVAL_SECS u64 30 Reaper wake interval in seconds.
jobs.max_attempts TELHA_JOBS__MAX_ATTEMPTS u32 5 Attempts before a job dead-letters.
jobs.backoff_base_secs TOML only u64 10 Retry backoff base, seconds (exponential).
jobs.backoff_factor TOML only u64 4 Retry backoff factor.
jobs.backoff_cap_secs TOML only u64 3_600 Retry backoff cap, seconds.
jobs.backoff_base_secs_by_kind.<KIND> TOML only u64 empty map Per-kind backoff base overrides; an override also lifts the cap to at least itself. Populated internally (e.g. clarify:temporal); not an env-layer key.

[ingest]

Key Env Type Default Description
ingest.json_nested TOML only enum: flatten|child flatten Default nested-object policy for format=json. flatten turns nested objects into dotted property keys (address.city); child makes them child nodes linked by HAS_<KEY> edges. Overridable per-request via options.nested.
ingest.json_max_depth TOML only usize 8 Nesting-depth ceiling for the JSON direct path.
ingest.json_max_records TOML only usize 10_000 Top-level record ceiling per JSON request.

[embedding]

The embedding subsystem activates when both endpoint and model are set.

Key Env Type Default Description
embedding.endpoint TOML only string "" OpenAI-compatible endpoint base (e.g. https://api.openai.com/v1, or a local server). Empty disables embedding.
embedding.api_key_env TOML only string TELHA_EMBEDDING_API_KEY Env var NAME holding the bearer token (empty = unauthenticated local endpoint).
embedding.model TOML only string "" Default model for ingestion fan-out; must be registered (telha vector register-model). Empty disables automatic fan-out.
embedding.batch_size TOML only usize 96 Max texts per provider call.
embedding.max_text_bytes TOML only usize 32768 (32 KiB) Truncation ceiling for assembled node text.
embedding.poll_interval_secs TOML only u64 5 Embed-runner poll interval, seconds.
embedding.timeout_secs TOML only u64 60 Provider request timeout, seconds.

[vector]

Partitioned-HNSW settings.

Key Env Type Default Description
vector.bucket TOML only enum: week|month|quarter month Time-bucket size for partitions (week = 7d, month = 30d, quarter = 90d).
vector.seal_grace_secs TOML only u64 172_800 (48h) Seconds past a bucket's end before its open partition seals; a late-arriving backfill grace period.
vector.memory_budget_mb TOML only u64 4096 Memory budget for loaded sealed partitions; an LRU evicts above it.
vector.ef_search TOML only usize 64 Default ef_search; a per-query override is bounded by 4× this.
vector.hnsw_m TOML only usize 16 HNSW connectivity (M).
vector.hnsw_ef_construction TOML only usize 200 HNSW build-time expansion (ef_construction).

[mcp]

The MCP listener starts only when enabled is true and grpc.token_key is set.

Key Env Type Default Description
mcp.enabled TELHA_MCP__ENABLED bool true Master switch for the MCP listener.
mcp.addr TELHA_MCP__ADDR socket addr 127.0.0.1:7627 Socket address for the MCP streamable-HTTP listener.
mcp.max_rows TELHA_MCP__MAX_ROWS usize 50 Hard cap on rows any tool returns.
mcp.max_field_chars TELHA_MCP__MAX_FIELD_CHARS usize 500 Per-field text cap in characters; longer values truncate with an ellipsis and a full-fetch hint.
mcp.specs_resource TOML only bool true Expose .ai/specs/**/*.md as the specs:// MCP resource.
mcp.specs_dir TELHA_MCP__SPECS_DIR path ./.ai/specs Directory the specs:// resource reads from. Relative paths resolve against the process working directory.

[planner]

Evidence-planner settings. All ratios are validated at load and never silently clamped.

Key Env Type Default Description
planner.default_budget TELHA_PLANNER__DEFAULT_BUDGET u64 6_000 Default token budget B when the request supplies none. The effective budget is min(B, floor(model_ctx × 0.5)) when the provider reports a context window.
planner.max_frac_per_source TELHA_PLANNER__MAX_FRAC_PER_SOURCE f64, (0, 1] 0.4 Hard per-source diversity cap: at most this fraction of B may come from spans of one source_id. Never relaxed; stranded budget is reported in stats instead.
planner.cache_discount TELHA_PLANNER__CACHE_DISCOUNT f64, (0, 1) 0.5 Weight multiplier for cache-class (derived) spans.
planner.dedup_overlap TELHA_PLANNER__DEDUP_OVERLAP f64, (0.5, 1] 0.8 Same-source span overlap above which the lower-weight span is dropped.
planner.kind_priors.<KIND> TOML only f64, (0, 1] paragraph=1.0, heading=0.6, cell=0.8, code=0.9 Span-kind weight priors; the single source of truth for span-kind weighting. Kinds absent from the map take prior 1.0.

[llm]

The generation subsystem activates when provider is set. There is deliberately no credential field: keys come from the env var named by api_key_env or from secrets_file, never from config files.

Key Env Type Default Description
llm.provider TELHA_LLM__PROVIDER enum: anthropic|openai_compat (optional) none Provider protocol; unset disables generation.
llm.endpoint TELHA_LLM__ENDPOINT string "" Provider endpoint base. Must be https unless the host is loopback (localhost, 127.0.0.1/other loopback IPv4, or [::1]): plaintext http to a remote host would put the Authorization header on the wire.
llm.api_key_env TELHA_LLM__API_KEY_ENV string TELHA_LLM_API_KEY Env var NAME holding the API key.
llm.secrets_file TELHA_LLM__SECRETS_FILE string "" Alternative to api_key_env: a file whose entire trimmed content is the key. Refused on unix unless permissions are 0600 or tighter; on Windows this is a logged warning only.
llm.model_default TELHA_LLM__MODEL_DEFAULT string "" Default generation model. Required when provider is set.
llm.models_allowed TOML only array of string [] Model allowlist. Requests naming a model outside models_allowed ∪ {model_default} are rejected with 400.
llm.max_output_tokens TELHA_LLM__MAX_OUTPUT_TOKENS u64 4_096 Per-request output-token ceiling, independent of the tenant budget.
llm.timeout_s TELHA_LLM__TIMEOUT_S u64 120 Provider request timeout, seconds.
llm.tenant_caps.daily_tokens TELHA_LLM__TENANT_CAPS__DAILY_TOKENS u64 0 (unlimited) Default per-tenant input+output token cap per daily window.
llm.tenant_caps.monthly_tokens TELHA_LLM__TENANT_CAPS__MONTHLY_TOKENS u64 0 (unlimited) Default per-tenant input+output token cap per monthly window.

[verify]

Claim-verification settings.

Key Env Type Default Description
verify.beta TELHA_VERIFY__BETA f64, (0, 1) 0.65 Geometric fusion balance β for claim↔span matching: match = clamp01(cos)^β · lex^(1−β). 0/1 are formula fast-paths, not valid config.
verify.bands.supported TELHA_VERIFY__BANDS__SUPPORTED f64 0.75 Claim score ≥ this → verdict supported. Overrides are bounded to ±0.1 of the default.
verify.bands.partial TELHA_VERIFY__BANDS__PARTIAL f64 0.50 Claim score in [partial, supported)partial; below → unsupported. Overrides bounded to ±0.1 of the default; supported must stay ≥ partial + 0.10 (no band collapse).
verify.candidates_m TELHA_VERIFY__CANDIDATES_M usize 8 Top-m plan spans by embedding similarity added to each claim's candidate set (cited markers are always candidates).
verify.policy TELHA_VERIFY__POLICY enum: flag|redact flag Unsupported-claim policy: flag annotates and delivers the draft unchanged; redact replaces unsupported claims with an omission notice.
verify.decompose_model TELHA_VERIFY__DECOMPOSE_MODEL string "" Model used for claim decomposition; empty uses the generation model.
verify.embed_model TELHA_VERIFY__EMBED_MODEL string "" Embedding model for claim↔span similarity; empty uses the request's semantic model, else embedding.model. Claims and spans embed under one model only.

[compare]

Key Env Type Default Description
compare.max_scan_rows TELHA_COMPARE__MAX_SCAN_ROWS u64 2_000_000 Hard version-row scan ceiling per /v1/compare request; beyond it the page returns partial-with-warning and a resume cursor.

[clarify]

Ships disabled until a bot surface is configured.

Key Env Type Default Description
clarify.enabled TELHA_CLARIFY__ENABLED bool false Master switch: gates CLARIFICATION creation, clarify:temporal job enqueue, and the capability flag advertised to workers.
clarify.escalation_window_hours TELHA_CLARIFY__ESCALATION_WINDOW_HOURS u64 48 Hours before an undelivered/unanswered candidate escalates to the next ranked person; also the clarify:temporal backoff base.
clarify.max_candidates TELHA_CLARIFY__MAX_CANDIDATES usize 3 Ranking length ceiling. Steward escalation is always attempt ranking+1 and does not count against this.
clarify.per_person_daily_cap TELHA_CLARIFY__PER_PERSON_DAILY_CAP u32 5 Per-person daily question cap, enforced by the delivery surface.
clarify.digest_threshold TELHA_CLARIFY__DIGEST_THRESHOLD u32 3 Questions targeting one person inside the digest window before delivery batches into a digest.
clarify.digest_window_minutes TELHA_CLARIFY__DIGEST_WINDOW_MINUTES u64 30 Digest batching window, minutes.
clarify.redact_fallback TELHA_CLARIFY__REDACT_FALLBACK bool true When no candidate passes the read gate, send the steward a redacted question (document link, no span text).
clarify.channels TELHA_CLARIFY__CHANNELS string teams,slack Comma-separated delivery surfaces, consumed by the clarify-bot.
clarify.quorum.enabled TELHA_CLARIFY__QUORUM__ENABLED bool true Whether critical severity requires multi-confirmation at all.
clarify.quorum.critical_required_confirmations TELHA_CLARIFY__QUORUM__CRITICAL_REQUIRED_CONFIRMATIONS u32 2 Matching binding-capable confirmations required to bind a critical clarification.
clarify.quorum.required_roles TOML only array of string ["editor"] Minimum rights whose responses count toward quorum. Each must be viewer|editor|steward.
clarify.quorum.allow_steward_override TELHA_CLARIFY__QUORUM__ALLOW_STEWARD_OVERRIDE bool true Whether a steward may bind single-handedly via an explicit override.
clarify.severity.high_notifies_steward TELHA_CLARIFY__SEVERITY__HIGH_NOTIFIES_STEWARD bool true Notify the steward when a high-severity question is asked.
clarify.severity.elevate.<KIND> TOML only string (severity) empty map Kind → minimum severity elevation, e.g. elevate.conflicting_dates = "high". Values must be low|normal|high|critical.

[backup]

Key Env Type Default Description
backup.enabled TELHA_BACKUP__ENABLED bool false Run periodic backups from the serving process. Requires backup.dir to be set.
backup.dir TELHA_BACKUP__DIR path (optional) none Backup target directory; stamp dirs are created inside it.
backup.interval_hours TELHA_BACKUP__INTERVAL_HOURS u64 24 Hours between ticker runs.
backup.keep TELHA_BACKUP__KEEP usize 7 Stamps retained; older ones prune after a verified create. 0 disables pruning.
backup.pg_database_url_env TELHA_BACKUP__PG_DATABASE_URL_ENV string DATABASE_URL Env var NAMING the app-layer PostgreSQL URL for the two-surface capture. Unset env means core-only backups, marked partial.

[retention]

Key Env Type Default Description
retention.enabled TELHA_RETENTION__ENABLED bool false Run the periodic retention pass from the serving process. Requires retention.archive_dir or backup.dir to be set.
retention.interval_hours TELHA_RETENTION__INTERVAL_HOURS u64 24 Hours between system:retention runs.
retention.orphan_ttl_days TELHA_RETENTION__ORPHAN_TTL_DAYS u64 14 Age (days) past which dead provisional streamed source versions (canonical hash None) are swept, with no policy opt-in required.
retention.archive_dir TELHA_RETENTION__ARCHIVE_DIR path (optional) none Archive slice target directory. Defaults under {backup.dir}/archives when unset.
retention.max_entities_per_run TELHA_RETENTION__MAX_ENTITIES_PER_RUN usize 10_000 Per-run entity ceiling; bounded runs resume next interval, and the remaining backlog is reported.

[watch]

The CLI/REST/MCP watch surfaces work regardless of enabled; the flag gates only the in-process evaluator ticker.

Key Env Type Default Description
watch.enabled TELHA_WATCH__ENABLED bool false Run the periodic evaluator sweep from the serving process.
watch.eval_interval_secs TELHA_WATCH__EVAL_INTERVAL_SECS u64 60 Seconds between evaluator ticks.
watch.max_watches_per_tenant TELHA_WATCH__MAX_WATCHES_PER_TENANT usize 1000 Per-tenant watch ceiling; create returns WATCH_LIMIT at the cap.
watch.max_rows_per_tick TELHA_WATCH__MAX_ROWS_PER_TICK u64 50_000 Bounded sweep: tx-index rows scanned per tenant per tick. The backlog resumes next tick.
watch.debounce_default_secs TELHA_WATCH__DEBOUNCE_DEFAULT_SECS u64 3600 Default coalescing window (seconds) when a watch omits one.
watch.debounce_floor_secs TELHA_WATCH__DEBOUNCE_FLOOR_SECS u64 60 Floor on any watch's coalescing window.
watch.max_events_per_fire TELHA_WATCH__MAX_EVENTS_PER_FIRE usize 100 Cap on events carried in a single fire; excess sets truncated.
watch.query_watch_max_results TELHA_WATCH__QUERY_WATCH_MAX_RESULTS usize 1000 Row ceiling for a query watch's result fingerprint.
watch.suspend_after_gate_denials TELHA_WATCH__SUSPEND_AFTER_GATE_DENIALS u32 5 Consecutive fire-time gate denials before a watch auto-suspends.
watch.webhook_timeout_secs TELHA_WATCH__WEBHOOK_TIMEOUT_SECS u64 10 Webhook delivery timeout, seconds.
watch.webhook_max_attempts TELHA_WATCH__WEBHOOK_MAX_ATTEMPTS u32 3 Webhook delivery attempts before dead-letter and watch suspend.
watch.fire_keep_per_watch TELHA_WATCH__FIRE_KEEP_PER_WATCH usize 1000 Durable WatchFire rows kept per watch (pruned oldest-first); the audit sink stays the unbounded record.

[erasure]

Deliberately minimal: masking semantics, the blocklist check, verification-before-close, ledger emission, dual approval, replay-before-serve, archive supersession, and the strong-identifier zero gate are doctrine, not knobs. None of these keys are on the environment allowlist; set them via TOML.

Key Env Type Default Description
erasure.backup_horizon_days TOML only u64 35 Backups older than this age out naturally; the completion report records the date after which no backup contains the erased data.
erasure.log_retention_days_max TOML only u64 30 Operational log retention bound attested in the completion report.
erasure.log_targets TOML only array of string app_logs, worker_logs, reverse_proxy_logs, job_runner_logs, cloud_provider_logs, error_tracking, support_exports Log targets the operator attests are covered by the retention bound.
erasure.per_subject_log_scrub_supported TOML only bool false Whether this deployment supports per-subject log scrubbing (v1 core: no). Attested in the completion report.
erasure.expect_pg_stage TOML only bool false Whether an app-layer PostgreSQL stage is expected to report before verification. Deployments without the app layer record the stage not_applicable with a loud warning.
  • CLI reference - telha check-config prints the fully resolved TOML; RunArgs flags override the highest layer.
  • Glossary - definitions for terms like decay, fusion, KEK/DEK, and quorum used in the descriptions above.
  • Operators › Configuration - the narrative guide to configuring a deployment section by section.
  • Deployment runbook - grpc.token_key generation, rotation, and the key inventory.