CedarCopilot wants to merge 0 commits into staging from feat/channel-sync-architecture
Live on prod, no production signal yet
OTEL fallback saw 220,393 prod spans for the repo/env since deploy, but 5,334 were errors and the intent has no concrete surface to attribute them to.
Strict CloudWatch fallback found 56 prod failure log lines for [UpdateExternalCrmWorkflow] Driver update failed (Step updateDeal failed: HTTP 400: {\), up from 5 in the comparable baseline, but this domain-wide failure family is not tied to this intent.
OTEL fallback saw 224,627 prod spans for the repo/env since deploy, but 5,447 were errors and the intent has no concrete surface to attribute them to.
Strict CloudWatch fallback found 6 recent prod failure log lines for mail.listThreads.reconcileFailed ([aws-primary] Connection <id> is not authorized), but the same failure had 1 log lines in the comparable pre-deploy baseline. Libra is not blaming this PR intent without a.
Strict CloudWatch fallback found 7 prod failure log lines for [syncSlackChannelForConversation] Error syncing channel (Superglue workflow failed: fetch failed), but this domain-wide failure family is not tied to this intent.
Libra has verdicts on 0 of 5 tracked behaviors on prod; 5 are still being checked. Libra checks hourly for 3 days after each deploy.
Unifies Slack/LinkedIn/WhatsApp sync onto shared containers. Phases 1, 2 and 13 of channel-sync-architecture.md.
The migrations are already applied to production. This PR makes the code match a schema that is live , the inverse of the usual risk. Everything applied was additive or guarded, and the old tables are still dual-written and authoritative until reads move.
| before | after | |
|---|---|---|
| envelope divergence | 134 | 0 |
| duplicate Slack messages | 3,344 | 0 |
| duplicate LinkedIn messages | 62 | 0 |
naive timestamp columns | 36 | 0 |
| buffer rows per shared-channel message | up to 7 | 1 |
| Slack messages with no container | 16,427 | 0 |
The envelope is derived, not written per message. LinkedIn replayed Unipile's newest-first pages through an unguarded upsert, so the last write was the oldest message: 129 of 292 chats disagreed with their own bodies, one 832 days stale at the bottom of the inbox.
Containers are shared; link and read state are per-user. slack_channels was keyed on the
owner, so a channel two reps share was two rows , 3,344 duplicated messages, and 6 of 24 shared
channels already disagreed with themselves about which deal they belonged to.
crm_events inverted onto the message. crm_slack_messages.event_id was the PK, which made
"one message = one event" structural. Ten readers assumed it; the compensating delete inverted
outright (ported naively, every member but the first would have received no events at all).
Reads are dual-read behind PostHog cedar-channel-container-reads (100%). Both stores stay
live, so setting the rollout to 0 reverts every reader with no deploy and nothing to replay.
A reconciler replaces manual SQL , channels.health / channels.reconcile, an hourly cron,
and pnpm channel-health [--reconcile].
integration_metadata mirror with no API calls. 777 channels now visible to 14
users who could never see them.projectMessageToLinkedMembers had never worked , bound an array as a scalar, and its
caller swallowed the error. Teammates would silently have lost every event.applyProviderEnvelopeFloor bound a live Date into a raw template , the 2026-07-31
mirror outage defect, again inside a swallowed catch.handleReexecuteEvent read a table the current ingest never writes
(every Slack re-run has failed since that migration), and a statistic counted
event_type = 'slack_message' where the stored value is 'slack' , always zero.pnpm run autofix:local , 187 suites / 1,831 tests greenverify-containers 15/15 ยท compare-feed 0 blocking diffs, 0 rows lost across 4 accountsCHANNEL_CONTAINER_READS=0 and =1687c2c43c, 09661ece7) from the base branch.container_id NULL; the verifier will drift until it restarts. Convergence loop is
channel_containers_converge.sql โ repair-envelopes โ verify-containers.๐ค Generated with Claude Code
The PR introduces shared Slack, LinkedIn, and WhatsApp containers with dual-write, flag-gated reads, scoped per-user state, envelope reconciliation, and operational health tooling.
Libra has not measured any production surfaces for this change yet.