{
  "_comment": "Relative-ratio regression gates (the maintainer's chosen policy). Ratios are portable across machines/WAN; absolute ms in the results JSON stay informational. Tune these after the first real baseline run, then tighten. 'field' is a dotted path into a metric's result; for list items use the index (e.g. sweep.3.median_ms).",
  "read-full": {
    "gates": [
      { "field": "speedup_ratio", "op": ">=", "min": 1.8,
        "why": "concurrent read_many must beat serial by the 1.1.0 concurrency margin; <1.8 means concurrency regressed" }
    ]
  },
  "bulk-get": {
    "gates": [
      { "field": "speedup_ratio", "op": ">=", "min": 1.5,
        "why": "controlled-K concurrent vs serial; lower bar than full-vault since K is small" }
    ]
  },
  "expand-graph": {
    "gates": [
      { "field": "min_speedup", "op": ">=", "min": 2.0,
        "why": "recall()'s graph layer must fetch each BFS hop concurrently (read_many), not serially per node; <2x means expand_graph regressed to the pre-fix serial walk" },
      { "field": "all_ranking_identical", "op": ">=", "min": 1,
        "why": "the concurrent expansion must return the same ranked neighbours as the serial reference" },
      { "field": "all_scores_identical", "op": ">=", "min": 1,
        "why": "decayed scores must match the serial reference to within float tolerance" }
    ]
  },
  "pool-warmup": {
    "gates": [
      { "field": "cold_over_warm_ratio", "op": ">=", "min": 1.5,
        "why": "cold request must be meaningfully slower than warm — proves keep-alive is reusing the connection; a ratio near 1.0 means every request is re-handshaking (the pre-1.1.0 bug)" }
    ]
  },
  "bulk-append": {
    "gates": [
      { "field": "all_skipped_second_pass", "op": ">=", "min": 1,
        "why": "second pass of identical lines must be 100% idempotent skips (boolean true coerced to 1)" }
    ]
  },
  "soak": {
    "gates": [
      { "field": "errors", "op": "<=", "min": 0,
        "why": "no read errors across the soak window — connection leaks/pool exhaustion would surface here" },
      { "field": "drift_ratio_late_over_early", "op": "<=", "min": 1.5,
        "why": "late passes must not be much slower than early ones; >1.5 suggests a leak or degrading pool" }
    ]
  },
  "lock": {
    "gates": [
      { "field": "ok", "op": ">=", "min": 1,
        "why": "free acquire returns 0 and a contended acquire fast-fails with exit 75" }
    ]
  },
  "cache": {
    "gates": [
      { "field": "deduped", "op": ">=", "min": 1,
        "why": "read_many must collapse a 3x-duplicated path list to the unique set" }
    ]
  }
}
