Libra CodeHub

CedarCopilot/cedar-mail

Branch: staging

fix(slack): create the container before recording participants

merged#2601CedarCopilot

CedarCopilot wants to merge 2 commits into staging from fix/slack-bootstrap-participant-order

Live on prod since Wed, 1 of 3 behaviors workingTimeline and evidence
  1. Opened
    Aug 26, 2026, 7:08 PM
  2. Aug 26, 2026, 7:34 PM
  3. Merged
    Aug 26, 2026, 7:52 PM
  4. Live on prod
    Aug 26, 2026, 7:52 PM
  5. Observed 25 hours
    Aug 26, 2026, 7:52 PM
  6. Pipelines steady after this deploy
    Aug 26, 2026, 7:52 PM
  7. Verified

    Live on prod since Wed, 1 of 3 behaviors working

    Aug 27, 2026, 9:07 PM

Behaviors Libra is checking

Slack channels linked during bot-join/bootstrap now resolve or create their channel container before saving members, so member evidence is available for counterparty-domain link evaluation even when the channel has no messages.Workingmedium confidence

Since the deploy, 182 prod OTEL spans matching linkSlackChannelOnly ran with 0 error spans. In the 26h before the deploy the same surface ran 365 OTEL spans with 0 error spans. Confidence is medium because the surface was already clean before the deploy, so this confirms no.

prod, checked Aug 27, 2026, 9:02 PM
Slack participant evidence is written directly to the caller's resolved container, preventing Slack Connect organizations from recording one organization's members in another organization's container.Not checked
prod, checked Aug 27, 2026, 9:04 PM
Slack participant recording now reports the number of participant rows actually inserted or updated, including reporting zero when no matching container exists, rather than counting attempted writes.Not checked
prod, checked Aug 27, 2026, 9:07 PM

Libra has verdicts on 1 of 3 tracked behaviors on prod; 2 are still being checked. Libra checks hourly for 3 days after each deploy.

Follow-up to #2597, from Greptile's review of it. The bootstrap landed in the wrong order, so the feature it was meant to enable still did not work.

What was wrong

recordSlackChannelParticipants is an INSERT ... SELECT c.id FROM channel_containers c. With no container row, the SELECT matches nothing and it writes zero participants.

In #2597 that call ran before the bootstrap. So on exactly the uningested channels the bootstrap exists to onboard, the container was created empty , and the link ladder reads channel_container_participants to derive the counterparty domain (link-runner.ts:337), so those channels still could not link. The bootstrap created a row and changed nothing else.

It would have self-healed on a second run, once the container existed , but a one-shot channels sync-slack reports 0 linked and looks broken.

Changes

  1. Reorder , resolve-or-bootstrap the container first, then record participants. That is the whole fix; the identity needed to create the container never depended on the participants.

  2. Honest count , recordSlackChannelParticipants counted written += 1 per attempted participant regardless of what the database did, so it reported a healthy participant total for a container that had none. That is why an empty container was invisible rather than obvious. It now sums real rowCount.

Tests

3 new. Verified they fail against the old counting (1 failed / 2 passed with the old written += 1 restored) and pass with the fix.

Credit to Greptile for catching this , it was a P1 on a PR I had already reviewed and merged.

šŸ¤– Generated with Claude Code

Greptile Summary

This PR reorders Slack link-only onboarding so the channel container exists before participants are persisted, and changes participant reporting to count database writes.

  • Resolves or bootstraps the organization-scoped Slack container before recording member evidence.
  • Adds a participant-write count to tracing and tests intended to distinguish attempted from successful writes.
  • The reordered call remains insufficiently scoped for Slack Connect containers, and the count relies on an unsupported database result field.

Confidence Score: 2/5

This PR should not merge until participant writes are restricted to the resolved container and affected-row counting uses a result shape supported by the real database adapters.

The reordered bootstrap path can contaminate participant evidence across organizations sharing a Slack Connect channel, while successful database writes are incorrectly reported as zero because the implementation reads an unreliable result field.

Files Needing Attention: apps/server/src/services/integrations/slack/slack-sync.ts, apps/server/src/services/channels/adapters/slack-evidence.ts, and the participant-count test

Security Review

The participant INSERT is not scoped to the resolved container or organization. For Slack Connect channels shared across organizations, the newly reachable bootstrap path can persist one organization's fetched participant evidence into another organization's container. How this was verified: The resolved container is user-scoped, but the subsequent INSERT SELECT matches all containers sharing the channel ID and account reference without an organization or container-ID predicate.

Important Files Changed

FilenameOverview
apps/server/src/services/integrations/slack/slack-sync.tsCorrects bootstrap ordering, but the newly effective participant write can target matching containers outside the resolved organization.
apps/server/src/services/channels/adapters/slack-evidence.tsAdds affected-row accounting through a result field unsupported by the actual database adapters while retaining an organization-unscoped INSERT SELECT.
apps/server/src/services/c
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/services/channels/adapters/__tests__/record-participants-count.test.tsno production surface mapped
  • apps/server/src/services/channels/adapters/slack-evidence.tsno production surface mapped
  • apps/server/src/services/integrations/slack/slack-sync.tsno production surface mapped
  • apps/server/src/trpc/routes/channels.tsno production surface mapped