Context (ORB round-2 adversarial audit)
Two compounding gaps:
- src/db/repositories.ts's #webhook-reorder-clobber guard (:379-404) protects state/headSha/mergedAt from stale-payload regression, but labelsJson is written UNCONDITIONALLY (:456 insert, :483 update) — a reordered webhook with a stale label snapshot silently wipes a just-applied pending-closure/manual-review label. upsertIssueFromGitHub (:540-578) has no reorder protection at all.
- src/queue/processors.ts:3535-3542 (reReviewStoredPullRequest): the live fetch's labels are only persisted when the HEAD SHA changed — a label-only change (exactly what Pass 1 of flag-then-close produces) is discarded despite being in hand.
Effect: the Pass-2 verify job (default closeDelaySeconds 30s) can misread pendingClosureLabelPresent=false, re-run Pass 1, and re-post the warning comment — duplicated warnings + delayed enforcement under queue backpressure.
Fix
Extend the reorder guard to labelsJson; add reorder protection to upsertIssueFromGitHub's state; resync in reReviewStoredPullRequest on live-vs-stored label mismatch, not just head drift. Tests: stale-payload label preservation; label-only resync; the two-pass machine under a delayed labeled-webhook.
99%+ patch coverage, branch-counted.
Context (ORB round-2 adversarial audit)
Two compounding gaps:
Effect: the Pass-2 verify job (default closeDelaySeconds 30s) can misread pendingClosureLabelPresent=false, re-run Pass 1, and re-post the warning comment — duplicated warnings + delayed enforcement under queue backpressure.
Fix
Extend the reorder guard to labelsJson; add reorder protection to upsertIssueFromGitHub's state; resync in reReviewStoredPullRequest on live-vs-stored label mismatch, not just head drift. Tests: stale-payload label preservation; label-only resync; the two-pass machine under a delayed labeled-webhook.
99%+ patch coverage, branch-counted.