ADR-0004: Linq as the primary channel
Status: Accepted Date: 2026-04-23 Deciders: Jacob
Context
picortex could target several messaging protocols:
- Linq — iMessage + SMS partner API; the same one Cortex uses.
- Slack — noos already has a Slack bot; well-trodden path.
- Telegram — OpenClaw uses it; good bot API.
- Native iMessage via BlueBubbles / AppleScript — sketchy, not scalable.
- OpenChat — Jacob's own messaging app; would need a linq-compatible adapter (candidate for D3).
Jacob's explicit goal: "chat with Claude Code from my phone, via iMessage, including group texts."
Only Linq offers a legitimate iMessage + iMessage-groups surface without running macOS + JavaScript-for-Automation chicanery.
Decision
Linq is the primary channel. linq-sim (Cortex cloudcli/dev-tools/linq-sim) is the dev/testing channel. OpenChat with a linq-compatible adapter is a deferred secondary channel (D3).
Interface abstraction in picortex is shaped to Linq's event vocabulary (14 event types). Anything talking to picortex over its inbound webhook must conform — this way linq-sim, real Linq, and a future OpenChat adapter are interchangeable.
Consequences
Positive
- Dev loop is Cortex-quality from day 1: linq-sim provides iMessage-shaped traffic without real phone numbers.
- Reuses Cortex's HMAC webhook contract exactly (same
{timestamp}.{raw_body}signing). - No phone-tree / no carrier setup until Jacob is ready for real Linq.
- Future OpenChat work pays dividends because adapter can also serve picortex.
Negative
- Linq is a paid partner API; real deployment costs money.
- Locks event model to Linq's shape. If we later want Slack-first, we'd need an adapter.
- Linq's group-text behavior is specific — no cross-channel semantics.
Mitigations
- Interface: picortex defines a
Channelinterface;LinqChannelis the v1 implementation. Adapters for Slack/Telegram/OpenChat can plug in without touching core logic. - No hard Linq-specific calls in business logic. All outbound goes via the Channel abstraction.
- linq-sim parity check: automated tests emit every event type linq-sim supports.