Libra CodeHub

CedarCopilot/cedar-mail

Branch: staging

fix: 2 Sherlock-rooted bugs , chat JSON leak, escaped subjects

merged#2802CedarCopilot

CedarCopilot wants to merge 4 commits into staging from fix/concentrate-bug-bundle-sept16

Live on prod since Thu, 4 of 12 surfaces workingTimeline and evidence
  1. Opened
    Sep 16, 2026, 7:00 AM
  2. Sep 16, 2026, 8:50 AM
  3. Merged
    Sep 17, 2026, 8:46 AM
  4. Live on prod
    Sep 17, 2026, 8:46 AM
  5. Observed 28 hours, 12 surfaces, 2,327 requests
    Sep 17, 2026, 8:46 AM
  6. Pipelines steady after this deploy
    Sep 17, 2026, 8:46 AM
  7. Verified

    Live on prod since Thu, 4 of 12 surfaces working

    Sep 18, 2026, 12:55 PM

Behaviors Libra is checking

Subjects written to Gmail drafts decode HTML entities so escaped text such as &lt;&gt; is stored and displayed as <>.Inconclusivelow confidence

Verification cited only 3 matching post-deploy events, below the 20-event floor for calling a change verified. Nothing is failing; there is not yet enough traffic to confirm it.

prod, checked Sep 18, 2026, 12:53 PM
Subjects sent through Gmail decode HTML entities before delivery so recipients see the intended subject text instead of escaped entities.Inconclusivelow confidence

Strict CloudWatch fallback saw 638 success or completion log lines and 30,570 failure-shaped log lines matching googlemailmanager, sendmessage, clientexecutionresponseprocessors, google, googlemailmanager.sendmessage; this needs a tied operation before Libra moves the card.

prod, checked Sep 18, 2026, 12:55 PM
Client execution responses with a null taskChannel are accepted and processed instead of failing TaskObjectSchema validation.Not checked
prod, checked Sep 18, 2026, 12:50 PM

Libra measured 4 of 12 production surfaces on prod. 1 surface had under 20 requests, so Libra has not judged it; 6 surfaces had no requests at all. Libra checks hourly for 3 days after each deploy.

Summary

Two independently root-caused bug fixes:

  1. Raw internal JSON leaking into the chat transcript (apps/mail/modules/cedar-os/src/store/agentConnection/responseProcessors/clientExecutionResponseProcessors.ts) Cause: TaskObjectSchema.taskChannel was z.string(), rejecting the legitimate null the backend sends for a task with no linked draft/output (the common case for a plain follow-up task). The failed Zod validation fell through to a fallback that renders the raw event object as a JSON code block in the visible chat. Fix: one-line change to z.string().nullable(). (Verified taskChannel is a legacy, write-only field never branched on downstream, so this doesn't need any further hardening.)

  2. HTML entities rendered literally in email subject lines (apps/server/src/lib/driver/google.ts) Cause: the drafting LLM sometimes fills a subject with HTML-escaped angle brackets (literal &lt;/&gt;); nothing decoded it before calling Gmail's API on the write path, even though the read path already does (he.decode when reading a subject back). Fix: he.decode(...) immediately before both setSubject() call sites (createDraft and send/parseOutgoing). No-op when the subject was never escaped.

Notes

  • A third fix , widening the pre-draft staleness re-check (checkThreadForNewerActivity) to also run for non-email-triggered drafting dispatches , was originally bundled here to address a customer-reported duplicate/stale-draft bug. Deeper investigation (checking DraftAnalytics/Axiom telemetry and task-execution history for the actual reported case) found no evidence this code path was the mechanism behind that bug, so it's been pulled pending further investigation rather than shipped as an unproven fix. It is no longer part of this PR.
  • The fourth fix originally bundled here , stale UI after a background execution completes, via a new /api/conversation-events SSE endpoint , grew large enough (a brand-new HTTP endpoint, not just a hook change) that it's been split out into its own PR: #2803.
  • apps/server/src/lib/driver/google.ts is a pre-existing large file (5400+ lines); this PR's addition to it is small and doesn't attempt any decomposition, which is out of scope here.

Test plan

  • pnpm --filter @zero/server run types , clean
  • pnpm --filter @zero/mail run types , clean
  • pnpm deps:check , no dependency violations
  • pnpm --filter @zero/server exec vitest run src/mastra/tools/event-execution/__tests__/drafter-executor-prompt.test.ts , 28/28 passing

šŸ¤– Generated with Claude Code

Show production surfaces and changed-file mapping

Production surfaces

SurfaceRequestsErrorsp95UsersVerdict
/a8n/notify/google720 → 11460 → 0 (0%)221 ms → 204 ms0Working
1,146 requests since the deploy with 0 errors (0 errors in the 720-request baseline before it). p95 204 ms, was 221 ms.
POST /a8n/notify/google72 → 3820 → 0 (0%)398 ms → 205 ms0Working
382 requests since the deploy with 0 errors (0 errors in the 72-request baseline before it). p95 205 ms, was 398 ms.
/a8n/notify/google-calendar83 → 1320 → 0 (0%)1312 ms → 133 ms0Working
132 requests since the deploy with 0 errors (0 errors in the 83-request baseline before it). p95 133 ms, was 1312 ms.
POST /a8n/notify/google-calendar5 → 440 → 0 (0%)2392 ms → 133 ms0Working
44 requests since the deploy with 0 errors (0 errors in the 5-request baseline before it). p95 133 ms, was 2392 ms.
gmail.users.threads.get484 → 6179 → 12 (2%)436 ms → 444 ms84Pre-existing
12 of 617 requests failed (1.9%) since the deploy, matching the 1.9% baseline error rate before it. Not attributable to this change.
calendar.events.instances0 → 60 → 6 (100%)not measured → 157 ms0Insufficient traffic
6 requests, under the 20 Libra needs
mail.getMessageAttachments0 → 00 → 0 (0%)not measured0No traffic
No requests recorded since this deploy.
GoogleMailManager.createDraft0 → 00 → 0 (0%)not measured0No traffic
No requests recorded since this deploy.
GoogleMailManager.sendMessage0 → 00 → 0 (0%)not measured0No traffic
No requests recorded since this deploy.
google_subscription_subscribe0 → 00 → 0 (0%)not measured0No traffic
No requests recorded since this deploy.
/api/trpc/recall.getCallSessionByGoogleEventId0 → 00 → 0 (0%)not measured0No traffic
No requests recorded since this deploy.
/api/auth/callback/google1 → 00 → 0 (0%)165 ms → not measured0No traffic
No requests recorded since this deploy.

Changed files → surfaces

  • apps/server/src/lib/driver/google.ts/a8n/notify/googlegmail.users.threads.getPOST /a8n/notify/google/a8n/notify/google-calendarPOST /a8n/notify/google-calendarcalendar.events.instances+4
  • apps/mail/modules/cedar-os/src/store/agentConnection/responseProcessors/clientExecutionResponseProcessors.tsno production surface mapped