Skip to content

[codex] fix(recovery): make review recovery dispatch durable - #1207

Merged
kkroo merged 1 commit into
masterfrom
codex/fix-pr-1048-durable-recovery
Aug 11, 2026
Merged

[codex] fix(recovery): make review recovery dispatch durable#1207
kkroo merged 1 commit into
masterfrom
codex/fix-pr-1048-durable-recovery

Conversation

@kkroo

@kkroo kkroo commented Aug 9, 2026

Copy link
Copy Markdown

Thinking Path

  • Paperclip manages AI agents and their external execution lifecycle.
  • A review-stage recovery escalation persists the source issue as blocked with an active recovery action before it dispatches an owner wake.
  • That wake must run after the transaction commits, because it can synchronously claim the issue.
  • A transient enqueue failure or process exit in that post-commit gap previously left the blocked issue with no retry path.
  • The same transaction defers activity publication to avoid phantom events, but the returned publisher was discarded on success.
  • This successor re-applies the intended fix(recovery): persist job-missing invocation evidence (BLO-18106) #1048 recovery work from current master and makes both reviewed gaps durable.
  • The benefit is that review recovery is eventually redelivered and committed escalation activity reaches live and plugin consumers.

Linked Issues or Issue Description

What Changed

  • Re-applied the intended job-missing and review-stage recovery behavior from fix(recovery): persist job-missing invocation evidence (BLO-18106) #1048 onto current master under an independent author.
  • Added an active-recovery-action backstop that uses a persisted cooldown claim and unique delivery token to redeliver an undelivered owner wake without widening the ordinary blocked-issue sweep.
  • Published the deferred review-stage escalation activity after its transaction commits.
  • Added focused regressions for a thrown post-commit wake dispatch and for the committed live activity event.

Verification

  • pnpm --filter @paperclipai/server exec vitest run --no-file-parallelism src/tests/issue-recovery-actions.test.ts -t review-stage recovery wake|publishes the committed review-stage escalation activity
    • 2 passed.
  • pnpm --filter @paperclipai/server exec vitest run --no-file-parallelism src/tests/activity-log-responsible-user.test.ts src/tests/heartbeat-process-recovery.test.ts
    • 188 passed.
  • pnpm --filter @paperclipai/server typecheck
    • passed.

Risks

  • Low to moderate: the backstop may re-attempt a delivery after its 30-minute cooldown only while the active recovery action remains within its existing attempt and horizon bounds. It does not re-route, re-escalate, or change issue status.
  • No migration, UI, or documentation change.

Model Used

  • OpenAI GPT-5 Codex, with code execution, GitHub tooling, and focused test execution.

Checklist

  • I have included a thinking path that traces from project context to this change
  • I have specified the model used (with version and capability details)
  • I have checked ROADMAP.md and confirmed this PR does not duplicate planned core work
  • I have searched GitHub for duplicate or related PRs and linked them above
  • I have either (a) linked existing issues with Fixes: / Closes: / Refs: OR (b) described the issue in-PR following the relevant issue template
  • I have run tests locally and they pass
  • I have added or updated tests where applicable
  • If this change affects the UI, I have included before/after screenshots (N/A)
  • I have updated relevant documentation to reflect my changes (N/A)
  • I have considered and documented any risks above
  • All Paperclip CI gates are green
  • Greptile is 5/5 with no open P2s, recommendations, or follow-ups
  • I will address all Greptile and reviewer comments before requesting merge

@cursor

cursor Bot commented Aug 9, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@kkroo

kkroo commented Aug 9, 2026

Copy link
Copy Markdown
Author

@ally please review exact head ba64d28.

This independently authored successor supersedes #1048. It re-applies the intended recovery behavior from current master and addresses the two current-head Important findings: durable redelivery after a post-commit review-stage wake failure, and post-commit publication of the deferred escalation activity. Focused regressions, the 188-test recovery suite, and server typecheck pass.

allyblockcast[bot]
allyblockcast Bot previously approved these changes Aug 9, 2026

@allyblockcast allyblockcast Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ally — Consolidated PR Review

Lenses: pr-review-toolkit (code, tests, comments, errors, types) + gstack/review + native-codex.
Reviewed head: ba64d28

Critical Issues (0)

Important Issues (0)

Suggestions (0)

Strengths

  • The review-stage escalation now commits its recovery action before dispatching the wake, preserving a repairable state across post-commit delivery failures.
  • Stage and participant checks prevent an obsolete review run from overwriting a newer review stage.
  • The deferred activity publication is correctly emitted only after the transaction commits.

Recommended Action

  1. Ready to merge once required checks complete.

allyblockcast
allyblockcast previously approved these changes Aug 9, 2026

@allyblockcast allyblockcast left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ally — Consolidated PR Review

Lenses: pr-review-toolkit (code, tests, comments, errors, types) + gstack/review + native-codex.
Reviewed head: ba64d28

Critical Issues (0)

Important Issues (0)

Suggestions (0)

Strengths

  • The review-stage escalation now commits its recovery action before dispatching the wake, preserving a repairable state across post-commit delivery failures.
  • Stage and participant checks prevent an obsolete review run from overwriting a newer review stage.
  • The deferred activity publication is correctly emitted only after the transaction commits.

Recommended Action

  1. Ready to merge once required checks complete.

@kkroo
kkroo force-pushed the codex/fix-pr-1048-durable-recovery branch from ba64d28 to 3150171 Compare August 9, 2026 12:22
@kkroo
kkroo requested a review from allyblockcast August 9, 2026 12:23
@kkroo

kkroo commented Aug 9, 2026

Copy link
Copy Markdown
Author

@ally please submit a fresh exact-head App review for 315017159ff5edc55ee57ca1bebd50508cc37f56 that satisfies review/ally-complete.

@allyblockcast please separately inspect this same exact head and submit a formal User-seat approve or request-changes review for the singleton-team rule.

This independently authored successor supersedes #1048. It was rebased onto current origin/master; the two focused durable-recovery regressions passed and server typecheck passed.

@allyblockcast allyblockcast Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ally — Consolidated PR Review

Lenses: pr-review-toolkit (code, tests, comments, errors, types) + gstack/review + native-codex.
Reviewed head: 3150171

Critical Issues (0)

Important Issues (0)

Suggestions (0)

Strengths

  • Review-stage escalation persists the recovery action within the locked transaction, then dispatches after commit so a failed delivery remains repairable.
  • The wake backstop uses a persisted cooldown claim and delivery key to avoid duplicate recovery dispatches while retaining eventual redelivery.
  • Deferred activity publication prevents rollback phantom events and is explicitly published after a successful escalation commit.

Recommended Action

  1. Ready to merge once required checks complete.

@allyblockcast allyblockcast left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ally — Consolidated PR Review

Lenses: pr-review-toolkit (code, tests, comments, errors, types) + gstack/review + native-codex.
Reviewed head: 3150171

Critical Issues (0)

Important Issues (0)

Suggestions (0)

Strengths

  • Review-stage escalation persists the recovery action within the locked transaction, then dispatches after commit so a failed delivery remains repairable.
  • The wake backstop uses a persisted cooldown claim and delivery key to avoid duplicate recovery dispatches while retaining eventual redelivery.
  • Deferred activity publication prevents rollback phantom events and is explicitly published after a successful escalation commit.

Recommended Action

  1. Ready to merge once required checks complete.

@kkroo
kkroo dismissed stale reviews from allyblockcast[bot] and allyblockcast August 9, 2026 13:09

Stale review artifact: body attests ba64d28, not current head 3150171. The current exact-head approval pair remains.

@kkroo
kkroo force-pushed the codex/fix-pr-1048-durable-recovery branch from 3150171 to 7907f7c Compare August 10, 2026 23:05
@kkroo
kkroo enabled auto-merge August 11, 2026 02:45
@kkroo
kkroo disabled auto-merge August 11, 2026 02:45
@kkroo
kkroo force-pushed the codex/fix-pr-1048-durable-recovery branch from 7907f7c to a28af68 Compare August 11, 2026 02:55
@kkroo
kkroo requested a review from allyblockcast August 11, 2026 02:55
@kkroo
kkroo enabled auto-merge August 11, 2026 02:56

@allyblockcast allyblockcast Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ally — Consolidated PR Review

Lenses: pr-review-toolkit (code, tests, comments, errors, types) + gstack/review + native-codex.
Reviewed head: a28af68

Critical Issues (0)

Important Issues (1)

  • [native-codex] server/src/services/heartbeat.ts:24504hasQueuedReplacementIssueWake only filters by company, queued status, and payload.issueId; it does not require the queued wake to target the failed review participant or its active stage. A queued comment/monitor wake for another agent (or an earlier stage) therefore suppresses this failure's escalation, leaving the current review participant pending without a recovery action or a runnable replacement.
    • Restrict the guard to a wake/run for the same participant and stage, or prove that the queued wake is an executable replacement for the current review stage.

Suggestions (0)

Strengths

  • The review-stage state mutation and recovery action now commit before the independent wake dispatch.
  • The new backstop gives failed post-commit delivery a durable retry path.

Recommended Action

  1. Address the Important recovery-suppression bug before merge.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
@kkroo
kkroo force-pushed the codex/fix-pr-1048-durable-recovery branch from a28af68 to 0d95183 Compare August 11, 2026 03:33
@kkroo

kkroo commented Aug 11, 2026

Copy link
Copy Markdown
Author

@ally please submit a fresh exact-head App review for 0d9518399974d6f61fe58437f04e2be110c0ea32 that satisfies review/ally-complete.

@allyblockcast please separately inspect this exact head and submit a formal User-seat approve or request-changes review.

The head is rebased onto current origin/master and addresses the prior Important finding: queued replacement wakes must now match the issue, review participant, recovery reason, and active stage. Regressions cover unrelated agents, prior stages, wrong reasons, and exact-match duplicate suppression. Server typecheck passes; the focused test file imports successfully, while its embedded-Postgres cases are skipped on macOS and will execute in Linux CI.

@allyblockcast allyblockcast Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ally — Consolidated PR Review

Lenses: pr-review-toolkit (code, tests, comments, errors, types) + gstack/review + native-codex.
Reviewed head: 0d95183

Prior Findings Dispositioned (1)

  • prior:a28af68 important 1 — fixed — server/src/services/heartbeat.ts:24324 — queued replacement wakes now require the active participant, execution_review_participant_recovery reason, issue ID, and active stage ID, so unrelated queued wakes cannot suppress this stage's recovery.

Critical Issues (0)

Important Issues (0)

Suggestions (0)

Strengths

  • The review-stage recovery action and state transition commit before the independent wake delivery, leaving failed delivery repairable by the new action-driven backstop.
  • The backstop uses an atomic cooldown claim and delivery-specific idempotency key, preventing concurrent sweeps from duplicating redelivery.
  • Tests cover stage supersession, mismatched queued wakes, post-commit dispatch failure, and the committed activity event.

Recommended Action

  1. Ready to merge once required checks complete.

@allyblockcast allyblockcast left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ally — Consolidated PR Review

Lenses: pr-review-toolkit (code, tests, comments, errors, types) + gstack/review + native-codex.
Reviewed head: 0d95183

Prior Findings Dispositioned (1)

  • prior:a28af68 important 1 — fixed — server/src/services/heartbeat.ts:24324 — queued replacement wakes now require the active participant, execution_review_participant_recovery reason, issue ID, and active stage ID, so unrelated queued wakes cannot suppress this stage's recovery.

Critical Issues (0)

Important Issues (0)

Suggestions (0)

Strengths

  • The review-stage recovery action and state transition commit before the independent wake delivery, leaving failed delivery repairable by the new action-driven backstop.
  • The backstop uses an atomic cooldown claim and delivery-specific idempotency key, preventing concurrent sweeps from duplicating redelivery.
  • Tests cover stage supersession, mismatched queued wakes, post-commit dispatch failure, and the committed activity event.

Recommended Action

  1. Ready to merge once required checks complete.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants