P2 pre-merge fixes: io_captured column, reconcile copy, harden security test

Fix 1: Add io_captured TINYINT(1) NOT NULL DEFAULT 0 to prv_call_meta
CREATE (baked into initial schema — table is new in v0.3.0, no separate
migration needed). PRV_Capture_Writer::write_io() sets io_captured=1 via
set_io_captured() on success; error rows and legacy rows keep 0.
Drawer state now driven by io_captured instead of config_version heuristic:
  0         → Legacy/not-captured
  1 + io    → Normal
  1 + no io → Pruned
ARCHITECTURE.md schema section updated.

Fix 2: Soften reconciliation copy in PRV_Costs_Renderer (~line 75):
'matches the Dashboard MTD total' → 'approximately reconciles to the
Dashboard MTD total' — error calls write prv_call_meta (cost 0) but not
prv_ai_visibility, so exact equality is not guaranteed.

Fix 3: Harden security test (test-capture-writer Test 4): inject sentinel
sk-or-TEST-LEAK-CANARY as PRV_OPENROUTER_API_KEY constant; queue a mocked
401 wp_remote_post response; drive PRV_Probe_Runner → PRV_Probe_Run_Executor
→ probe_one() 401 error path end-to-end; assert the sentinel, Bearer, and
Authorization appear in NO stored row (prv_call_meta or prv_call_io).
Original direct-writer security test retained as Test 3.
This commit is contained in:
peptiderepo
2026-06-15 09:56:11 +00:00
parent 94bef937c7
commit 09dc6db9ce
7 changed files with 116 additions and 25 deletions

View File

@@ -15,6 +15,9 @@ rendered prompt + raw response. Two new admin pages (Costs, Call Log) with
a non-modal detail drawer. Raw I/O is pruned on a configurable retention
window (default 90 days); cost/metadata kept indefinitely.
### Fixed (pre-launch P2 cleanup)
- `io_captured TINYINT(1) NOT NULL DEFAULT 0` column added to `prv_call_meta` CREATE (baked into initial schema — table is new in v0.3.0). Set to `1` by `PRV_Capture_Writer::write_io()` on success, remains `0` for error rows and legacy/pre-feature rows. Drawer state now driven by `io_captured` instead of the `config_version < 3` heuristic: `0` = Legacy/not-captured; `1` + io row present = Normal; `1` + io row absent = Pruned (aged out). Removes a fragile inference.
### Security (P0)
- `PRV_Gateway_Client::post_to_gateway()` — removed response body from
RuntimeException message; exception now carries HTTP status code only.