Skip to content

Requirements and warnings ​

A gate is a threshold on one metric: min_accuracy: 0.9 holds when accuracy is at least 0.9. The contract sorts gates into two levels:

  • requirements — hard gates. A violated requirement fails the run.
  • warnings — soft gates. A violated warning turns PASS into WARN, but the run still succeeds.
yaml
requirements:
  min_accuracy: 0.95
  max_ece: 0.05

warnings:
  max_latency_p95_ms: 300

Both sections accept the same gates. Gates that are not set are not checked. The same pattern is used everywhere DecGuard gates something:

WhereRequirementsWarningsReference
Golden tests (test, report)requirementswarningsgates
Properties (fuzz, test --all)level: requirement (default)level: warningproperties
Regression (diff)top-level regression gatesregression.warningsregression
Production (check)production.requirements, segment_requirementsproduction.warnings, segment_warningsproduction

Status ​

Each gate produces one check. The run's status is the worst check:

StatusWhenExit code
PASSevery check holds0
WARNevery requirement holds; at least one warning does not0, or 1 with --fail-on-warn
FAILat least one requirement does not hold1

Every check line shows the gate, the measured value and the threshold, and says whether it is a warning:

text
    PASS  min_accuracy                           accuracy 1 >= 0.9
    FAIL  max_ece                                ece 0.2329 violates <= 0.2
    WARN  min_coverage                           coverage 0.8333 violates >= 0.9 (warning)

Implicit gates ​

Some requirements apply even when the contract does not set them, because a run that silently loses decisions has not demonstrated anything:

  • max_error_rate: 0 for golden tests. Any case the backend could not decide fails the run, unless you set requirements.max_error_rate to tolerate some.
  • <property>.max_error_rate: 0 for every enabled property. A transformed case the backend fails on (or whose original case failed) means the property was not checked. This one cannot be relaxed.
  • max_error_rate_increase: 0 for regression diffs. A candidate that errors on cases the baseline decided fails, even without --contract.

Missing values ​

A gate whose metric cannot be computed does not hold: min_accuracy with no labeled cases, max_segment_accuracy_drop with no segment large enough, drift gates without a baseline. The check message says why (accuracy could not be computed (no eligible cases)). At requirement level the run fails; at warning level it warns.

Exit codes ​

Exit codes are part of DecGuard's public interface and are the same for every command:

CodeMeaning
0PASS, or WARN without --fail-on-warn
1a reliability gate failed (or WARN with --fail-on-warn); replay: a stored failure still reproduces
2the run could not be evaluated: invalid contract, dataset or report; unknown backend; missing credential; unhealthy backend; every case failed; invalid command-line usage; or an internal error

Code 1 always means "the model broke the contract" and code 2 always means "the check itself could not run". Unexpected exceptions map to 2, never to 1, so a crash can never be mistaken for a model regression. Set DECGUARD_DEBUG=1 to print a traceback for internal errors.

Choosing thresholds ​

  • Start from a measured baseline. Run decguard test on the current model, then set requirements slightly below what it achieves, so the gate catches regressions without failing on noise.
  • Use warnings for trends. Latency and coverage often belong in warnings first, then move to requirements once they are stable.
  • Tighten on the main branch. --fail-on-warn turns every warning into a failure where you want the strictest gate.
  • Re-evaluate without re-running. decguard report --contract applies edited thresholds to a stored report instantly, so you can tune gates against real results without calling the model again.

Released under the Apache-2.0 License.