CedarCopilot wants to merge 1 commit into staging from feature/cli-channels-sync-slack
Live on prod, no production signal yet
Strict CloudWatch fallback found 7 prod failure log lines for [backfillSlackChannelHistory] Backfill failed (Failed query: insert into \), but this domain-wide failure family is not tied to this intent.
Libra has verdicts on 0 of 1 tracked behaviors on prod; 1 is still being checked. Libra checks hourly for 3 days after each deploy.
Pattern-based Slack channel linking (match a connection's autoSelectPatterns / selectedChannelIds, link each matching channel to its deal) previously lived only in:
processPeriodicSlackChannelSync cron , gated on agentExecutionEnabled, so it never runs for a user still being set up, and--slack-sync step , which runs before the deals it would match exist.Result: a freshly-onboarded rep's ext-* deal channels stay unlinked until go-live, and there was no CLI way to link them on demand (only the UI's connect-channels flow).
services/integrations/slack/link-matching-channels.ts → linkMatchingSlackChannelsForUser(slackConn, env) (behavior unchanged; the cron now imports it).channels.syncSlack tRPC route , same linker, for the session user, without the agentExecutionEnabled gate.cedar-cli channels sync-slack [--for <email>].Link-only (no message backfill), idempotent (skips already-linked + unchanged channels).
pnpm --filter @zero/server run types , clean.cedar-cli channels sync-slack --for <email> against a pre-go-live account with ext- channels + autoSelectPatterns: [{startsWith:"ext-"}] → links the matching channels, returns {linked, skipped, errors}.🤖 Generated with Claude Code
The PR extracts periodic Slack pattern matching into a shared linker and exposes it through a session-scoped tRPC mutation and a new CLI command.
channels sync-slack for on-demand, link-only Slack channel discovery.The PR should not merge until explicit sync-slack reruns can retry still-unlinked channels instead of silently skipping unsuccessful prior attempts.
The new on-demand workflow persists success:false attempts into the unchanged-channel cache, so a normal unresolved result prevents subsequent operator-triggered retries unless Slack metadata happens to change; the remaining findings are non-blocking repository-convention violations.
Files Needing Attention: apps/server/src/services/integrations/slack/link-matching-channels.ts and apps/server/src/trpc/routes/channels.ts
| Filename | Overview |
|---|---|
| apps/server/src/services/integrations/slack/link-matching-channels.ts | Extracts the cron linker, but unsuccessful non-null attempts are persisted as unchanged and prevent explicit command retries; it also violates import-layer conventions. |
| apps/server/src/trpc/routes/channels.ts | Adds a session-scoped route that loads the caller's Slack connection and invokes the shared linker. |
| apps/server/src/cli/channels.ts | Adds the sync-slack CLI dispatch and help text. |
| apps/server/src/cron/process-periodic-slack-channel-sync.ts | Replaces the inline per-user implementation with the extracted shared linker while retaining cron selection and metrics behavior. |
Libra has not measured any production surfaces for this change yet.