Libra CodeHub

CedarCopilot/cedar-mail

Branch: staging

feat(cli): channels sync-slack , on-demand Slack channel linking

merged#2554CedarCopilot

CedarCopilot wants to merge 1 commit into staging from feature/cli-channels-sync-slack

Live on prod, no production signal yetTimeline and evidence
  1. Opened
    Aug 23, 2026, 2:33 PM
  2. Aug 23, 2026, 2:40 PM
  3. Merged
    Aug 23, 2026, 9:16 PM
  4. Live on prod
    Aug 23, 2026, 9:16 PM
  5. Observed 39 hours
    Aug 23, 2026, 9:16 PM
  6. Pipelines steady after this deploy
    Aug 23, 2026, 9:16 PM
  7. Unobserved

    Live on prod, no production signal yet

    Aug 25, 2026, 11:55 AM

Behaviors Libra is checking

Slack integration behavior from cron/process-periodic-slack-channel-sync.ts, slack/link-matching-channels.ts keeps working in prod.Inconclusivelow confidence

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.

prod, checked Aug 25, 2026, 11:55 AM

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.

Why

Pattern-based Slack channel linking (match a connection's autoSelectPatterns / selectedChannelIds, link each matching channel to its deal) previously lived only in:

  • the hourly processPeriodicSlackChannelSync cron , gated on agentExecutionEnabled, so it never runs for a user still being set up, and
  • the initial-sync --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).

What

  • Extract the cron's per-user linker into services/integrations/slack/link-matching-channels.tslinkMatchingSlackChannelsForUser(slackConn, env) (behavior unchanged; the cron now imports it).
  • Add channels.syncSlack tRPC route , same linker, for the session user, without the agentExecutionEnabled gate.
  • Add cedar-cli channels sync-slack [--for <email>].

Link-only (no message backfill), idempotent (skips already-linked + unchanged channels).

Test plan

  • 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}.
  • Cron behavior unchanged (same function, now imported).

🤖 Generated with Claude Code

Greptile Summary

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.

  • Adds channels sync-slack for on-demand, link-only Slack channel discovery.
  • Reuses the extracted linker from the existing hourly cron.
  • Preserves channel selection, archived/linked/unchanged skipping, and connection metadata persistence.

Confidence Score: 4/5

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

Important Files Changed

FilenameOverview
apps/server/src/services/integrations/slack/link-matching-channels.tsExtracts 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.tsAdds a session-scoped route that loads the caller's Slack connection and invokes the shared linker.
apps/server/src/cli/channels.tsAdds the sync-slack CLI dispatch and help text.
apps/server/src/cron/process-periodic-slack-channel-sync.tsReplaces the inline per-user implementation with the extracted shared linker while retaining cron selection and metrics behavior.

Sequence Diagram

rendering diagram…
Show production surfaces and changed-file mapping

Production surfaces

Libra has not measured any production surfaces for this change yet.

Changed files → surfaces

  • apps/server/src/cli/channels.tsno production surface mapped
  • apps/server/src/cron/process-periodic-slack-channel-sync.tsno production surface mapped
  • apps/server/src/services/integrations/slack/link-matching-channels.tsno production surface mapped
  • apps/server/src/trpc/routes/channels.tsno production surface mapped