Guardrails and invalidations¶
LDTC's job is not only to measure NC1 / SC1 but to make it hard
to quietly tune the result. The
ldtc.guardrails package is where that
happens. There are four moving parts:
| Piece | Code | Purpose |
|---|---|---|
| LREG enclave | LREG |
Write-only registry for raw 𝓛. |
| Audit log | AuditLog |
Append-only, hash-chained event journal. |
Δt governance |
DeltaTGuard |
Rate-limits and audits Δt changes. |
| Smell tests | smelltests |
Per-window invalidation heuristics. |
What gets watched¶
Defaults below come from
SmellConfig. They are
all overridable per profile.
| Smell test | Threshold | Code | What it catches |
|---|---|---|---|
| CI half-width | > 0.30 on 𝓛_loop or 𝓛_ex |
invalid_by_ci |
One bad window with a blown-up CI. |
| CI inflation vs baseline | median half-width > 2 × baseline median over 5 windows |
invalid_by_ci_history |
Slow-creeping noise, bad seed of the bootstrap, etc. |
Excessive Δt edits |
> 3 per rolling hour |
enforced inline by DeltaTGuard |
Operator nudging Δt to make M look better. |
| Partition flapping | > 2 flips per hour |
invalid_by_partition_flips |
A regrowth knob that chatters. |
Flip during Ω |
any | invalid_flip_during_omega |
A reshuffle that happens to make SC1 pass. |
Δt jitter excess |
p95(|jitter|) / Δt > 0.25 |
computed by SchedulerStats |
The scheduler did not actually hold Δt. |
| Audit chain broken | any prev_hash mismatch |
audit_chain_broken |
Torn write, edited audit, etc. |
| Raw LREG breach | any audit row with raw 𝓛 fields |
audit_contains_raw_lreg_values |
Something tried to log raw measurements. |
| Exogenous subsidy | M rising while I/O suspicious or SoC rising without harvest |
exogenous_subsidy_red_flag |
Hidden energy source masquerading as loop dominance. |
When any guard returns True the CLI:
- Calls
LREG.invalidate(reason)so subsequent indicators carryinvalidated = true. - Appends a
run_invalidatedaudit record with the reason and any quantitative payload.
Indicators after that point still get signed, but their
invalidated bit is true, and downstream verifiers should treat
the whole run as failed.
Multi-run audit files¶
Each CLI invocation starts a fresh audit chain (counter resets,
prev_hash = GENESIS) but, by default, appends to the same
artifacts/audits/audit.jsonl. The post-run integrity check
validates the entire file, so after the first run, subsequent runs
in the same file will trip an "Audit chain broken" invalidation.
For clean, non-invalidated runs, clear artifacts between commands:
make clean-artifacts && ldtc run --config configs/profile_r0.yml
make clean-artifacts && ldtc omega-power-sag --config configs/profile_r0.yml --drop 0.35 --duration 8
If you are iterating on figures or manifests, this invalidation is expected and does not prevent artifacts from being produced; it only reflects multiple runs aggregated into one audit file.
Negative controls¶
Several configs in configs/ are intended to fail, so you can
confirm the guards work end-to-end:
| Config | What it triggers |
|---|---|
profile_negative_command_conflict.yml |
omega-command-conflict exercises RefusalArbiter; T_refuse should be measured and a refusal_event should appear in the audit. |
profile_negative_controller_disabled.yml |
Disables the controller; NC1 should fail (no loop). |
profile_negative_exogenous_soc.yml |
omega-exogenous-subsidy should trip the exogenous-subsidy smell test. |
profile_negative_permanent_ex_flood.yml |
omega-ingress-flood with no recovery; SC1 should fail. |
Run any of these with make clean-artifacts && ldtc <subcommand>
--config configs/<negative.yml>, then read the
run_invalidated records in artifacts/audits/audit.jsonl.
What guarded actually means¶
The guarantees the harness gives you:
- No raw
𝓛ever appears in a CSV, indicator, or audit row. Both the exporter and the CSV writer callaudit_contains_raw_lreg_valuesbefore emitting; LREG itself only exposesderiveandlatest. - Every
Δtchange is rate-limited and audited. A change has to go throughDeltaTGuard.change_dt, which appends adt_changedrecord on success or refuses on rate-limit failure (seecan_change). - The audit chain is verified twice: once in process and once by re-reading the file from disk. A torn write or a partial flush still gets caught.
- Indicators and audit cannot disagree. A signed indicator's
invalidatedbit comes from the same in-process flag that appended the most recentrun_invalidatedaudit row.
See also¶
- Lifecycle: when each guard runs during a CLI invocation.
- Definitions: formal statements of
Δt,𝓛,M, partition. ldtc.guardrails: API reference for every guard and theSmellConfigthresholds.