Skip to content

Complete merge-queue lifecycle and retry guards - #46

Open
mchwang wants to merge 6 commits into
mainfrom
codex/merge-queue-k2-k3
Open

mchwang wants to merge 6 commits into
mainfrom
codex/merge-queue-k2-k3

Conversation

@mchwang

@mchwang mchwang commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Closes #24.

Outcome

Completes lane K2/K3 on baseline 13a7b308011c1ea5ef57ec974c5c338584538ec2:

  • persists submitting -> queued -> merged | removed | failed attempts against the exact plan revision, snapshot, review version, and reviewed head;
  • treats enqueue success as queued, never merged, and recovers a committed enqueue when its immediate local refresh fails;
  • polls queue state through a narrow endpoint without rebuilding Git history;
  • disables the action while submitting/queued and after confirmed merge;
  • preserves terminal removal/failure reasons and safely retries only an unchanged reviewed context;
  • keeps replacement heads blocked until every plan item has a replacement-snapshot approval;
  • requires both validation reads to agree on queue mode before submission;
  • guards stale poll publication by attempt identity and legal-state compare-and-swap;
  • aborts and awaits active enqueue/queue inspection during shutdown;
  • preserves UI selection, draft, attachments, and navigation while queue polling updates only merge state.

Lifecycle/state-holder and interface details are recorded in issue #24 and docs/implementation/merge-queue.md. Queue support remains fail-closed for adapters that do not implement the K1 observation contract.

Validation

Validated head: cff4b12b11bd2c33f5eeab7304cf583953dee19a (exact pushed head).

  • GitHub CI run 36046438177: typecheck passed; 379 tests across 16 files passed; 46 browser tests passed.
  • GitHub CI run 36046445549: typecheck passed; 379 tests across 16 files passed; 46 browser tests passed.
  • Focused local review regressions: replacement approval generation, queue-mode flip, and the previously timed-out question suite all passed.
  • git diff --check passed.

A local full-suite attempt experienced timeout-only failures while lane D ran Vitest concurrently in another worktree; each failed suite passed in isolation, and both isolated GitHub runners passed the standard commands at the exact head.

Controlled regressions cover enqueue success, delayed merge, queue removal, unmergeable failure, head replacement and complete re-review, queue-mode changes between validation passes, retry, retry while prior work is active, stale old-attempt publication, restart recovery, post-enqueue local refresh failure, queue-inspection shutdown settlement, partial-request shutdown admission, and UI draft/selection preservation.

Review rounds

  • Self-review round 1: fixed exact-head observation validation and stale poll invalidation after page failure.
  • Self-review round 2: no new findings.
  • Copilot round 1: two valid findings fixed in cff4b12: replacement-head fresh-review gating and queue-mode stability across validation reads. Regressions added; threads replied to and resolved.
  • Declined findings: none.
  • Deferred follow-ups: none.

Review-lesson audit

  • Existing rules cover stale publication, shutdown settlement, durable/visible divergence, and post-action failure handling.
  • New AGENTS.md rules capture both round-1 lessons: context replacement does not itself satisfy fresh review, and lifecycle mode changes between validation passes must abort before the irreversible command.
  • No finding was classified as one-off.

Current head is mergeable, both CI runs are green, and unresolved review threads are 0. Awaiting a clean Copilot re-review. Do not merge without explicit authorization.

Copilot AI lite review requested due to automatic review settings September 24, 2026 18:58

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Unresolved fresh-review, queue identity, retry, and shutdown race conditions can leave state inconsistent or permit unsafe merges.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity · 1 Medium severity

Open (2)
What changed in this PR

Completes durable merge-queue lifecycle tracking, guarded retries, queue polling, shutdown handling, and UI state preservation.

Changes:

  • Persists merge attempts and terminal outcomes.
  • Adds queue observation and stale-response protection.
  • Updates UI behavior and regression coverage.
File Summary
web/​server.ts Exposes queue polling endpoints.
web/​public/​app.js Renders and polls merge-queue state.
test/​store.test.ts Tests persistence and stale transitions.
test/​merge.test.ts Tests lifecycle and concurrency behavior.
test/​browser/​review.spec.ts Tests queue UI workflows.
runner/​store.ts Persists merge-attempt lifecycle state.
runner/​merge.ts Coordinates enqueue, polling, retries, and shutdown.
github/​merge.ts Observes GitHub merge-queue state.
docs/​implementation/​merge-queue.md Documents lifecycle and runtime behavior.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread runner/merge.ts Outdated
Comment thread runner/merge.ts
Copilot AI review requested due to automatic review settings September 24, 2026 19:11

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

Seven moderate review findings remain unresolved.

Review effort: Lite
Findings: None

Resolved since last review (2)
Previously missed (1)

In code that hasn't changed since last review

Medium severity Preserve submitting state for ambiguous enqueue outcomes

runner/​merge.ts:155

This catch marks every enqueue-side error, including cancellation or timeout, as a terminal failed attempt and makes it retryable. If gh pr merge has already been accepted by GitHub when the local process is aborted (especially during close()), the existing queue entry is no longer polled; after restart the UI can offer a second enqueue for the same head. Preserve the submitting record for ambiguous command outcomes and recover it through queue inspection, only recording failed when the adapter can establish that submission was refused before commit.

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Unresolved critical enqueue/retry correlation issues and additional lifecycle race and shutdown issues block approval.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 2 High severity · 1 Medium severity

Open (3)

Comment thread runner/merge.ts Outdated
Comment thread runner/merge.ts
Comment thread runner/merge.ts Outdated
Copilot AI review requested due to automatic review settings September 24, 2026 19:20

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

Unresolved moderate findings affect retry correctness, failure handling, stale UI state, and queue polling load.

Review effort: Lite
Findings: 1 High severity · 1 Medium severity

Open (2)
Resolved since last review (1)

Copilot AI review requested due to automatic review settings September 24, 2026 19:29

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Address the retry-attempt timestamp boundary and classify reviewed-head mismatches as terminal fresh-review outcomes.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity

Open (1)
Resolved since last review (2)

Comment thread github/merge.ts Outdated
Copilot AI review requested due to automatic review settings September 24, 2026 19:42

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Unresolved critical and moderate lifecycle, review-gating, retry, and polling issues remain.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity

Open (1)
Resolved since last review (1)

Comment thread runner/merge.ts Outdated
Copilot AI review requested due to automatic review settings September 24, 2026 19:49

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

Five unresolved review findings remain, including four moderate issues.

Review effort: Lite
Findings: None

Resolved since last review (1)
Previously missed (1)

In code that hasn't changed since last review

Medium severity Stale polling response can overwrite newer review state

web/​public/​app.js:140

This poll is guarded only by mergeGeneration, but review actions in act() update data and reviewGeneration without incrementing mergeGeneration. If a note/assignment completes while this request is in flight, the older response can overwrite the current merge queue status (for example, re-enable retry using the pre-action review version). Capture the current review token/generation when polling starts and discard the response if it changed.

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.

Support and verify merge-queue lifecycle

2 participants