CedarCopilot wants to merge 2 commits into staging from fix/live-thread-revalidation-gate
Live on prod, watching, less than a day left
Verification reached its 130s outer budget before the verifier returned. Libra is keeping this intent verifying until the next check.
Only 6 prod OTEL spans matching draft-email reached Libra since the deploy, below the 20-span floor for calling a change verified. Nothing is failing; there is not yet enough traffic to confirm it.
Libra has verdicts on 0 of 14 tracked behaviors on prod; 14 are still being checked. Libra checks hourly for 3 days after each deploy.
Second PR from the same latency/staleness investigation as #2775 (dispatch ordering). This one covers the two remaining pieces: making the playbook documents describe the order that's now actually true, and closing the actual stale-context/duplicate-output gap.
Moves strategist/next-steps (with their prose, correctly kept attached to whichever ref it precedes) to the tail of every account's <trigger type="any"> block, matching what the orchestrator dispatches at runtime after #2775. Already run for real against the full active cohort: 56/57 succeeded, 1 correctly skipped (an eligibility edge case, not guessed at) and fixed by hand in scripts/manual-fix-jacob-reorder.ts. Every account's before/after state was independently read back from Postgres via a separate DOM-based verifier (not the migration's own logic) , see commit message for full detail.
Traced both incidents to the same underlying gap: a subagent decides to draft or alert from a conversation snapshot frozen at the start of its run, and nothing re-checks it before acting , even though the run can sit queued for minutes. Directly measured: a rep's own reply was sent 2m47s after the trigger and wasn't visible in Cedar's own synced conversation state for another 16m35s , so a re-check against Cedar's own database would have caught nothing. Only a live mailbox fetch, bypassing Cedar's sync pipeline entirely, can catch this in time.
checkThreadForNewerActivity (staleness-check.ts) fetches the live thread and flags a newer non-draft message (the rep already replied) or an existing draft (already asked Cedar via chat) , wired into both places a subagent actually produces output: the drafter dispatch and the generic custom-subagent path (covers inbound-email-notifier and similar). Degrades to null on any failure rather than ever blocking the pipeline. For brand-new threads, added a prompted search-live-emails check to the drafter's own instructions instead, since the deterministic check only covers the thread that triggered the run.
staleness-check.test.ts) , newer-reply, existing-draft, nothing-changed, connection/API failure, unparseable-timestamp casesrunSubagentTool/drafter-executor-prompt suites (54 tests) pass unchangedpnpm --filter @zero/server run types cleanoxlint --deny-warnings clean on every changed file--apply run; live DB read back independently afterward for multiple accounts across every distinct shape (simple, custom-subagent-spliced, the most complex multi-sequencer account, and the manually-fixed edge case)getThread)š¤ Generated with Claude Code
Libra has not measured any production surfaces for this change yet.