Libra CodeHub

CedarCopilot/cedar-mail

Branch: staging

fix(initial-sync): honor no-op AOP flag in finalize

merged#2481CedarCopilot

CedarCopilot wants to merge 0 commits into staging from fix/initial-sync-noop-tasks

Live on prod, no production signal yetTimeline and evidence
  1. Opened
    Aug 14, 2026, 7:36 AM
  2. Merged
    Aug 14, 2026, 9:23 AM
  3. Live on prod
    Aug 14, 2026, 9:23 AM
  4. Observed 2 days
    Aug 14, 2026, 9:23 AM
  5. Pipelines steady after this deploy
    Aug 14, 2026, 9:23 AM
  6. Unobserved

    Live on prod, no production signal yet

    Aug 17, 2026, 1:26 AM

Behaviors Libra is checking

AOP context behavior from aop/no-op-check.ts keeps working in prod.Inconclusivelow confidence

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.

prod, checked Aug 17, 2026, 1:26 AM
Email workflow behavior from initial-sync/handlers.ts, initial-sync/types.ts keeps working in prod.Inconclusivelow confidence

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.

prod, checked Aug 17, 2026, 1:26 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.

Problem

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.

Fix

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-op
  • services/mail/initial-sync/types.ts , add 'aop_no_op' to the skipReason union

Impact

Prevents 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

Greptile Summary

The PR prevents initial-sync finalize from running field updates, next steps, and task creation for AOPs marked as no-op.

  • Adds an early no-op result after AOP selection.
  • Extends the finalize result union with the aop_no_op reason.
  • The gate currently diverges from the live path's excluded-domain handling and bypasses its completion-record behavior.

Confidence Score: 4/5

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

Important Files Changed

FilenameOverview
apps/server/src/services/mail/initial-sync/handlers.tsAdds 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.tsSafely extends the optional skip-reason union for the new finalize result.

Flowchart

rendering diagram…
Prompt To Fix All With AI
### 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

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/services/aop/no-op-check.tsno production surface mapped
  • apps/server/src/services/mail/initial-sync/handlers.tsno production surface mapped
  • apps/server/src/services/mail/initial-sync/types.tsno production surface mapped