Libra CodeHub

CedarCopilot/cedar-mail

Branch: staging

feat(coaching): coaching agent brief, document fences, and per-rep folders

merged#2581CedarCopilot

CedarCopilot wants to merge 2 commits into staging from fix/skip-agent-runs-for-warmup-traffic

Live on prod, no production signal yetTimeline and evidence
  1. Opened
    Aug 25, 2026, 5:40 PM
  2. Merged
    Aug 25, 2026, 6:21 PM
  3. Live on prod
    Aug 25, 2026, 6:21 PM
  4. Observed 38 hours
    Aug 25, 2026, 6:21 PM
  5. Pipelines steady after this deploy
    Aug 25, 2026, 6:21 PM
  6. Aug 25, 2026, 6:24 PM
  7. Unobserved

    Live on prod, no production signal yet

    Aug 27, 2026, 8:11 AM

Behaviors Libra is checking

CRM integration behavior from crm/email-events.ts keeps working in prod.Inconclusivelow confidence

Strict CloudWatch fallback found 102 recent prod failure log lines for [UpdateExternalCrmWorkflow] Driver update failed (Step updateOpportunityField failed: HTTP 400: [{\), but the same failure had 103 log lines in the comparable pre-deploy baseline. Libra is not blaming this.

prod, checked Aug 27, 2026, 7:11 AM
Email workflow behavior from components/markdown-editor.tsx, components/markdown-prose-classes.ts, components/read-only-markdown-view.tsx keeps working in prod.Inconclusivelow confidence

Strict CloudWatch fallback found 3 recent prod failure log lines for mirror.upsertEmailThread failed (write CONNECTION_CLOSED aws-1-us-east-2.pooler.supabase.com:6543), but the same failure had 8 log lines in the comparable pre-deploy baseline. Libra is not blaming this PR.

prod, checked Aug 27, 2026, 8:11 AM

Libra has verdicts on 0 of 2 tracked behaviors on prod; 2 are still being checked. Libra checks hourly for 3 days after each deploy.

Summary

Two related strands of work, both rooted in the coaching agent:

1. Skip agent runs on inbox warm-up traffic (the branch's namesake)

Email-warming vendors seed inboxes with synthetic threads. Those were reaching handleExecuteSyncThread and triggering real agent executions , burning tokens and polluting deal data with traffic that has no human on the other end. Detection keys on the warm-up label, not the sending domain, since the same domains carry genuine mail.

2. The coaching agent , the bulk of the diff

A pre-call brief that applies the rep's playbook rather than delivering generic skill coaching, plus the document plumbing it needs:

  • Coaching fences , scorecard and moment fenced blocks, taught to both the mail TipTap editor (MomentFenceNode, ScorecardFenceNode) and the server markdown parser/serializer, so a fence survives the full round-trip and Yjs sync intact.
  • Seed content + rubrics , extraction prompts written against the real win/loss rubrics; scoring out of 5, graded on rep attempts; every row carries a live cue and a mandatory recording link.
  • Per-rep file system , one folder per rep (meetings/, log, overview), with the overview split by section. Xander's, Keenan's, and Kasra's folders are published.
  • Headless dry-run driver , coaching-dryrun CLI plus the write-coaching-* scripts.

Also includes the Pirros discovery-diff analysis docs and a lint fix (an unused dims parameter on a judge-workflow schema() whose only call site already passed nothing).

Test plan

  • pnpm run autofix:local , oxlint --deny-warnings clean, deps:check clean, paraglide compiles, 2659 mail tests pass, 7316 server tests pass.
  • Branch-specific suites run scoped and green: 38 mail tests (coaching fences, Yjs survival, markdown baseline) + 56 server tests (seed content, warm-up seed detection, coaching fences, coaching paths) = 94 passing.
  • Two flaky mail timeouts surfaced under full-suite parallel load (split-inbox-templates, TableSelection) , different test each run, both pass in isolation in ~26-160ms against a 5s limit, and neither touches code this branch changes.
  • Merged fresh origin/staging with no conflicts before pushing.

Greptile Summary

The PR adds coaching scorecard and moment fences across TipTap, server markdown/Yjs serialization, coaching prompts, per-rep path conventions, and operational dry-run tooling. It also skips event-agent execution for threads detected as inbox warm-up traffic.

  • Adds editable and read-only coaching fence renderers with round-trip parsing and stable Yjs node IDs.
  • Adds organization coaching paths, templates, playbooks, and publishing/dry-run scripts.
  • Adds warm-up thread detection before event-agent workflow execution.
  • Exposes Circleback credential loading for the new operational probe.

Confidence Score: 4/5

The PR appears safe to merge after the non-blocking import-convention inconsistency is cleaned up.

The reviewed runtime paths did not establish a concrete blocking failure, but the new frontend coaching components depart from the repository's required absolute-import convention.

Files Needing Attention: apps/mail/modules/documents/coaching/MomentFenceNode.tsx; apps/mail/modules/documents/coaching/ScorecardFenceNode.tsx

Important Files Changed

FilenameOverview
apps/mail/modules/documents/coaching/MomentFenceNode.tsxAdds the moment-fence node view and markdown round trip; its local helper imports violate the frontend absolute-import convention.
apps/mail/modules/documents/coaching/ScorecardFenceNode.tsxAdds scorecard table/radar rendering and markdown round trip, with the same relative-import convention issue.
apps/server/src/services/crm/email-events.tsAdds a constrained body-token heuristic for identifying warm-up threads.
apps/server/src/mastra/routeHandlers/event
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/components/markdown-editor.tsxno production surface mapped
  • apps/mail/components/markdown-prose-classes.tsno production surface mapped
  • apps/mail/components/read-only-markdown-view.tsxno production surface mapped
  • apps/mail/modules/documents/coaching/MomentFenceNode.tsxno production surface mapped
  • apps/mail/modules/documents/coaching/ScorecardFenceNode.tsxno production surface mapped
  • apps/mail/modules/documents/coaching/fence-attrs.tsno production surface mapped
  • apps/mail/modules/documents/coaching/moment-fence.tsno production surface mapped
  • apps/mail/modules/documents/coaching/scorecard-fence.tsno production surface mapped
  • apps/mail/modules/documents/yjs/ensureNodeIdsPlugin.tsno production surface mapped
  • apps/mail/tests/modules/documents/coaching-fence-attrs.test.tsno production surface mapped
  • apps/mail/tests/modules/documents/coaching-fence-render.test.tsno production surface mapped
  • apps/mail/tests/modules/documents/coaching-yjs-survival.test.tsno production surface mapped
  • apps/mail/tests/modules/documents/markdown-baseline.test.tsxno production surface mapped
  • apps/mail/tests/modules/documents/moment-fence.test.tsno production surface mapped
  • apps/mail/tests/modules/documents/scorecard-fence.test.tsno production surface mapped
  • apps/server/docs/coaching-agent.mdno production surface mapped
  • apps/server/docs/coaching-dryrun-keenan.mdno production surface mapped
  • apps/server/scripts/circleback-mcp-probe.tsno production surface mapped
  • apps/server/src/cli/__tests__/no-heavy-imports.test.tsno production surface mapped
  • apps/server/src/cli/coaching-dryrun.tsno production surface mapped
  • apps/server/src/mastra/routeHandlers/event-execution/handleExecuteSyncThread.tsno production surface mapped
  • apps/server/src/scripts/delete-coaching-stubs.tsno production surface mapped
  • apps/server/src/scripts/verify-yjs-nodes.tsno production surface mapped
  • apps/server/src/scripts/write-coaching-dryrun.tsno production surface mapped
  • apps/server/src/scripts/write-coaching-suite.tsno production surface mapped
  • apps/server/src/services/coaching/__tests__/seed-content.test.tsno production surface mapped
  • apps/server/src/services/coaching/seed-content.tsno production surface mapped
  • apps/server/src/services/crm/__tests__/warmup-seed-detection.test.tsno production surface mapped
  • apps/server/src/services/crm/email-events.tsno production surface mapped
  • apps/server/src/services/document-saving/__tests__/coaching-fences.test.tsno production surface mapped
  • apps/server/src/services/document-saving/markdown-parser.tsno production surface mapped
  • apps/server/src/services/document-saving/serialize.tsno production surface mapped
  • apps/server/src/services/documents/__tests__/coaching-paths.test.tsno production surface mapped
  • apps/server/src/services/documents/convention-paths.tsno production surface mapped
  • apps/server/src/services/documents/path-shortcuts.tsno production surface mapped
  • apps/server/src/services/documents/rep-slug.tsno production surface mapped
  • apps/server/src/services/integrations/meetings/circleback.tsno production surface mapped
  • docs/pirros/discovery-diff/DIMENSION-RUBRICS.mdno production surface mapped
  • docs/pirros/discovery-diff/PROMPTS-RECOVERED.mdno production surface mapped
  • docs/pirros/discovery-diff/QUALITATIVE-DIFFS.mdno production surface mapped
  • docs/pirros/discovery-diff/README.mdno production surface mapped
  • docs/pirros/discovery-diff/RESULTS.mdno production surface mapped
  • docs/pirros/discovery-diff/RUBRIC_emergent.mdno production surface mapped
  • docs/pirros/discovery-diff/RUBRIC_framework.mdno production surface mapped
  • docs/pirros/discovery-diff/SYNTHESIS.mdno production surface mapped
  • docs/pirros/discovery-diff/masterlist_judge.workflow.jsno production surface mapped