Libra CodeHub

CedarCopilot/cedar-mail

Branch: staging

fix(tasks): a Slack task opens its channel , and the draft, the flags and the gates all agree

merged#2576CedarCopilot

CedarCopilot wants to merge 2 commits into staging from feat/slack-style-reactions

Live on prod, no production signal yetTimeline and evidence
  1. Opened
    Aug 24, 2026, 11:26 PM
  2. Aug 24, 2026, 11:51 PM
  3. Merged
    Aug 24, 2026, 11:59 PM
  4. Live on prod
    Aug 24, 2026, 11:59 PM
  5. Observed 43 hours
    Aug 24, 2026, 11:59 PM
  6. Pipelines steady after this deploy
    Aug 24, 2026, 11:59 PM
  7. Unobserved

    Live on prod, no production signal yet

    Aug 26, 2026, 6:32 PM

Behaviors Libra is checking

AOP context behavior from db/aop-schema.ts keeps working in prod.Inconclusivelow confidence

Strict CloudWatch fallback saw 1,773 success-shaped log lines matching pipeline, analytics, quota, aop, but no tied operation was present, so Libra is not calling this working.

prod, checked Aug 26, 2026, 6:12 PM
Chat workflow behavior from conversation-inbox/ConversationInboxLayout.tsx keeps working in prod.Inconclusivelow confidence

Strict CloudWatch fallback found 3 prod failure log lines for mirror.upsertEmailThread failed (write CONNECTION_CLOSED aws-1-us-east-2.pooler.supabase.com:6543), but this domain-wide failure family is not tied to this intent.

prod, checked Aug 26, 2026, 6:12 PM
Data model behavior from db/schema.ts keeps working in prod.Inconclusivelow confidence

OTEL fallback saw 123,089 prod spans for the repo/env since deploy, but 4,622 were errors and the intent has no concrete surface to attribute them to.

prod, checked Aug 26, 2026, 6:20 PM
Email workflow behavior from tasks/layout.tsx, ui/active-view-display.tsx, hotkeys/view-stack-manager.tsx keeps working in prod.Inconclusivelow confidence

Strict CloudWatch fallback found 3 prod failure log lines for mirror.upsertEmailThread failed (write CONNECTION_CLOSED aws-1-us-east-2.pooler.supabase.com:6543), but this domain-wide failure family is not tied to this intent.

prod, checked Aug 26, 2026, 6:20 PM
Slack integration behavior from utils/open-slack-channel-from-task.ts, draft-comms/saveSlackDraftTool.ts, event-execution/onEventExecutionDraftSlackTool.ts keeps working in prod.Inconclusivelow confidence

Strict CloudWatch fallback found 2 recent prod failure log lines for [backfillSlackChannelHistory] Backfill failed (Failed query: insert into \), but the same failure had 3 log lines in the comparable pre-deploy baseline. Libra is not blaming this PR intent without a.

prod, checked Aug 26, 2026, 6:32 PM

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.

Summary

Continues feat/slack-style-reactions past the merge of #2571. Two threads of work:

A Slack task opens its channel. Previously a Slack task opened a draft card inside the task ticket , the same words, in a surface that cannot send them. It now opens the actual channel through the same display-artifact mechanism an email task opens its thread with, with the drafted message seeded into that channel's composer.

The task ticket reads like a Linear issue. A header row and two columns: editable title and notes, the deal as the shared ConversationBadge, the source thread rendered inline, the triggering event named and openable, and a properties rail of icon+value rows. Plus /inbox-style thread preloading on hover and after a task list loads, so a task no longer opens cold.

Also: a drizzle schema-barrel fix (taskGroups was referenced by a relation but not exported, so with: { taskGroup: true } 500'd at query time), correlation ids in tRPC error bodies, and DM-backfill that resumes where it stopped.

Review fixes in this PR

A /review pass over the branch found the defects clustered in one place: the new slack_thread artifact kind had to be added to several independent enumerations, and only some of them got it. Each omission is silent in its own direction.

  • The draft went to the wrong composer. There are two Slack composers fed by two different mechanisms , the per-deal timeline one takes a ProseMirror doc, the unibox's ChannelThreadView takes raw mrkdwn via pending-channel-draft. The task path seeded the deal's while opening the unibox's, so the message landed in a surface the click never navigated to. One shared open-slack-channel-from-task.ts now, which also de-duplicates a closure copied into both call sites.
  • The channel name landed in a field Slack doesn't read. The stand-in feed row put #channel in counterpart.name, but a Slack channel's title is read off counterpart.subtitle , every hinted channel rendered a header saying "Slack channel". Built to slackMessageToItem's real shape, which also retires an as unknown as InboxItem cast that was hiding it.
  • A sent message was re-seeded. Sending completes the task but leaves the text on taskActionData, and there is no sentAt , so re-opening a done task dropped an already-posted message into the composer, one Enter from a duplicate.
  • Three more enumerations listed three kinds out of four: setNavigationPage left isSlackThreadOpen true with the artifact already null (a flag with nothing behind it, which every route gate reads as "open"); useExitTaskExecutionOnClose never saw a Slack channel closing, so ?task=/?group= outlived it; ConversationInboxLayout and mail.tsx omitted isTaskOutputOpen while ?task= is routed from the root layout.
  • A blank page with no way off it. When neither a feed row nor a hint resolved, ActiveViewDisplay returned null while its hosts had already hidden everything else. It now says so and offers Back.
  • Escape tore down the whole ticket. EditableText's Escape called preventDefault but not stopPropagation, so the native event still reached TaskTicketView's window listener , and with the title and notes now always-mounted fields, backing out of a word closed the ticket.

The branch's invariant test covered one of the four enumerations; it now covers the exit hook and setNavigationPage too, and a new suite pins which composer gets seeded.

Test plan

  • pnpm run autofix:local , green, before and after merging origin/staging
    • mail: 269 suites, 2,568 tests
    • server: 690 files, 7,376 tests
  • pnpm --filter @zero/mail run types and @zero/server run types , clean
  • New: openSlackChannelFromTask.test.ts (which composer is seeded, the sent-draft guard, the artifact write); sent-task case in open-task.test.ts; overlayArtifactCoverage.test.ts extended to the exit hook and setNavigationPage

Known, not addressed

`pnpm --filter @z

Show production surfaces and changed-file mapping

Production surfaces

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

Changed files → surfaces

  • apps/mail/app/(routes)/tasks/layout.tsxno production surface mapped
  • apps/mail/components/ui/active-view-display.tsxno production surface mapped
  • apps/mail/lib/hotkeys/view-stack-manager.tsxno production surface mapped
  • apps/mail/modules/agentCanvas/components/AgendaDocument.tsxno production surface mapped
  • apps/mail/modules/agentCanvas/extensions/AgendaTaskNode.tsxno production surface mapped
  • apps/mail/modules/agentCanvas/utils/agenda-artifact-actions.tsno production surface mapped
  • apps/mail/modules/cedar-os/src/store/CedarStore.tsno production surface mapped
  • apps/mail/modules/cedar-os/src/store/messages/messagesSlice.tsno production surface mapped
  • apps/mail/modules/cedar-os/src/store/messages/renderers/MainAgentThinkingRenderer.tsxno production surface mapped
  • apps/mail/modules/conversations/components/EditableText.tsxno production surface mapped
  • apps/mail/modules/conversations/components/nextSteps/TaskBlock.tsxno production surface mapped
  • apps/mail/modules/conversations/components/timeline/helpers.tsxno production surface mapped
  • apps/mail/modules/inbox/components/ChannelThreadView.tsxno production surface mapped
  • apps/mail/modules/inbox/store/inboxSlice.tsno production surface mapped
  • apps/mail/modules/threads/conversation-inbox/ConversationInboxLayout.tsxno production surface mapped
  • apps/mail/modules/threads/mail.tsxno production surface mapped
  • apps/mail/modules/threads/thread/components/ConversationBadge.tsxno production surface mapped
  • apps/mail/modules/threads/threadList/store/threadSlice.tsno production surface mapped
  • apps/mail/modules/userTasks/components/ChannelIcon.tsxno production surface mapped
  • apps/mail/modules/userTasks/components/TaskExecutionList.tsxno production surface mapped
  • apps/mail/modules/userTasks/components/TaskExecutionUrlSync.tsxno production surface mapped
  • apps/mail/modules/userTasks/components/TaskKanbanBoard.tsxno production surface mapped
  • apps/mail/modules/userTasks/components/TaskKanbanCard.tsxno production surface mapped
  • apps/mail/modules/userTasks/components/TaskListRow.tsxno production surface mapped
  • apps/mail/modules/userTasks/components/TaskTicketProperties.tsxno production surface mapped
  • apps/mail/modules/userTasks/components/TaskTicketView.tsxno production surface mapped
  • apps/mail/modules/userTasks/hooks/use-exit-task-execution-on-close.tsno production surface mapped
  • apps/mail/modules/userTasks/hooks/use-hydrate-tasks-slice.tsno production surface mapped
  • apps/mail/modules/userTasks/hooks/use-open-task-in-execution-mode.tsno production surface mapped
  • apps/mail/modules/userTasks/hooks/use-prefetch-task-threads.tsno production surface mapped
  • apps/mail/modules/userTasks/slice/userTasksSlice.tsno production surface mapped
  • apps/mail/modules/userTasks/utils/open-slack-channel-from-task.tsno production surface mapped
  • apps/mail/modules/userTasks/utils/open-task.tsno production surface mapped
  • apps/mail/modules/userTasks/utils/task-threads.tsno production surface mapped
  • apps/mail/modules/ux/layout/LayoutUrlSync.tsxno production surface mapped
  • apps/mail/modules/ux/uxSlice.tsno production surface mapped
  • apps/mail/tests/modules/agentCanvas/agendaTaskNode.test.tsxno production surface mapped
  • apps/mail/tests/modules/inbox/slackChannelHint.test.tsno production surface mapped
  • apps/mail/tests/modules/userTasks/open-task.test.tsno production surface mapped
  • apps/mail/tests/modules/userTasks/openSlackChannelFromTask.test.tsno production surface mapped
  • apps/mail/tests/modules/userTasks/openTaskInExecutionModeGroup.test.tsxno production surface mapped
  • apps/mail/tests/modules/userTasks/openTaskKeepsExecutionMode.test.tsxno production surface mapped
  • apps/mail/tests/modules/userTasks/taskThreadPrefetchHooks.test.tsxno production surface mapped
  • apps/mail/tests/modules/userTasks/taskThreadPreload.test.tsno production surface mapped
  • apps/mail/tests/modules/userTasks/taskTicketProperties.test.tsxno production surface mapped
  • apps/mail/tests/modules/userTasks/taskTicketView.test.tsxno production surface mapped
  • apps/mail/tests/modules/userTasks/updatingTasksBridge.test.tsxno production surface mapped
  • apps/mail/tests/modules/ux/artifactOpenFlags.test.tsno production surface mapped
  • apps/mail/tests/modules/ux/overlayArtifactCoverage.test.tsno production surface mapped
  • apps/server/docs/customer-feedback-loop.mdno production surface mapped
  • apps/server/docs/next-steps-commitment-split.mdno production surface mapped
  • apps/server/src/cli/channels.tsno production surface mapped
  • apps/server/src/db/aop-schema.tsno production surface mapped
  • apps/server/src/db/schema.tsno production surface mapped
  • apps/server/src/mastra/tools/draft-comms/saveSlackDraftTool.tsno production surface mapped
  • apps/server/src/mastra/tools/event-execution/onEventExecutionDraftSlackTool.tsno production surface mapped
  • apps/server/src/mastra/utils/__tests__/slack-channel-ref.test.tsno production surface mapped
  • apps/server/src/mastra/utils/slack-channel-ref.tsno production surface mapped
  • apps/server/src/services/playbook/playbook-doc-hooks.tsno production surface mapped
  • apps/server/src/trpc/__tests__/error-correlation-ids.test.tsno production surface mapped
  • apps/server/src/trpc/routes/__tests__/get-task-by-id-ticket-fields.test.tsno production surface mapped
  • apps/server/src/trpc/routes/channels.tsno production surface mapped
  • apps/server/src/trpc/routes/user-tasks.tsno production surface mapped
  • apps/server/src/trpc/trpc.tsno production surface mapped