Libra CodeHub

CedarCopilot/cedar-mail

Branch: staging

fix(slack): deliver Go Deeper's real content instead of a one-line receipt

merged#2773CedarCopilot

CedarCopilot wants to merge 2 commits into staging from fix/go-deeper-content-delivery

Live on prod, no production signal yetTimeline and evidence
  1. Opened
    Sep 13, 2026, 1:25 PM
  2. Sep 13, 2026, 1:51 PM
  3. Merged
    Sep 13, 2026, 2:12 PM
  4. Live on prod
    Sep 13, 2026, 2:12 PM
  5. Observed 2 days
    Sep 13, 2026, 2:12 PM
  6. Pipelines steady after this deploy
    Sep 13, 2026, 2:12 PM
  7. Unobserved

    Live on prod, no production signal yet

    Sep 15, 2026, 7:30 PM

Behaviors Libra is checking

Agent_prompt operations without deliverContentToThread retain their existing short-receipt behavior and do not receive Slack notification instructions or make an unrelated notify call.Inconclusivelow confidence

Verification reached its budget before a verdict.

prod, checked Sep 15, 2026, 6:38 PM
The agent_prompt operation establishes the selected granular or families tool surface before generating preambles and loading user skills so skill tool references resolve to tools available to the active chat agent.Inconclusivelow confidence

Verification reached its 120s wall-clock budget before a tied verdict. Libra is keeping this intent verifying until the next check.

prod, checked Sep 15, 2026, 6:40 PM
When a content-producing Slack button opts in with deliverContentToThread, the agent posts the complete breakdown or report back to the clicked Slack thread instead of losing it in the short final_answer receipt.Inconclusivelow confidence

Unable to complete the verification because the production agent_prompt telemetry query was aborted before yielding results.

prod, checked Sep 15, 2026, 7:25 PM
Slack interaction dispatch resolves the delivery thread from the clicked message's parent thread_ts, or from the clicked message ts when the message is a top-level thread root, and propagates it with the channel ID into the operation context.Inconclusivelow confidence

Verification reached its 130s outer budget before the verifier returned. Libra is keeping this intent verifying until the next check.

prod, checked Sep 15, 2026, 7:30 PM
Opted-in content delivery uses notify-user with flat slack parameters on the granular tool surface and uses notify with action "send" and nested send.slack parameters on the families tool surface.Not checked
prod, checked Sep 15, 2026, 7:25 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

Aspire's daily-call-summary digest posts each customer call to Slack with a "Go Deeper" button meant to post a fuller breakdown back into the thread on click. In production, clicking it completed successfully server-side but nothing useful ever reached Slack , only a one-line confirmation sentence landed on the original message, describing a breakdown that was never actually written down anywhere.

Root cause: "Go Deeper" reuses the generic Slack approval-button machinery (agent_prompt op), whose shared wrapper prompt caps the model's <final_answer> text at "ONLY a short confirmation (1-2 sentences)". That's correct for apply-style buttons (CRM field change, task update) where the real effect already happened via a tool call and the text is just a receipt , but Go Deeper has no other effect; the breakdown is the deliverable, and it was silently discarded.

Changes

  • handleSlackInteraction now derives the real Slack channel + thread from the click payload itself (the only place it can be known , a button's prompt is authored before the thread's ts exists) and passes it through OperationContext.
  • agent_prompt gains an opt-in deliverContentToThread arg. When set, the wrapper prompt instructs the run to post its real output via notify-user into that channel/thread, and lets <final_answer> stay a short receipt.
  • Kept opt-in, not automatic: my first pass injected the new instruction unconditionally into every agent_prompt run. agent_prompt also backs the "Accept" button on essentially every CRM-approval card across every Cedar customer (crm-updater.ts, plus pipeline-review.ts, inbound-email-notifier.ts, ambiguity-ping-message.ts) , those must see an unchanged prompt. Caught this in a thermo-review pass on the diff before opening this PR; fixed by gating behind the new opt-in arg, with a regression test locking in that ordinary approval buttons are unaffected.
  • Also updates Aspire's live daily-call-summary org subagent doc to set deliverContentToThread: true on its button and documents the failure mode directly in the doc so it doesn't quietly regress.

Test plan

  • pnpm --filter @zero/server run types , clean
  • pnpm --filter @zero/server exec vitest run src/mastra/operations/__tests__/operation-registry.test.ts , 6/6 passing (3 new: instruction present when opted in, "lost" warning present, and , the regression guard , absent entirely when not opted in)
  • pnpm deps:check , 0 violations
  • Traced every existing call site of dispatchOperation/agent_prompt (Slack buttons, Slack reactions, iMessage tapbacks) to confirm no other surface is affected
  • Manual: next daily-call-summary digest run in Aspire's #cedar-call-reviews, click "Go Deeper" on a call entry, confirm the real breakdown posts as a new thread reply

šŸ¤– Generated with Claude Code

https://claude.ai/code/session_01GPYHTQhFJ4WuDvsnoUVHy3

Greptile Summary

This PR adds opt-in delivery of substantive agent_prompt output to the Slack thread where a button was clicked.

  • Captures the Slack channel and parent-thread timestamp from block_actions payloads.
  • Adds deliverContentToThread to agent_prompt and instructs the agent to use a notification tool for long-form content.
  • Adds prompt-level regression tests ensuring ordinary approval buttons remain unchanged.
  • The delivery instruction currently names only the granular notification tool, leaving the feature broken when the family-agent surface is selected.

Confidence Score: 4/5

This PR is not yet safe to merge because threaded content delivery remains broken whenever the family-agent feature flag selects the notify tool surface.

The new prompt always mandates the granular notify-user interface, while the existing runtime can select a family toolset that exposes only notify with a different argument schema, preventing the substantive Slack

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/mastra/operations/__tests__/operation-registry.test.tsno production surface mapped
  • apps/server/src/mastra/operations/operation-registry.tsno production surface mapped
  • apps/server/src/mastra/routeHandlers/slack/slack-interactions.tsno production surface mapped