Repository navigation
fix: freeze approved feature heads during integration - #674
krasnoperov-coding-agent[bot] merged 3 commits into
Conversation
| // A repair budget represents an agent attempt, not an enqueue, worktree | ||
| // preparation, failed claim, or other pre-turn infrastructure work. | ||
| // Consume it only after Codex confirms that the turn actually started. | ||
| if (!this.runTaskPlanner.incrementAttemptCounters( |
There was a problem hiding this comment.
🚨 Attempt accounting is not atomic with turn start. claimRun still records lastAttemptedFailure* before pre-turn setup, so a failed CI launch suppresses same-head retry despite consuming no budget; an early completion can also release the lease before this post-await increment, letting retries evade the budget. Record both counter and provenance at a turn-start boundary ordered before completion handling.
Superseded by newer head 91a829a; review-quill will re-review the latest commit separately.
| lastAttemptedFailureAt: new Date().toISOString(), | ||
| } | ||
| : {}), | ||
| ...buildAttemptStartFields(params.runType, fresh, params.effectiveContext), |
There was a problem hiding this comment.
🚨 Claim-time accounting still misses a pre-turn crash window. If PatchRelay exits after persisting the thread but before startTurn, restart reads a valid thread with zero turns; reconciliation never settles it, leaving activeRunId and the consumed budget pinned indefinitely.
| lastAttemptedFailureAt: new Date().toISOString(), | ||
| } | ||
| : {}), | ||
| ...buildAttemptStartFields(params.runType, fresh, params.effectiveContext), |
There was a problem hiding this comment.
🚨 The counter is derived from fresh, but the claim commit reuses that same update on version conflict. A concurrent head/reset write can therefore be overwritten with a stale counter value instead of recomputing current + 1, prematurely exhausting the repair budget.
Superseded by newer head 4c17901; review-quill will re-review the latest commit separately.
Summary
mainmovement produces a dirty PRInvariants