diff --git a/docs/superpowers/plans/2026-07-02-cyclone-ack-claim-auto-link.md b/docs/superpowers/plans/2026-07-02-cyclone-ack-claim-auto-link.md index 317f4d4..ccc402e 100644 --- a/docs/superpowers/plans/2026-07-02-cyclone-ack-claim-auto-link.md +++ b/docs/superpowers/plans/2026-07-02-cyclone-ack-claim-auto-link.md @@ -747,4 +747,41 @@ src/ - **Backend created** (7): `migrations/0018_claim_acks.sql`, `claim_acks.py`, `store/claim_acks.py`, `api_routers/claim_acks.py`, `tests/test_apply_claim_ack_links.py`, `tests/test_api_claim_acks.py`, `tests/test_e2e_999_to_claim_drawer.py`. - **Backend modified** (10): `db.py`, `store/ui.py`, `store/__init__.py`, `api.py`, `api_routers/acks.py`, `api_routers/ta1_acks.py`, `handlers/handle_999.py`, `handlers/handle_277ca.py`, `handlers/handle_ta1.py`, plus test assertion bumps in `tests/test_acks.py` + `tests/test_db_migrate.py`. - **Frontend created** (15): `useClaimAcks` + `useAckClaims` + `useAckOrphans` hooks (+ tests), `AcknowledgmentsPanel` + `MatchedClaimPanel` + `AckOrphansLane` components, type definitions in `src/types/index.ts`. -- **Frontend modified** (11): `ClaimDrawer.tsx` + `AckDrawer.tsx` + `pages/Acks.tsx` + `pages/Inbox.tsx` (panel/lane mounting), `tail-store.ts` + `useTailStream.ts` + `useMergedTail.ts` (live-tail extension), `lib/api.ts` (claim_ack methods), `auth/api.ts` (joinUrl refactor), plus 4 test file expansions. \ No newline at end of file +- **Frontend modified** (11): `ClaimDrawer.tsx` + `AckDrawer.tsx` + `pages/Acks.tsx` + `pages/Inbox.tsx` (panel/lane mounting), `tail-store.ts` + `useTailStream.ts` + `useMergedTail.ts` (live-tail extension), `lib/api.ts` (claim_ack methods), `auth/api.ts` (joinUrl refactor), plus 4 test file expansions. +--- + +## SP28 follow-ups (post-merge, 2026-07-02) + +### Bug fix — `Batch.kind` filter mismatch (shipped as merge `02b879a`) + +The original SP28 helpers (`batch_envelope_index()` + `lookup_claims_for_ack_set_response()` fallback + the two `_batch_lookup` closures in `handle_ta1.py` / `api.py`) all filter `Batch.kind == "837"`. But production `Batch` rows are written with `kind="837p"` (lowercase `p`, per `api.py:443` and `store/records.py:58`). Result on prod: the batch envelope index was empty, every Pass-1 (ST02 via batch) join missed, and the user's claim `t991102989o1c120d` (batch `0e2726b3...`, envelope.control_number=`991102989`) had zero claim_acks rows despite having 334 incoming 999 AK2s with set_control_number=`991102989`. + +**Why tests passed:** the SP28 test files seeded `Batch(kind="837", ...)` — internally consistent with the wrong helper filter, but never exercised the prod value. The 4 production sites + 3 test files + 1 test closure were all updated to `kind="837p"`. 25 SP28 tests + 20 handler tests pass post-fix. Branch + atomic merge: `sp28-fix-batch-kind-mismatch` → `02b879a`. + +**Files touched (7):** +- `backend/src/cyclone/api.py` (1 line) +- `backend/src/cyclone/claim_acks.py` (1 line) +- `backend/src/cyclone/handlers/handle_ta1.py` (1 line) +- `backend/src/cyclone/store/claim_acks.py` (1 line) +- `backend/tests/test_apply_claim_ack_links.py` (2 lines — seed + test closure) +- `backend/tests/test_api_claim_acks.py` (1 line) +- `backend/tests/test_e2e_999_to_claim_drawer.py` (1 line) + +### One-time backfill script (`/tmp/backfill_claim_acks.py`, in-container) + +The 1,398 existing 999 acks (and the 1 277CA + 1 TA1) pre-date the auto-linker. The bug fix above makes NEW acks auto-link correctly, but the existing rows need a one-time pass to populate `claim_acks`. The script walks the SP28 helpers against the live DB (no re-ingest required) and persists via `CycloneStore.add_claim_ack(...)` so live-tail events fire normally. Idempotent via the partial unique index + Python pre-check in each helper. + +**Run from the prod container:** +```bash +docker exec -e CYCLONE_DB_URL=sqlite:////var/lib/cyclone/db/cyclone.db \ + cyclone-backend-1 python /tmp/backfill_claim_acks.py +``` + +**Result on prod (2026-07-02 18:30 UTC):** +- 999: 1,398 acks → 66,559 link rows inserted → 867 set_control_numbers orphaned (mostly the 671 with ST02=`0001` + a few rare mismatches) +- 277CA: 1 ack → 0 links (sample data, PCNs don't match real claims) +- TA1: 1 ack → 0 links (sender/receiver mismatch) +- User's claim `t991102989o1c120d`: 334 claim_acks rows (all 999 type, batch=`0e2726b3...`, ack_kind=999, all `set_accept_reject_code='A'`) +- API verification: `GET /api/claims/t991102989o1c120d/acks` → 334 rows; `GET /api/claims/t991102989o1c120d` now includes `ack_links: [...334 rows...]` + +**Note on the script:** it's a one-shot in-container tool, not part of the shipped codebase. The 671 ST02=`0001` orphans + 196 other orphans will surface in the new Inbox `ack-orphans` lane as designed — operator can clear them via the manual-match dropdown (D4 + D5 in spec).