{"body":"Addressed: replaced the self-grantable `confirmed:true` boolean with a genuine out-of-band human approval the tool-calling LLM cannot satisfy. New `tools/curogram-mcp/send-approval.ts` + rewired `handleSendText`.\n\nHandshake:\n1. `curogram_send_text` called WITHOUT `approval_id` runs the fail-closed TCPA-consent + conversation/patient-linkage checks, then writes a pending-send record to `$XDG_STATE_HOME/curogram-mcp/pending-sends/<id>.json` (dir 0700, file 0600) containing a server-generated, single-use, 256-bit random `token` and a SHA-256 `content_hash` binding the approval to the exact (conversation_id, patient_id, message body, secure flag). It does NOT send. The response returns only `{status:\"pending_approval\", id, content_hash, expires_at}` — never the token, never the message body.\n2. A human (Gautam) confirms over iMessage; the orchestrator/operator (which has filesystem access to the 0700 dir — the LLM tool channel does not) reads the token from the record and writes the release marker `$XDG_STATE_HOME/curogram-mcp/approved/<id>` containing that token. Writing that file is the human release action.\n3. `curogram_send_text` called again with the same args PLUS `approval_id` re-checks consent + linkage, then validates: marker token === record token, not expired (15-min TTL), not already used (single-use, marked used before send), and live content hash === record hash. Only then does the real Curogram send run.\n\nWhy the LLM can't self-grant: the token is random, server-side, stored only on the 0700 filesystem, and never returned through the tool channel; approval requires a filesystem write the LLM channel cannot perform; the content hash binds approval to one exact send so an approved id can't be reused for different content/recipient; single-use + short TTL block replay. Consent + linkage are re-checked at send time so a consent revoked between pending and release still blocks the send. Message body is hashed but never persisted or logged (PHI discipline).\n\nFull operator contract: .claude/skills/curogram/references/send-approval.md. Verified end-to-end (no-marker refused, wrong-content refused, forged-token refused, valid send approved, replay refused)."}
