Libra CodeHub

CedarCopilot/cedar-mail

Branch: staging

fix(notifications): align agent prompt + skill with notify-user's email channel

merged#2544CedarCopilot

CedarCopilot wants to merge 0 commits into staging from fix/automation-agent-allow-email-channel

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

    Live on prod, no production signal yet

    Aug 25, 2026, 8:55 AM

Behaviors Libra is checking

Automation agents can send a notification as a real email by explicitly passing `channel: "email"`, including for reports intended for the user's inbox.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 notifytool, notify-user, channel:"email", success: true, send-email.

prod, checked Aug 25, 2026, 8:55 AM
A failed notification is reported as failed and stopped rather than causing an agent to create a Gmail draft or independently reroute the message to email.Not checked
prod
Notifications now deliver through the user's selected/default single channel (Slack, email, iMessage, or WhatsApp) rather than faning out to every configured channel.Not checked
prod

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.

What

Align the headless notification surfaces with what notify-user actually does, and give the consolidated notify tool a real way to request email.

  • automation-agent system prompt + notifications SKILL.md: drop the false "Notifications are never delivered by email" / "fans out to all channels" claims; keep the guardrail (never draft/reroute around a failed channel).
  • notify family tool: add an optional channel (email|slack|imessage|whatsapp) to send, forwarded to notify-user; correct its description + text wording + file-header rationale.
  • notifications-skill.ts header comment updated to match.

Why

On current staging, notify-user delivers to the ONE channel the user chose (resolvePrimaryChannel) , and that set includes email , with a named email fallback. The prompt/skill/tool text all still said email was never a notification channel, and the notify family send had no channel param at all, so an agent instructed to email couldn't reliably do it.

Evidence (playbook-instruction-eval harness)

Real tool descriptions, record-only stubs, 8 trials, claude-sonnet-5. Target = deliver via notify-user(channel:"email"), no draft:

old promptthis PR
meeting-prep-style instruction6/88/8
digest-style instruction8/88/8

Guardrail preserved

Keeps the rule that prevented the original incident (a dead Slack grant → unrequested mail): never create a draft, or otherwise reroute, to route around a failed channel. Email is a caller-chosen channel, never inferred from a delivery failure.

Blast radius

No behavior change for users who don't ask for email , notify-user/notify send still resolve each user's own chosen channel by default. Verified: 30/30 notify unit tests pass; @zero/server typecheck clean.

šŸ¤– Generated with Claude Code

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/notifications/SKILL.mdno production surface mapped
  • apps/server/src/mastra/agents/automation-agent.tsno production surface mapped
  • apps/server/src/mastra/skills/notifications/notifications-skill.tsno production surface mapped
  • apps/server/src/mastra/tools/notify/__tests__/notifyTool.test.tsno production surface mapped
  • apps/server/src/mastra/tools/notify/notifyTool.tsno production surface mapped