CedarCopilot wants to merge 0 commits into staging from fix/initial-sync-noop-tasks
Live on prod, no production signal yet
Strict CloudWatch fallback saw 734 success-shaped log lines matching pipeline, analytics, quota, aop, but no tied operation was present, so Libra is not calling this working.
Strict CloudWatch fallback saw 22,065 success-shaped log lines matching email, emails, gmail, mail, inbox, but no tied operation was present, so Libra is not calling this working.
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.
The initial-sync Phase 2 finalize selects the AOP for each conversation, then runs field-updates + next-steps + task creation , without ever checking isNoOp. So a bulk backfill schedules throwaway follow-up tasks on no-op conversations (Spam, Vendor notification, Recruiting, Inbound cold pitch, Non-deal professional relationships) , e.g. investor and recruiting threads getting "follow up" tasks.
Live per-event execution already gates on this (services/aop/no-op-check.ts → "Execution skipped , AOP is marked as no-op"). The finalize path just never applied the same gate.
Short-circuit finalizeConversationForInitialSync right after AOP selection when selectedAop.isNoOp, mirroring the live gate. Real Deals AOPs are unaffected.
services/mail/initial-sync/handlers.ts , early-return skipReason: 'aop_no_op' when the selected AOP is no-opservices/mail/initial-sync/types.ts , add 'aop_no_op' to the skipReason unionPrevents every future customer backfill from spawning tasks on no-op conversations. Steady-state (live events) already behaved correctly.
Typecheck: clean (0 errors in the server package for the touched files).
🤖 Generated with Claude Code
The PR prevents initial-sync finalize from running field updates, next steps, and task creation for AOPs marked as no-op.
aop_no_op reason.The excluded-domain regression should be fixed before merging; the missing completion record also causes avoidable repeat processing on later sync runs.
The unconditional no-op branch suppresses required initial-sync work for contract and e-signature conversations that the live gate explicitly exempts, and it bypasses the records used to recognize finalized events.
Files Needing Attention: apps/server/src/services/mail/initial-sync/handlers.ts
| Filename | Overview |
|---|---|
| apps/server/src/services/mail/initial-sync/handlers.ts | Adds the intended no-op gate, but omits the live gate's excluded-domain exception and returns before idempotency records are stamped. |
| apps/server/src/services/mail/initial-sync/types.ts | Safely extends the optional skip-reason union for the new finalize result. |
### Issue 1
apps/server/src/services/mail/initial-sync/handlers.ts:571
**Excluded-domain bypass is lost**
If initial sync includes a no-op conversation with a contract or e-signature participant such as DocuSign, PandaDoc, or Adobe Sign, this unconditional check skips the conversation even though the live gate explicitly runs it, causing its field updates, next steps, and tasks to be omitted.
### Issue 2
apps/server/src/services/mail/initial-sync/handlers.ts:572-580
**No-op completion remains unstamped**
This return bypasses the execution-record stamping used by the finalize idempotency check, so a later initial-sync run selects the no-op conversation again and repeats AOP resolution and its database or model costs.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
Reviews (1): Last reviewed commit: ["fix(initial-sync): honor no-op AOP flag ..."](https://github.com/cedarcopilot/cedar-mail/commit/e8e9f7593442a10f5bc3fe448
Libra has not measured any production surfaces for this change yet.