Libra CodeHub

CedarCopilot/cedar-mail

Branch: staging

feat(tasks): cancel deal-advancing work when a deal closes, protect the rest

closed#2626CedarCopilot

CedarCopilot wants to merge 1 commit into staging from fix/cancel-deal-advancing-tasks-on-close

Not deployedTimeline and evidence
  1. Opened
    Aug 30, 2026, 1:31 PM
  2. Aug 30, 2026, 1:39 PM
  3. Merged, live on staging, live on prod, observed
    Pending
  4. Not deployed

    Not deployed

    Pending

Libra has no production signal for this change yet because it has not deployed. Libra checks hourly for 3 days after each deploy.

What's wrong

A closed-won or closed-lost deal keeps carrying the tasks that existed to move it forward , the chase for a reply, the recap owed from a meeting, the response to a thread.

572 open tasks sit on closed deals today, across 52 accounts:

overduefuture-scheduled
follow-up16334
manual11210
response350
post-meeting340
reactivation25138
field-approval80
calendar30
total388184

The 138 future-dated reactivations are deliberate work. The 388 overdue ones are residue.

Nothing cancels them: there is no stage-change handler anywhere in the codebase, and the one instruction that mentions the case tells the agenda agent the opposite , a terminal stage "is not a reason to cancel". That rule is right for deliberate reactivations and wrong for everything else, and it is stated without the distinction.

Where the rule lives, and why

assembleNextStepsPrompt, not the seeded next-steps body:

  • a per-user document can be edited away , 20 of 61 active accounts have edited theirs
  • next-steps runs on every event, so it fires when the deal actually closes rather than up to a day later, which is the agenda's cadence

What it says

Cancelled, never done. The work stopped being necessary; it did not happen. Recording it as done says the rep did something they did not do, and inflates the completion metric the task system is judged on.

Never cancelled, whatever the due date: reactivation, re-engagement, win-back, renewal, upsell, expansion, onboarding and customer-success work. Those are the path forward on a closed deal, not residue.

Defers to the user. The block says outright that a user's own next-steps instructions override it , a default, not a policy.

Verified

  • tsc -b on @zero/server , clean
  • vitest run over mastra/tools/task and mastra/routeHandlers , 246 passed, 2 skipped
  • 4 new tests in next-steps-prompt.test.ts covering the cancel instruction, the done prohibition, every protected category by name, and the user-override clause

Not in scope

The 388 already-stranded tasks. This stops the accrual; a backfill is separate, and I'd rather run it after watching this behave.

🤖 Generated with Claude Code

Greptile Summary

The PR adds an always-present next-steps prompt rule that cancels obsolete deal-advancing tasks when a deal closes while preserving reactivation and post-close work.

  • Registers the cleanup rule in the assembled prompt’s block map.
  • Adds prompt guidance for cancellation, protected categories, and user overrides.
  • Adds tests covering the new instruction text and exemptions.

Confidence Score: 4/5

The conflicting seeded and terminal-stage instructions should be reconciled before merging so closed-lost deals reliably shed obsolete advancing tasks.

The assembled prompt can simultaneously tell the agent that closed-lost is not grounds for closing a task and that differing next-steps instructions override the new cleanup rule, undermining the feature for accounts using the seeded instructions.

Files Needing Attention: apps/server/src/mastra/tools/task/next-steps-prompt.ts

Important Files Changed

FilenameOverview
apps/server/src/mastra/tools/task/next-steps-prompt.tsAdds the terminal-stage cleanup rule, but its override clause leaves a conflicting seeded instruction able to suppress cleanup.
apps/server/src/mastra/tools/task/tests/next-steps-prompt.test.tsVerifies the new text is present, but does not cover the assembled conflict with the existing seeded closure guidance.

Flowchart

rendering diagram…
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/tools/task/__tests__/next-steps-prompt.test.tsno production surface mapped
  • apps/server/src/mastra/tools/task/next-steps-prompt.tsno production surface mapped