Problem
A Turn selected for an open Todo with completion_validation_required can be stranded after a truthful blocked writeback. This is distinct from an accepted in_flight_continuation: the agent has no validated progress to claim because a peer currently owns an overlapping hard write lease.
Reproduction
- Select an open completion-validated Todo in a managed Turn.
- Let a different active task hold an overlapping write-scope lease, so implementation and terminal validation cannot proceed.
- Commit the Turn-bound
refresh-state with delivery_outcome=outcome_gap and progress_result_class=blocked. The durable writeback succeeds.
- Follow the returned settlement plan and call
quota spend-slot for the same Turn/Todo.
Observed: completion_validation_spend_error rejects the spend until the Todo is terminally validated. The Turn has a durable blocked writeback but no allowed settlement step. Re-selecting an independent Todo within that Turn conflicts with the selected identity. Retrying the same blocked writeback does not change the missing validation authority.
Expected behavior
A typed, non-consuming blocked settlement should close this Turn's accounting identity and schedule a bounded retry/backoff of the same Todo after the lease or other external blocker changes. It must preserve the terminal completion validator, prohibit a fabricated outcome_progress or completion, and prevent a second spend/writeback on replay. If a Turn has another explicit continuation route, project it in the settlement plan instead of instructing a spend that the validator must reject.
Owning boundary and tests
The spend gate in loopx/control_plane/quota/settlement_validation.py correctly permits an exact Turn-bound, satisfied in_flight_continuation while rejecting an unvalidated terminal claim. The missing case is a valid blocked outcome_gap with no terminal work possible. Add a managed-Turn regression with a completion-validated Todo and an overlapping hard lease: blocked writeback is durable; final receipt is non-consuming and retryable; no Todo completion, quota spend, or unrelated Todo selection is authorized by that receipt. Preserve negative cases for mismatched Turn/Todo identities and ordinary unvalidated progress.
Problem
A Turn selected for an open Todo with
completion_validation_requiredcan be stranded after a truthful blocked writeback. This is distinct from an acceptedin_flight_continuation: the agent has no validated progress to claim because a peer currently owns an overlapping hard write lease.Reproduction
refresh-statewithdelivery_outcome=outcome_gapandprogress_result_class=blocked. The durable writeback succeeds.quota spend-slotfor the same Turn/Todo.Observed:
completion_validation_spend_errorrejects the spend until the Todo is terminally validated. The Turn has a durable blocked writeback but no allowed settlement step. Re-selecting an independent Todo within that Turn conflicts with the selected identity. Retrying the same blocked writeback does not change the missing validation authority.Expected behavior
A typed, non-consuming blocked settlement should close this Turn's accounting identity and schedule a bounded retry/backoff of the same Todo after the lease or other external blocker changes. It must preserve the terminal completion validator, prohibit a fabricated
outcome_progressor completion, and prevent a second spend/writeback on replay. If a Turn has another explicit continuation route, project it in the settlement plan instead of instructing a spend that the validator must reject.Owning boundary and tests
The spend gate in
loopx/control_plane/quota/settlement_validation.pycorrectly permits an exact Turn-bound, satisfiedin_flight_continuationwhile rejecting an unvalidated terminal claim. The missing case is a valid blockedoutcome_gapwith no terminal work possible. Add a managed-Turn regression with a completion-validated Todo and an overlapping hard lease: blocked writeback is durable; final receipt is non-consuming and retryable; no Todo completion, quota spend, or unrelated Todo selection is authorized by that receipt. Preserve negative cases for mismatched Turn/Todo identities and ordinary unvalidated progress.