Skip to content

Configuration Reference

Wraith uses two TOML files per twin workspace to control behaviour and security policy.

twins/<name>/
├── wraith.toml # Twin behaviour, thresholds, generation settings
└── scrub.toml # Security scrubbing rules

Both are created automatically by wraith init.


FieldTypeDefaultDescription
namestringTwin name (directory name under twins/)
base_urlstringUpstream API base URL
specstringOptional path to OpenAPI spec
FieldTypeDefaultDescription
modestring"reverse"Proxy mode: reverse or forward
portu168080Port the recording proxy binds to
FieldTypeDefaultDescription
portu168081Port the twin server binds to
session_modestring"header"Session isolation: header, cookie, or path
fidelitystring"synth"Response mode: strict, synth, permissive
deterministic_seedu6442Seed for deterministic random generation
debugboolfalseEnable debug response headers
FieldTypeDefaultDescription
modestring"none"none, recorded, scaled, or fixed
min_msu640Minimum simulated latency (ms)
max_msu645000Maximum simulated latency (ms)
multiplierf641.0Multiply recorded latency by this factor
FieldTypeDefaultDescription
max_entities_per_typeu6410000Max entities per resource type
max_total_state_mbu64100Max in-memory state (MB)
max_namespacesu641000Max concurrent session namespaces
request_drain_timeout_msu645000Graceful shutdown drain timeout (ms)
FieldTypeDescription
limitu64Max requests per window
window_secondsu64Window duration in seconds
FieldTypeDefaultDescription
required_scoref640.90Minimum overall conformance score
session_pass_ratef640.95Minimum fraction of passing sessions
scoring_versionu321Scoring algorithm version
FieldTypeDefaultDescription
status_exact_matchbooltrueRequire exact HTTP status match
body_structuref640.90Min structural similarity [0, 1]
body_valuesf640.85Min value similarity [0, 1]
symbol_consistencyf641.0Required symbol/token consistency
header_conformancef640.80Min response header conformance

Per-route threshold overrides. Same fields as [diff.thresholds] but all optional.

[diff.overrides."POST /v1/charges"]
body_structure = 0.95
body_values = 0.95

Override field classifications for specific JSON paths. Use hole-style paths (no body. prefix — it’s added automatically).

FieldTypeRequiredDescription
classifystringyes"generated", "timestamp", "constant", or "echoed"
valuesstring[]noAllowed values when classify = "enum"
[diff.fields]
# Force exact comparison on computed fields (not auto-suppressed)
"total" = { classify = "constant" }
"summary.total_value" = { classify = "constant" }
# Treat a field as a timestamp (type-only comparison)
"expires_at" = { classify = "timestamp" }

User-supplied classifications always override auto-detected ones.

Suppress specific divergences by route, path, and/or category. Supports * wildcards.

FieldTypeRequiredDescription
routestringnoRoute pattern (e.g. "POST /repos/*")
pathstringnoJSON path (e.g. "body.created_at")
categorystringnoDivergence category (e.g. "value_mismatch")
reasonstringyesHuman-readable explanation
[[diff.suppress]]
path = "body.created_at"
reason = "twin uses placeholder timestamps"
[[diff.suppress]]
route = "POST /repos/*/statuses/*"
category = "value_mismatch"
reason = "commit status fields are state-dependent"

Suppressed divergences are excluded from scoring but listed by --show-suppressed.

FieldTypeDefaultDescription
max_iterationsu3210Max agent optimisation iterations
token_budgetu64200000LLM token budget per generation run
time_budget_minutesu3230Time limit for generation run
regression_tolerancef640.0Acceptable conformance regression
FieldTypeDefaultDescription
entropy_thresholdf644.5Shannon entropy cutoff for symbol detection
min_string_lengthu324Ignore strings shorter than this
exclude_urlsbooltrueDon’t symbolise URL-like values
exclude_natural_languagebooltrueDon’t symbolise natural language
field_name_hintingbooltrueUse field names to guide symbolisation
FieldTypeDefaultDescription
min_exchanges_per_routeu323Min exchanges before pattern extraction
low_confidence_thresholdf640.20Below this, route is flagged low-conf
array_modestring"schema"schema or element
FieldTypeDefaultDescription
numeric_idsbooltrueCollapse /users/123 -> /users/:id
prefix_pattern_idsbooltrueCollapse prefix-style IDs
value_flow_confirmationbooltrueUse value-flow graph to confirm
structural_alignmentboolfalseExperimental structural alignment
FieldTypeDefaultDescription
algorithmstring"decision_tree"decision_tree or rule_list
max_depthu324Max decision tree depth
z3_minimizationboolfalseUse Z3 to minimise guards
FieldTypeDefaultDescription
cross_route_unificationbooltrueUnify types across routes
enum_max_valuesu325Max distinct values before non-enum
enum_min_samplesu323Min samples to confirm enum type
FieldTypeDefaultDescription
default_runnerstring?Default LLM runner name
fallbackstring[][]Fallback runner chain
air_gappedboolfalseDisable all network-based runners
FieldTypeDefaultDescription
commandstringRunner executable
argsstring[][]Command-line arguments
formatstring?Output format (json, etc.)
FieldTypeDefaultDescription
sample_strategystring"risk_weighted"risk_weighted, random, coverage
budget_requestsu64500Max requests per refresh cycle
FieldTypeDefaultDescription
max_sessionsu641000Max recording sessions retained
max_total_size_mbu645000Max total recording size (MB)
retention_daysu6490Delete recordings older than this
max_body_size_mbu6410Max body size per exchange (MB)
FieldTypeDefaultDescription
enabledboolfalseForward unmatched requests to upstream
allowstring[][]Route patterns allowed for passthrough

FieldTypeDefaultDescription
scrub_auth_headersbooltrueAuto-scrub Authorization, Cookie
scrub_cookiesbooltrueAuto-scrub Set-Cookie values
tokenize_modeTokenizeMode"hmac"Default action: hmac, redact, mask

User-defined scrub rules are applied in order after built-in rules.

FieldTypeRequiredDescription
scopeScrubScopeyesheader, cookie, jsonpath, regex, query_param
matchstringyesPattern to match (name, JSONPath, or regex)
actionScrubActionyestokenize, mask, or redact
replacementstringnoRequired when action is mask
apply_toApplyTarget[]noheader_values, body, query

These 11 rules are always active regardless of user configuration:

ScopePatternAction
headerauthorizationtokenize
headercookietokenize
headerx-api-keytokenize
query_paramapi_keytokenize
query_paramsecrettokenize
query_parampasswordtokenize
query_paramtokentokenize
query_paramaccess_tokentokenize
query_paramrefresh_tokentokenize
query_paramclient_secrettokenize
regex\b\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}\bredact
[defaults]
scrub_auth_headers = true
scrub_cookies = true
tokenize_mode = "hmac"
[[rules]]
scope = "header"
match = "x-api-key"
action = "tokenize"
[[rules]]
scope = "jsonpath"
match = "$.card.number"
action = "mask"
replacement = "****"
[[rules]]
scope = "jsonpath"
match = "$.card.cvc"
action = "redact"
[[rules]]
scope = "regex"
match = "sk_test_[a-zA-Z0-9]{24}"
action = "tokenize"
apply_to = ["header_values", "body"]

VariableDescription
WRAITH_HMAC_KEYHMAC key for deterministic tokenisation. Required in CI.
CIWhen "true", missing HMAC key is a hard error (exit 3).
  • Set WRAITH_HMAC_KEY to any secret string for reproducible tokens across sessions
  • Without it, wraith generates an ephemeral key (tokens differ between runs)
  • In CI (CI=true), a missing key causes exit code 3 (security violation)
  • Never commit the key to version control — wraith doctor checks for this