Configuration reference¶
Everything lives in .dedrift/config.toml, created by dedrift init.
Every key below is optional; omitted keys use the documented default.
[project]
name = "my-agent"
canary_repetitions = 7 # N runs per canary per cycle
rolling_window_cycles = 5 # K cycles in the rolling reference
[detection]
fdr_q = 0.05 # Benjamini–Hochberg level over primary tests
permutations = 500 # resamples for permutation tests (seeded)
seed = 1729 # global seed, recorded in every report
ph_lambda = 12.0 # Page–Hinkley alarm threshold (robust-scale units)
ph_delta = 0.3 # Page–Hinkley dead-zone
[materiality]
refusal_rate_pp = 2.0 # min refusal-rate shift, percentage points
format_validity_pp = 1.0 # min format-validity shift, pp
rate_default_pp = 2.0 # other rate signatures, pp
ks_distance = 0.15 # min KS statistic D for KS alerts (see note)
scalar_cohen_d = 0.5 # location gate for non-KS scalar channels
variance_ratio = 1.5 # dispersion gate: var must grow/shrink 50%
p95_relative = 0.10 # tail gate: min relative P95 shift
embedding_mmd2_floor = -1.0 # -1 = auto-calibrate; 0 = off; >0 = explicit
[embeddings]
model = "" # set via `dedrift embedder pin`, not by hand
Notes that matter¶
canary_repetitions (N)¶
The single biggest power lever. The power table shows what each N buys; cost grows linearly.
fdr_q¶
Applied once per check across all primary tests (both baselines together). Corroboration tests (Anderson–Darling, Welch) never enter the pool and never alert.
ks_distance¶
The KS channel gates — and reports — the KS statistic D (sup-norm CDF distance), because a shape change with equal means has Cohen's d ≈ 0 and is still real drift. Binding scale, stated plainly: the raw-α=0.05 critical value is ≈ 1.36·√((n+m)/nm), which for equal arms stays above 0.15 until n ≳ 165 per arm — so at typical per-family scale, significance is the stricter filter and this gate exists to stop trivially significant tiny D from alerting at large n.
embedding_mmd2_floor¶
Left at -1, the MMD² materiality floor is auto-calibrated per
(baseline, family) as the 95th percentile of MMD² between pairs of the
baseline's own cycles — an empirical null from known-same-distribution
data, computed under the same kernel bandwidth as the observed statistic.
Needs ≥ 3 reference cycles; below that the floor is 0 and the report says
"uncalibratable".
ph_lambda, ph_delta¶
Page–Hinkley is a diagnostic, not an alert: it localizes drift onsets for attribution. Defaults are calibrated to ≈1.5% per-stream false-flag rate over 30-cycle horizons (measured, enforced < 3% in CI). Flags compound across streams — a stable agent shows ≥1 flag on 56% of checks — which is why flags never page anyone.
Embeddings¶
dedrift embedder pin hash # zero-dependency, always available
dedrift embedder pin st:all-MiniLM-L6-v2 # requires dedrift[embeddings]
Pinning is forever per project: changing the embedder invalidates all semantic history, so dedrift refuses to compare across embedder versions rather than produce quietly meaningless numbers. Pick deliberately, then leave it.
[anytime] — anytime-valid mode¶
[detection]
inference = "fixed" # or "anytime"
[anytime]
alpha = 0.05 # lifetime, battery-wide false-alert budget
gamma_total = 0.02 # coverage budget; alpha_prime = alpha - gamma_total
tilts = [1.5, 2.0, 3.0] # symmetrised to {psi, 1/psi}
epoch_allocation = "per_epoch" # or "geometric"
Switches the inference layer from per-check FDR to e-processes with a
lifetime guarantee. The trade — validity over an unbounded horizon, paid for
in detection power — is quantified in
anytime-valid mode. Default stays fixed.
Exit codes¶
| Command | Exit | Meaning |
|---|---|---|
dedrift check |
0 | OK (or NO REFERENCE) |
dedrift check |
2 | DRIFT DETECTED — wire this to alerting |