Contents

Scoped-QA dispatch and member close-out

A scoped-QA stage gates every member and wakes waiting members before closing accepted members. A member held by a QA configuration refusal (qa_configuration_refused) is woken too, once per wait, with the refusal and its recovery. An item-scoped member also settles when every run-bound item case has a current pass and evidence, including passes from yoke qa case run. A pending independent review still waits; rerunning passed cases cannot supply it. Automatic capture also stops when any live case in a plan has a latest fail or error verdict. Repeated dispatch cannot open another review for that failure. A declared --replaces correction transfers the obligation to its replacement; the failed predecessor no longer prevents the corrected case from capturing.

Plan ownership freezes at item QA entry. A plan attached by exactly one member runs as that member's QA: wake its holder to run yoke qa plan run --item PREFIX-N --stage STAGE. Plans shared by two or more members run as driver-owned plan groups; run-level QA also belongs only to the driver. Later attachments never change that ownership. Shared-plan waits, failures and passes send no member-holder notice; only item QA and close-out wake them. A failed shared plan tells the driver to triage which attaching items need code fixes and names rework, retry, authorized waiver and member-removal commands. The notice and fleet recovery name the pinned commit: Retry reruns that commit for environment/flaky failures; a merged code fix needs a new run on a later commit that takes over the failed run. Waive discharges the case; remove leaves the item's delivery owed. Closed groups credit only their recorded covered_item_ids across the superseded-run lineage. A later attacher gets a new group; already covered items do not wait on it. The group's pinned cases and target remain authoritative after plan edits. Run an open group with yoke qa plan run --deployment-run-id RUN --stage STAGE --plan PLAN; the run supplies its project. With no open group, the command refuses plan_group_not_open and names the closed groups. An ambiguous plan name refuses with the matching plan ids; select an exact id.

An unchanged wait reuses its notice while its recipient session remains live. A cancelled notice or an ended recipient permits redelivery to the live driver, then the run creator, then steering. Closing a group withdraws its old group notice. The fleet report names waiting requirements and commands, and flags QA waits with no live driver and an undelivered or unanswered notice.

Each dispatch closes accepted members in order and stops starting more work after five seconds. A close-out already running finishes; the budget cannot interrupt it. Each member's route is read fresh immediately before acting, so an earlier close-out cannot leave later routes stale. A refused close-out wakes its owner with the refusal and recovery, and the next member is still tried. The refused member retries by itself when its blocking record settles. While a member still has a live deployment-stage plan execution, verdict callbacks defer close-out and send no acceptance or failure notice; stage settlement closes the member after the delivering execution ends. A member the budget skipped closes on a later dispatch or at settlement; the skip never holds the stage.

If the idempotent dispatch exceeds its HTTPS response limit, the client waits for the server's existing reservation and recorded result using the identical request envelope and request id. It makes up to ten 60-second HTTPS waits, each within the hosted response cap. It never recovers this timeout through the self-deploy database door. The server replays a completed successful call; QA dispatch is also safe to repeat if the original failed before recording a successful result.

An in-flight copy answers idempotency_request_in_flight immediately. HTTPS result recovery keeps waiting on that same request id within its existing limit; those replies do not spend the driver's busy retry budget. The driver also keeps one request id across busy and lost-answer retries for a logical dispatch. Its next gate check gets a fresh id, so a recorded waiting result cannot freeze the stage.

Other busy dispatch answers (run_busy, qa_plan_busy, qa_checkin_busy, qa_ownership_busy, deployment_start_lock_busy, deployment_membership_changed, lock_timeout or statement_cancelled) return to the deploy driver's shared retry policy for every transport. In-process idempotency_request_in_flight also uses this policy. It retries after 15, 30, then 60 seconds, with six retries total, reusing the same request id. Named check-in, takeover, start and admission contention is retryable after its transaction rolls back. If every retry stays busy, the driver stops with deployment_run_stayed_busy, leaving the run and QA stage unchanged; resume with yoke watch deploy -- RUN-ID once the named holder finishes.

An unanswered recovery reports qa_dispatch_result_unconfirmed, leaving the run resumable at its QA stage. Read yoke deployment-runs get RUN-ID and the driver capture before re-driving that same run with yoke watch deploy -- RUN-ID. Do not use --fresh or the database door to recover an unknown result.

See deployment start diagnostics for other lost responses, stage interruptions and bounded QA waits.

QA dispatch ยท Yoke