Libra CodeHub

CedarCopilot/cedar-mail

Branch: staging

chore(f8): vendor-bucket task cleanup script + workstream design docs

merged#2696CedarCopilot

CedarCopilot wants to merge 6 commits into staging from chore/f8-cleanup-script-and-design-docs

Live on prod, no production signal yetTimeline and evidence
  1. Opened
    Sep 6, 2026, 2:15 PM
  2. Sep 6, 2026, 4:57 PM
  3. Merged
    Sep 6, 2026, 4:58 PM
  4. Live on prod
    Sep 6, 2026, 4:58 PM
  5. Observed 2 days
    Sep 6, 2026, 4:58 PM
  6. Pipelines steady after this deploy
    Sep 6, 2026, 4:58 PM
  7. Unobserved

    Live on prod, no production signal yet

    Sep 9, 2026, 4:20 PM

Behaviors Libra is checking

When explicitly run with APPLY=1, the cleanup operation changes matching open conversation tasks from todo to agent_deleted rather than done.Degradedlow confidence

Strict CloudWatch fallback found 5 prod failure log lines for [UpdateExternalCrmWorkflow] Driver update failed (Error: Organization tool execution queue is full (500 tasks waiting), try again later) in the last 24h while checking /server/scripts/cancel-vendor-bucket-tasks.ts.

prod, checked Sep 9, 2026, 4:18 PM
The vendor-bucket cleanup defaults to a no-write dry run and requires APPLY=1 before any task status is mutated.Degradedlow confidence

Strict CloudWatch fallback found 5 prod failure log lines for [UpdateExternalCrmWorkflow] Driver update failed (Error: Organization tool execution queue is full (500 tasks waiting), try again later) in the last 24h while checking /run-cancel-vendor-bucket-tasks.mjs, dry-run.

prod, checked Sep 9, 2026, 4:20 PM
Repeated cleanup runs re-evaluate live rows and update only tasks still in todo status, so an already-cleaned vendor conversation becomes a no-op.Degradedlow confidence

Strict CloudWatch fallback found 5 prod failure log lines for [UpdateExternalCrmWorkflow] Driver update failed (Error: Organization tool execution queue is full (500 tasks waiting), try again later) in the last 24h while checking /server/scripts/cancel-vendor-bucket-tasks.ts.

prod, checked Sep 9, 2026, 4:07 PM
The cleanup operation selects only conversations with at least five inbound emails, at least 70% from recognized vendor/notifier domains, no inbound real-counterparty emails, and at least one open todo task.Degradedlow confidence

Strict CloudWatch fallback found 5 prod failure log lines for [UpdateExternalCrmWorkflow] Driver update failed (Error: Organization tool execution queue is full (500 tasks waiting), try again later) in the last 24h while checking /run-cancel-vendor-bucket-tasks.mjs.

prod, checked Sep 9, 2026, 4:07 PM

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

What

The Step 0 cleanup script for the F8 vendor-routing workstream, plus the design docs the open PRs reference.

Already executed against production: 32 tasks cancelled across 10 conversations and 8 users. Read-back clean, and a re-run is a no-op.

userconversationvendorcancelled
Broadband Hospitalityfathom.video8
PandaDocemail.pandadoc.net6
Cantodocusign.net6
KBMCofathom.video4
SingleStoremg.ironcladapp.com2
Lumacalendar.luma-mail.com2
HubSpothubspot.com1
PandaDocemail.pandadoc.net1
Bitvis - New Annual 3/2026chilipiper.com1
Procurement Sciencesmail.granola.ai1

Why these tasks can never be cancelled by the system

listTasksTool.ts:272-273 scopes to eq(userTasks.conversationId, conversationId). The agent on the real deal cannot see the task; the agent on the vendor conversation cannot see the deal's stage. The one CRM-state-driven cancel path (external-crm-events.ts:489-503) misses on both predicates: it is scoped to the deal's own conversation and to taskType='crm-opportunity', and these are manual.

The safety test

Selection requires >= 5 inbound, >= 70% from a known vendor sender, and zero inbound from a real counterparty (an external sender that is neither the vendor nor one of the user's own domains).

That last predicate is what makes this safe to run. It excluded a "Melissa & Doug" conversation holding 4 PandaDoc notices and 1 email from the actual customer, which is a genuine deal whose tasks may be correctly placed.

It is deliberately conservative and under-selects. A few conversations were skipped because a second notifier not in the vendor list (Stripe, Superhuman, Slack) counted as a counterparty. Missing 3 tasks is a better failure than cancelling a legitimate one.

Not a behaviour change

This clears rows that already exist. The root cause is findOrCreateVendorConversation adopting a deal conversation, traced in docs/design/f8-vendor-conversation-routing.md §2.3, and fixed by Steps 2 to 4 of that plan.

Docs

f8-vendor-conversation-routing.md is referenced by #2694, where the link currently dangles. task-completion-write-path.md and refused-save-client-state.md are the two handoffs for Jesse. f8-agent-log.md records the workstream's scope corrections, including two fixes that were proven to be no-ops.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NVHnt2pEEjhVwSyhkcaxoC

Greptile Summary

This PR adds a one-off F8 cleanup utility and extensive design handoffs for vendor routing, stale tasks, refused document saves, and deferred task completion.

  • Selects vendor-dominated, counterparty-free conversations and marks their open tasks agent_deleted.
  • Adds an esbuild runner for executing the cleanup in dry-run or APPLY mode.
  • Documents the vendor-routing workstream and several related production failure investigations.
  • The cleanup’s domain predicates can misclassify genuine counterparties, and the documents expose identifiable production customer data.

Confidence Score: 2/5

This PR is not safe to merge until the cleanup’s false-positive domain matching, the production-data disclosure, and the explicit repository-rule violation are resolved.

The cleanup can cancel every open task on a genuine conversation whose counterparty domain merely contains a vendor token, and the new public documentation exposes identifiable customer operational data. The raw SQL double assertion also violates an explicit repository requirement.

Files Needing Attention: apps/server/scripts/cancel-vendor-bucket-tasks.ts; docs/design/refused-save-client-state.md; docs/design/stale-task-failure-modes.md; docs/design/task-completion-write-path.md; docs/

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/scripts/cancel-vendor-bucket-tasks.tsno production surface mapped
  • apps/server/scripts/run-cancel-vendor-bucket-tasks.mjsno production surface mapped
  • apps/server/tests/scripts/cancel-vendor-bucket-tasks-selection.test.tsno production surface mapped
  • docs/design/f8-agent-log.mdno production surface mapped
  • docs/design/f8-vendor-conversation-routing.mdno production surface mapped
  • docs/design/refused-save-client-state.mdno production surface mapped
  • docs/design/stale-task-failure-modes.mdno production surface mapped
  • docs/design/task-completion-write-path.mdno production surface mapped