# Social network capabilities (sandbox)

Phase 6 ships **sandbox/dry-run connectors**. Native IDs are simulated (`{network}_sandbox_*`). Live OAuth apps are not required.

| Network | Publish | Schedule | Insights | Comment reply | Messaging | Notes / gaps |
|---|---|---|---|---|---|---|
| Facebook | Yes | Yes | Yes | Yes | Entitled | Pages-oriented; Messenger only if `messaging` entitled |
| Instagram | Yes | Yes | Yes | Limited | No | Media required; Reels/Stories not fully modeled |
| TikTok | Yes | Limited | Limited | No | No | Video required; inbox not entitled by default |
| X | Yes | Yes | Limited | Limited | No | 280-char hard fail (no silent truncation) |
| Reddit | Yes | Limited | No | Mod-only | Modmail* | Modmail only if moderator entitlement |
| LinkedIn | Yes | Yes | Yes | Limited | No | Community Management subset |
| Pinterest | Yes | Limited | Limited | No | No | Media required |
| YouTube | Yes | Limited | Yes | Yes | No | Video upload sandbox only |
| GBP | Yes | Limited | Yes | Reviews* | No | Review reply when entitled |

\* Capability fail-closed: UI and services call `CapabilityRegistry::assertCan()` — missing entitlement aborts with 403.

## Operator workflow (command center)

1. **Connect** — Social → Accounts → Connect account. Pick a network; sandbox OAuth completes and stores a TokenVault token with default entitlements. Account detail supports health, pause/resume, revoke, reconnect.
2. **Compose** — Social → Composer. Select target accounts (not just network strings), write body (per-network length meters), Insert Media from the media library, then Save draft / Schedule / Publish now. High-risk accounts route to Approvals (four-eyes).
3. **Calendar & posts** — Social → Calendar shows the day-grouped schedule; Posts is the library (filter, publish, duplicate). Due `scheduled` / `approved` posts dispatch via `social:publish-due` (every minute) through `PublishSocialPost` → `PublisherService` when `social_publish_enabled` is on.
4. **Approvals** — High-risk or approval-required posts wait here. A different staff user must Approve or Reject; creators cannot self-approve.
5. **Inbox** — Reply / Hide / Escalate / To CRM on engagements. Use **Pull sample** (or `POST /webhooks/social/{network}` in sandbox) when the inbox is empty.
6. **Analytics** — Sync sandbox insights to write `social_metrics_daily` rows; review impressions, engagements, and publishes per account.

## Operational rules

- Token revoke sets `schedules_paused_at` and stops scheduled publish selection.
- High-risk accounts require four-eyes approval before publish lock.
- Feature flag `social_publish_enabled` gates `PublisherService` and the due-post dispatcher.
- Publish attempts are idempotent by `(post, network, account)`; successful attempts are not duplicated.
- UI only offers actions `CapabilityRegistry` allows (fail-closed).
- `config/social.php` holds network labels, default capabilities, and future live client IDs. `SOCIAL_MODE=sandbox` until live credentials are configured.
