Skip to content

[codex] fix(issues): restore checkout status across ownership releases (BLO-20649) - #1258

Merged
kkroo merged 3 commits into
masterfrom
codex/supersede-pr-1037-checkout-status
Aug 11, 2026
Merged

[codex] fix(issues): restore checkout status across ownership releases (BLO-20649)#1258
kkroo merged 3 commits into
masterfrom
codex/supersede-pr-1037-checkout-status

Conversation

@kkroo

@kkroo kkroo commented Aug 10, 2026

Copy link
Copy Markdown

Thinking Path

  • Paperclip manages agent work through issue status, checkout ownership, and heartbeat runs.
  • A checkout correctly promotes an issue to in_progress while a run owns it.
  • Prior lock-release paths cleared run ownership but left that temporary promotion behind.
  • That made in_progress a historical high-water mark rather than evidence of live work, corrupting WIP and recovery decisions.
  • App PR fix(issues): restore pre-checkout status when a run releases without advancing (BLO-20649) #1037 introduced the status marker; stacked App PR fix(issues): restore checkout status on every ownership-ending path (BLO-20649) #1082 identified missing ownership-ending coverage and two lifecycle defects.
  • This independently authored successor preserves the needed behavior, installs replacement ownership before restoration, and carries the marker through legacy adoption paths.
  • The result restores the exact pre-checkout tier only when no live or replacement execution path remains.

Linked Issues or Issue Description

What Changed

  • Add a nullable checkout_restore_status migration and schema field.
  • Restore a checkout-promoted status only after all live execution claims are gone.
  • Preserve in_progress while finalization queues a continuation, so the retry passes its dispatch staleness gate.
  • Record the marker in normal checkout, stale-lock, markerless adoption, and ownership-adoption paths.
  • Add status round-trip, cross-company, finalizer, adoption, and queued-continuation regression coverage.

Verification

  • Passed: pnpm --filter @paperclipai/db check:migrations.
  • Passed: pnpm --filter @paperclipai/db typecheck.
  • Passed: pnpm --filter @paperclipai/plugin-sdk ensure-build-deps.
  • Passed: pnpm --filter @paperclipai/server typecheck.
  • Targeted issue-status/adoption Vitest execution recorded 11 passing assertions and 0 failing assertions. Its JSON reporter flagged two suite-level teardown outcomes without an emitted error while the shared embedded-Postgres runner drained I/O; full CI is pending.

Risks

  • Low migration risk: one nullable text column with no default or rewrite.
  • Intended behavior change: legacy markerless in_progress rows are treated as stranded work and return to todo after their next ownership release.
  • The live-run guard is safety critical; it checks both checkout and execution references before restoring.

Model Used

  • OpenAI Codex based on GPT-5, with tool-assisted repository inspection, code execution, and focused test runs. The exact runtime version and context-window size are not exposed in this session.

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 linked the related Paperclip issue and predecessor PRs
  • 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 — not applicable
  • I have updated relevant documentation to reflect my changes
  • 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

@allyblockcast

allyblockcast Bot commented Aug 10, 2026

Copy link
Copy Markdown

🔗 Paperclip issue: BLO-20649

1 similar comment
@allyblockcast

allyblockcast Bot commented Aug 10, 2026

Copy link
Copy Markdown

🔗 Paperclip issue: BLO-20649

@allyblockcast

allyblockcast Bot commented Aug 10, 2026

Copy link
Copy Markdown

Hey @kkroo! Before this PR can be reviewed, a few things need attention:

Missing or incomplete:

  • Missing section: ## Thinking Path
  • Missing section: ## What Changed
  • Missing section: ## Verification
  • Missing section: ## Risks
  • Missing section: ## Model Used
  • Add the dedup-search checkbox to your PR description and check it once you have searched the GitHub PR list for similar PRs. See the PR template at .github/PULL_REQUEST_TEMPLATE.md and CONTRIBUTING.md → "Before You Start: Search First".

Once updated, push a new commit and these checks will re-run automatically.

— commitperclip

@kkroo
kkroo force-pushed the codex/supersede-pr-1037-checkout-status branch from 8565f60 to 98bc7c9 Compare August 11, 2026 11:22
@kkroo
kkroo marked this pull request as ready for review August 11, 2026 11:22
@cursor

cursor Bot commented Aug 11, 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.

@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: 98bc7c9

Critical Issues (0)

Important Issues (2)

  • [gstack/review, native-codex] server/src/services/heartbeat.ts:16996 — Successful runs that carry only taskId are restored before their handoff is queued. The restore deferral uses readRuntimeStatusIssueIdCandidate, which does not see taskId, while handleSuccessfulRunHandoff explicitly accepts it at line 11945. The resulting handoff wake targets a restored todo issue and can fail its in_progress dispatch-staleness check. The same sequence exists at server/src/services/heartbeat.ts:23769.
    Recommendation: derive the deferred primary issue from the same issueId ?? taskId source used by the handoff path, and add a taskId-only regression test.
  • [pr-review-toolkit, native-codex] server/src/services/heartbeat.ts:15726 — The newly added restore call demotes the issue but leaves checkoutRunId pointing to the terminal run. This path clears only execution-lock fields; restoreCheckoutPromotedStatus permits restoration once the remaining checkout owner is terminal, but checkout requires the incoming run to match or replace a null checkoutRunId (server/src/services/issues.ts:9833). The restored todo/backlog issue therefore remains unclaimable. The stale-queued path repeats this at server/src/services/heartbeat.ts:15964, as does watchdog finalization at server/src/services/recovery/service.ts:2925.
    Recommendation: clear the matching checkoutRunId atomically before restoring, or route these paths through the shared full lock-release helper; cover each cancellation/fold path.

Suggestions (0)

Strengths

  • The marker-based design preserves an explicit status disposition and correctly protects rows still owned by a live retry.
  • The new tests cover normal round trips, stale-lock adoption, sibling cleanup, and continuation dispatch.

Recommended Action

  1. Fix the Important issues before merge.

@kkroo
kkroo force-pushed the codex/supersede-pr-1037-checkout-status branch from 98bc7c9 to 3efd202 Compare August 11, 2026 12:08

@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: 3efd202

Prior Findings Dispositioned (2)

  • prior:98bc7c9 important 1 — fixed — server/src/services/heartbeat.ts:18757issueIdFromRunContext now resolves issueId ?? taskId, and both finalization paths defer restoration using that helper before queuing the successful handoff.
  • prior:98bc7c9 important 2 — fixed — server/src/services/issue-checkout-status.ts:16 — terminal paths use per-column ownership release to clear a matching checkoutRunId before guarded status restoration; the dependency, stale-queue, and watchdog paths are covered.

Critical Issues (0)

Important Issues (0)

Suggestions (0)

Strengths

  • The shared restoration guard preserves a newer live retry owner while safely returning abandoned checkout promotions to their original status.
  • Regression coverage exercises taskId-only handoff, cancellation/fold cleanup, and finalizer continuation dispatch.

Recommended Action

  1. Merge when the remaining required checks and approvals are satisfied.

@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: 3efd202

Prior Findings Dispositioned (2)

  • prior:98bc7c9 important 1 — fixed — server/src/services/heartbeat.ts:18757issueIdFromRunContext now resolves issueId ?? taskId, and both finalization paths defer restoration using that helper before queuing the successful handoff.
  • prior:98bc7c9 important 2 — fixed — server/src/services/issue-checkout-status.ts:16 — terminal paths use per-column ownership release to clear a matching checkoutRunId before guarded status restoration; the dependency, stale-queue, and watchdog paths are covered.

Critical Issues (0)

Important Issues (0)

Suggestions (0)

Strengths

  • The shared restoration guard preserves a newer live retry owner while safely returning abandoned checkout promotions to their original status.
  • Regression coverage exercises taskId-only handoff, cancellation/fold cleanup, and finalizer continuation dispatch.

Recommended Action

  1. Merge when the remaining required checks and approvals are satisfied.

@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: 59c359c

Critical Issues (0)

Important Issues (0)

Suggestions (0)

Strengths

  • The exact-head regression now verifies the production cleanup sequence: a terminal adopter releases both ownership columns, restores the captured todo tier, and lets assigned-todo liveness enqueue issue_assigned without changing the assignee.
  • The full restoration implementation guards against live replacement runs and clears the marker only when the queue-tier restoration is actually safe.
  • The narrow follow-up changes the expected recovery contract without weakening production behavior.

Recommended Action

  1. Merge when the remaining required checks and approvals are satisfied.

@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: 59c359c

Critical Issues (0)

Important Issues (0)

Suggestions (0)

Strengths

  • The exact-head regression now verifies the production cleanup sequence: a terminal adopter releases both ownership columns, restores the captured todo tier, and lets assigned-todo liveness enqueue issue_assigned without changing the assignee.
  • The full restoration implementation guards against live replacement runs and clears the marker only when the queue-tier restoration is actually safe.
  • The narrow follow-up changes the expected recovery contract without weakening production behavior.

Recommended Action

  1. Merge when the remaining required checks and approvals are satisfied.

@kkroo
kkroo added this pull request to the merge queue Aug 11, 2026
Merged via the queue into master with commit 4b426db Aug 11, 2026
18 checks passed
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