Libra CodeHub

CedarCopilot/cedar-mail

Branch: staging

fix(slack): emit standard Markdown, not Slack `*bold*` mrkdwn

merged#2539CedarCopilot

CedarCopilot wants to merge 0 commits into staging from fix/slack-markdown-dialect-contract

Live on prod, no production signal yetTimeline and evidence
  1. Opened
    Aug 21, 2026, 10:44 AM
  2. Merged
    Aug 22, 2026, 9:04 AM
  3. Live on prod
    Aug 22, 2026, 9:04 AM
  4. Observed 2 days
    Aug 22, 2026, 9:04 AM
  5. Pipelines steady after this deploy
    Aug 22, 2026, 9:04 AM
  6. Unobserved

    Live on prod, no production signal yet

    Aug 25, 2026, 7:54 AM

Behaviors Libra is checking

All Slack-bound agent prompts and tool inputs consistently require `**bold**`, `-` bullets, and `###` headers, while rejecting Slack `*bold*` mrkdwn and literal bullet characters.Degradedlow confidence

Strict CloudWatch fallback found 1 prod failure log lines for [run-chat-agent-sdk] query() failed (Claude Code process aborted by user) in the last 24h while checking sendslacktool, notifyusertool, bullets, and, headers, while rejecting slack, chat-agent.

prod, checked Aug 25, 2026, 7:54 AM
Slack notification thread replies can be used to place the full body of a long brief beneath a concise lead message.Inconclusivelow confidence

OTEL fallback found no prod spans matching notifyUserTool slack.threadReplies since deploy.

prod, checked Aug 23, 2026, 5:11 PM
Slack messages drafted or generated across chat, notification, and Slack-send flows use standard Markdown so bold text renders as native bold rather than italic.Inconclusivelow confidence

OTEL fallback found no prod spans matching buildBlockKitBlocks / Slack rich_text notifications since deploy.

prod, checked Aug 23, 2026, 5:11 PM

Libra has verdicts on 0 of 3 tracked behaviors on prod; 3 are still being checked. Libra has 1 low-confidence degraded verdict it is still confirming. Libra checks hourly for 3 days after each deploy.

Problem

Meeting-prep (and other automated) Slack messages still render with bad formatting even though the "universal Slack styling" fix (#2359) is live. Root cause is a Markdown-dialect mismatch, not a missing deploy.

  • #2359's renderer (markdown-to-slack-richtext.ts) parses message bodies as standard Markdown: **x** → bold, and a single *x*italic (regex m[15]). There is no mrkdwn→Markdown normalization step.
  • But agents were still told to use Slack mrkdwn (*bold*, ). So every section label an agent wrote as *Open Commitments* / *Top priorities:* rendered italic, and long prep briefs looked broken.

Verified against real runs on <email> (Dynasty / Hey Telo meeting-prep, Aug 21): the delivered notify-user bodies contain single-asterisk labels and literal bullets.

This same trap was already fixed in notifications/SKILL.md and agent-defaults/pipeline-review.ts (which explicitly says use **bold**, "a real header block , not *italic*", "never the literal "). This PR propagates that contract to the sources that were missed.

Fix

The decisive gap: the notify-user / send-slack tool descriptions had no markup guidance at all , text was just "Sent to all configured notification channels", and send-slack even claimed "converted to Slack mrkdwn automatically." That tool schema is the guidance every automated agent sees at the point of use, regardless of which skill it loaded , so it's the lever that actually reaches meeting-prep / daily-agenda.

  • notify-user: text and threadReplies[].text now state the Markdown contract (**bold** not *bold*; - bullets never ; ### headers).
  • send-slack: corrected the misleading message description.
  • drafting/slack.md: **bold**, - bullets (never ), ### headers , was *bold* / - or .
  • drafting-content.ts: the Slack side of the channel-format rule matches the above (email/HTML side unchanged).

Why guidance-only (no converter change)

*x* is legitimately italic in Markdown, so teaching the converter to treat single-asterisk as bold would break real italics. The house contract (per the converter, notifications/SKILL.md, and pipeline-review.ts) is "standard Markdown" , this aligns the remaining guidance to it.

Note / follow-up

LLMs have a strong "Slack bold = *x*" prior, so guidance raises adherence but may not be a 100% guarantee. If a specific agent (e.g. a customized meeting-prep subagent) keeps drifting, the belt-and-suspenders is to make that subagent's own Notify step explicit , a per-account playbook edit, out of scope here.

Test plan

  • Trigger a meeting-prep run; confirm section labels render bold (not italic) and bullets are native rich_text.
  • Confirm a drafted Slack follow-up (draft-slack) uses **bold** / -.

🤖 Generated with Claude Code

Greptile Summary

This PR aligns Slack-facing agent instructions and notification tool schemas with Cedar’s standard-Markdown-to-rich-text renderer.

  • Replaces Slack mrkdwn guidance with **bold**, - bullets, and ### headings.
  • Updates notify-user, thread-reply, and send-slack parameter descriptions.
  • Leaves a cross-channel mismatch because shared notify-user.text is also delivered to WhatsApp without equivalent Markdown normalization.

Confidence Score: 4/5

The cross-channel notify-user guidance should be fixed before merging because WhatsApp recipients can receive raw standard-Markdown markers.

The new formatting contract is correct for Slack and normalized for iMessage, but the shared notification text reaches WhatsApp without converting or stripping the newly mandated emphasis and heading syntax.

Files Needing Attention: apps/server/src/mastra/tools/notify/notifyUserTool.ts

Important Files Changed

FilenameOverview
apps/
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/.claude/skills/drafting/slack.mdno production surface mapped
  • apps/server/src/mastra/agents/chat-agent.tsno production surface mapped
  • apps/server/src/mastra/routeHandlers/slack/slack-bot-chat.tsno production surface mapped
  • apps/server/src/mastra/skills/drafting/drafting-content.tsno production surface mapped
  • apps/server/src/mastra/tools/notify/notifyUserTool.tsno production surface mapped
  • apps/server/src/mastra/tools/notify/sendSlackTool.tsno production surface mapped
  • apps/server/src/mastra/workflows/chat/chat-workflow.tsno production surface mapped
  • apps/server/src/services/notifications/slack-block-kit.tsno production surface mapped