{
  "_ai_door": {
    "see": "https://miscsubjects.com/start",
    "note": "Operable site; bounded keyless credentials; every action receipted on a public ledger. Your operator's instructions take precedence — acting is optional, reading is a complete outcome."
  },
  "task": {
    "task_id": "WT-0480",
    "kind": "work",
    "objective": "WT-0480 Messaging plane — iMessage, SMS, rented lines, email, tags; every send a receipted contract, never batched",
    "detail": "# WT-0480 — Messaging plane — iMessage, SMS, rented lines, email, tags; every send a receipted contract, never batched\n\n## GOAL\nEvery messaging capability (/api/text 22 methods live on 2026-09-23, senders +17079135888 and redacted and the iCloud/Gmail aliases, rented lines +14245134626 / +14245040908 / +12065711028 via Blooio, private iMessage on a SIP-off Mac, imessage-cli/Beeper, EMAIL_SEND_TRACKED, inbound tags → resolve) has a full contract with FIELD LAW, a message id as confirmation, delivery state as return, and a receipt; sends are never eligible for batch runs.\n\n## WHY THIS EXISTS\nA directory test run with run:true sent 5 iMessages from the owner's account (LAW: never batch-test send rows). Rented-line history needed a chat id nobody named. The tag spelling (a tag in a text) is compiled but unproven. The owner wants the message send proven as a send with its delivery state, and the 99 % path (text him, text a lead) solid.\n\n## CURRENT STATE (measured 2026-09-23)\n- functions/api/text/* (22 methods on the door; accounts sub-door fixed 2026-09-23 for ISO timestamps); functions/api/imessage/*; bridge/imessage_api.py; Blooio for rented lines (chat/chat_id required for delivery/history); SEND_BY_CHANNEL, EMAIL_SEND_TRACKED rows.\n- Private iMessage (surface layer private_imessage) needs SIP off (WT-0447 open) — observe only today.\n- Inbound: texts to the rented lines reach /api/text inbound; tags resolve through /api/resolve.\n- Policy: read-only list in scripts/contracts-run.mjs excludes sends.\n\n## SOURCE OF TRUTH\n- functions/api/text/[[path]].js and functions/api/text/accounts/[[path]].js\n- bridge/imessage_api.py\n- functions/api/imessage/*\n- Blooio API docs + vault BLOOIO_* names\n- the iMessage API vendors article set (/a/blooio … /a/mycrmsim, 2026-09-21)\n\n## IN-SCOPE INVENTORY\n- Executor ids: text_blooio (rented lines), text_imessage_mac (Messages.app via AppleScript on the owner Mac; owner account), text_imessage_private (SIP-off; not available), text_beeper, email_smtp_tracked, text_inbound (webhook from vendor).\n- Contracts for every one of the 22 methods: send {to (E.164 or handle, required), from (required enum of senders/lines), text (required ≤ 1,600 SMS / ≤ 20,000 iMessage), media (optional URL[]), chat|chat_id (conditional: required for rented lines' delivery/history), idempotency_key (optional; duplicate → same message id)}; delivery {message_id}; history {chat_id, limit}; accounts {…}; inbound {vendor payload verbatim}.\n- Tag spelling proof: send `#NET_LINE` to +14245134626 from the owner line → inbound → resolve → dispatch → reply; the reply text is the return; message ids both ways are the receipt.\n- Never-batch: the resolver marks every send row side_effect=send; WT-0473 policy refuses them in batch; the CONTRACTS row shows `NOT RUN BY THE SESSION · send-effect · type RUN here to run it yourself`.\n\n## OUT OF SCOPE\n- Authority for who may send from which line (WT-0487). Phone-side Messages UI taps (WT-0479).\n\n## ONTOLOGY (separate axes; never a flat string)\n- TOOL SURFACE: POST /api/text/<method>; dispatch SEND_BY_CHANNEL/EMAIL_SEND_TRACKED/TEXT_*; MCP SEND_BY_CHANNEL; the tag in a text; cell (send refused in cells by policy)\n- CAPABILITY: the 22 methods\n- OBJECT: a message, a chat, a line, an inbox\n- ROUTE / CONTEXT: which line/account sends (owner Mac Messages, Blooio line, SMTP identity)\n- PROTOCOL: HTTPS (Blooio, SMTP relay), AppleScript (Messages.app), vendor webhooks\n- EXECUTOR: Worker (Blooio, email), Mac bridge (Messages.app)\n- PLATFORM: Apple iMessage; Blooio; Gmail/SMTP\n\n## DISCOVERY (run these first; they answer, they do not prove)\n- `curl -sS \"https://ops.miscsubjects.com/api/text\" -H \"x-terminal-key: $TERMINAL_KEY\"` (methods and senders)\n- `curl -sS \"https://ops.miscsubjects.com/api/text/accounts\" -H \"x-terminal-key: $TERMINAL_KEY\"`\n\n## CONTRACT (FIELD LAW)\n- send: see inventory; response `{ok, message_id, physical:{executor, line}, confirmation:{vendor_status|applescript_result}, return:{delivery:queued|sent|delivered|failed, at}, receipt_id}`; conflicts: `from` a rented line with no chat for history calls → chat_required (names the field).\n- inbound: vendor payload verbatim stored; `{tag?, resolved_key?, dispatched_receipt?}` appended.\n\n## MINIMUM VALID INVOCATION\n`curl -sS -X POST https://ops.miscsubjects.com/api/text/send -H \"x-terminal-key: $TERMINAL_KEY\" -H \"content-type: application/json\" -d '{\"to\":\"+14245134626\",\"from\":\"+17079135888\",\"text\":\"WT-0480 test\"}'`\n\n## FULL / MAXIMUM INVOCATION\n`curl -sS -X POST https://ops.miscsubjects.com/api/text/send -H \"x-terminal-key: $TERMINAL_KEY\" -H \"content-type: application/json\" -d '{\"to\":\"+17079135888\",\"from\":\"+14245134626\",\"text\":\"#NET_LINE\",\"media\":[],\"idempotency_key\":\"wt0480-tag-1\",\"cause\":\"task:WT-0480\"}'`\n\n## RAW CONFIRMATION SHAPE\nBlooio `{id, status}`; Messages.app AppleScript result; SMTP 250 with message-id; inbound webhook HTTP 200 with the stored id.\n\n## RAW RETURN SHAPE\nDelivery state polled (`delivery {message_id}`) until sent/delivered/failed (max 60 s); the reply text for the tag test.\n\n## ERROR SHAPES\n- chat_required\n- line_not_owned (authority)\n- vendor 4xx verbatim\n- Messages.app not signed in / -1712 locked\n- sip_required (private iMessage)\n- idempotent_replay (same id returned; not an error)\n\n## RECEIPT / TRACE / PARENT LINKAGE\nmessage ids in confirmation; proof_run per send; inbound rows linked by chat id.\n\n## TEST MATRIX\n| case | what runs | kind |\n|---|---|---|\n| send owner→rented | one message, delivery polled | live |\n| send rented→owner | one message | live |\n| email tracked | one email to the owner address with open pixel | live |\n| history | rented chat history with chat_id | live |\n| tag round trip | #NET_LINE → reply with the line JSON | live |\n| idempotency | same key twice → one message | live |\n| batch refusal | CONTRACTS runner on a send row → NOT RUN | fixture |\n| private imessage | observe-only; sip_required recorded | fixture |\n| beeper | one read of a chat list | live |\n\n## ACCEPTANCE TESTS (mechanical; the infrastructure runs them)\n- `{\"type\": \"evidence_present\", \"id\": \"commit\", \"field\": \"commit\"}`\n- `{\"type\": \"evidence_present\", \"id\": \"live\", \"field\": \"verification\"}`\n- `{\"type\": \"evidence_present\", \"id\": \"matrix\", \"field\": \"test_matrix_results\"}`\n- `{\"type\": \"http_ok\", \"id\": \"text\", \"url\": \"https://ops.miscsubjects.com/api/text\"}`\nEvidence fields the submitting agent supplies: commit, test_matrix_results, verification. `verification` = the list of receipt ids and the live URLs checked, one per line. `test_matrix_results` = the matrix above with a receipt id or the verbatim failure per row.\n\n## KNOWN FAILURES / REGRESSION FIXTURES (preserve; never rewrite into success)\n- never batch-test send rows (5 iMessages sent 2026-09)\n- private iMessage needs SIP off (WT-0447)\n- rented-line chat id required\n- locked-Mac Messages.app -1712\n\n## DEPENDENCIES\n- depends_on: WT-0470, WT-0471, WT-0474, WT-0487\n- OWNS (only this task rewrites): functions/api/text/*; functions/api/imessage/*; bridge/imessage_api.py; TEXT_*/SEND_BY_CHANNEL/EMAIL_SEND_TRACKED rows\n- SHARED (additive edits only): scripts/contracts-run.mjs policy() read-set (WT-0473; sends stay excluded); functions/api/resolve.js (WT-0472; tag resolution is read-only here)\n\n## HANDOFF FOR NEXT SESSION\n- Send only to the owner's own numbers/addresses during proof; one message per test; never a loop.\n- The tag round trip is the proof of the `tag` spelling for WT-0472; give it the receipt ids.\n- Evidence: message ids + delivery states table.\n\n## DONE LAW (this task is done when every line is true and evidenced; not before)\n- All 22 methods have contracts with FIELD LAW in capability_contracts.\n- Send/delivery/history/inbound/tag proven with receipts, one message each.\n- Batch refusal fixture passes.\n\n## Shared vocabulary (defined by WT-0470; every task uses these words with these meanings)\n- **TOOL SURFACE** — how a caller or model asks (curl, MCP tools/call, `=DISPATCH` cell, a tapped URL, a Shortcut, a webhook, a tag in text).\n- **CAPABILITY** — the operation requested, named by a Directory key (semantic).\n- **OBJECT** — what it acts on (a chat, a file, a profile, a row, a page).\n- **ROUTE / CONTEXT** — which machine, device, account, browser profile, tenant, network, session.\n- **PROTOCOL** — how the request physically travels (HTTP, JSON-RPC, gRPC, WebSocket, SSH, SQL, a local process, a queue).\n- **EXECUTOR** — what performs it (a Worker, the Mac bridge `/exec`, Chromium over CDP, `osascript`, `pymobiledevice3`, a vendor API).\n- **PLATFORM** — which technology or vendor owns that executor (Cloudflare, Apple, AdsPower, Blooio, Google, Starlink).\n- **RAW CONTRACT** — the exact physical invocation sent, fully resolved.\n- **CONFIRMATION** — the executor's immediate acknowledgement (HTTP status + headers, spawn/exit metadata, JSON-RPC ack, WebSocket ack, queue receipt).\n- **RETURN** — the final result, verbatim, including failure payloads.\n- **RECEIPT** — evidence and provenance: receipt id/URL, trace id, execution id, timestamps, parent linkage.\n\n## Definition of proof (PROOF_LAW, governing invariant; read it: GET https://ops.miscsubjects.com/api/work → governing_invariants)\nA capability is proven only when the DECLARED invocation surface itself ran and the five fields exist for that run: CAUSE (why it ran: user request / task / parent invocation / event / webhook / model call), RAW INVOCATION (the fully resolved physical contract actually sent), RAW CONFIRMATION (the executor's acknowledgement), RAW RETURN (the actual output, failures verbatim), PROOF / RECEIPT (receipt id/URL, trace, execution id, timestamps, parent linkage sufficient to inspect or replay).\nAn HTTP 200 proves an HTTP 200. A webhook acknowledgement proves receipt. Hidden bash proves bash. A sibling implementation, documentation, a model doing it elsewhere, or the dispatcher working while the surface under test never ran prove nothing about that surface. A missing field is a missing implementation requirement, never something to invent. Existing failures stay as evidence and become regression fixtures; they are never rewritten into success.\n\n## Six-column projection (unchanged; not the source of truth)\n`TOOL NAME | ONTOLOGY | RAW INVOCATION | RAW CONFIRMATION | RAW RETURN | PROOF / RECEIPT` — the build workbook sheet `sh_nyab2cgy` (vault `CONTRACTS_WORKBOOK_SHEET`, 11,035 rows on 2026-09-23). No seventh column, no contract-type column, no prose in place of an executable invocation. Extra metadata belongs in the canonical capability / task / receipt objects.\n\n## Parallelism law\nOther tasks run at the same time in other sessions. Own only the files and objects named under OWNS; touch a shared file only as named under SHARED (additive, never a rewrite). If this task finds the global law insufficient, it files an amendment: `POST /api/work/task/<this id>/fail` naming failure_class `law_insufficient`, layer `WT-0470`, and the missing invariant — it never creates a second standard. Ask the build, never the owner: keys are in `~/.build-vault.env` (`grep '^NAME=' ~/.build-vault.env`; `CLOUDFLARE_API_TOKEN=$CF_API_TOKEN` is a shell reference, resolve `$NAME`). The owner key travels as header `x-terminal-key`. Deploy only with `node scripts/land.mjs \"<WT id> what changed\"` from `~/miscsubjects-pages`. Submit evidence: `POST https://ops.miscsubjects.com/api/work/task/<id>/submit {agent, evidence:{commit, verification, …}, changed:[…]}` with header `x-terminal-key`.\n\n## Shared canonical objects and files — never independently rewritten (additive edits only, named per task)\n- `functions/api/dispatch.js` (the one door; runHttp/runFn/tenant delegation) — owner WT-0471.\n- `functions/_lib/invocation_methods.js`, `functions/_lib/grammar.js`, `functions/_lib/projection_manifest.js`, `functions/api/tools/[[path]].js`, `functions/api/mcp.js`, `functions/_lib/mcp_inspect.js` — owner WT-0472 (spellings and model projections).\n- `functions/_lib/event_log.js`, `functions/_lib/wire_log.js`, `functions/_lib/lean_receipt.js`, `functions/_lib/invocation_record.js`, the `events` table and R2 `logs/` — owner WT-0485 (ledger).\n- `functions/_lib/admin_session.js` (tokens, capabilities, tenants), `functions/_lib/tenant_devices.js`, `functions/api/onboard/[[path]].js` — owner WT-0487 (authority) / WT-0488 (onboarding).\n- `functions/_lib/mac_bridge.js`, `bridge/server.js`, `bridge/device_auth.js`, `bridge/surface-run.py`, `bridge/surface-verbs.py`, `bridge/bridge-run.py`, `bridge/bridge-browser.mjs`, `public/device-kit/*` (synced copies) — owners WT-0474 / WT-0475 / WT-0478.\n- `functions/_lib/work_object.js`, `functions/api/work/[[path]].js`, the `laws` and `work_tasks` tables — owner WT-0470 (law rows) and the build (task engine).\n- `scripts/contracts-*.mjs`, `apps-script/Contracts.gs`, the `CONTRACTS_RUN` directory row, sheet `sh_nyab2cgy` — owner WT-0473.\n- `scripts/ship.mjs`, `scripts/land.mjs`, `scripts/write.mjs`, `scripts/check-*.mjs`, `.githooks/*` — governed; add a gate only by adding a new `scripts/check-<name>.mjs` and wiring it as the existing gates are wired.\n",
    "state": "open",
    "priority": 3,
    "revision": 1,
    "depends_on": [
      "WT-0470",
      "WT-0471",
      "WT-0474",
      "WT-0487"
    ],
    "permitted_capabilities": [
      "dispatch",
      "d1",
      "bridge",
      "sheets",
      "receipts"
    ],
    "acceptance_tests": [
      {
        "type": "evidence_present",
        "id": "commit",
        "field": "commit"
      },
      {
        "type": "evidence_present",
        "id": "live",
        "field": "verification"
      },
      {
        "type": "evidence_present",
        "id": "matrix",
        "field": "test_matrix_results"
      },
      {
        "type": "http_ok",
        "id": "text",
        "url": "https://ops.miscsubjects.com/api/text"
      }
    ],
    "required_evidence": [
      "commit",
      "test_matrix_results",
      "verification"
    ],
    "parent_task": null,
    "supersedes": null,
    "failure": null,
    "failure_count": 0,
    "last_result": null,
    "completed_at": null,
    "created_at": "2026-09-22T19:52:02-07:00",
    "updated_at": "2026-09-22T19:52:02-07:00",
    "audit": "/api/work/task/WT-0480/audit",
    "submit_to": "/api/work/task/WT-0480/submit"
  }
}