On this page

On this page

Project and contributing

PR merge admission

PR merge admission

  • Fresh merge admission on every route (ordinary, prior-CI admin, and Crabbox) accepts forward main movement only after proving descent from the observed and verified main anchors and checking the prepared-head merge tree is conflict-free and nonempty. PR identity, head, base, lifecycle, draft state, and policy facts stay pinned. Mergeability projections may recalculate; UNKNOWN settles within a 60-second window with 2/4/8-second capped backoff, then MERGEABLE and the selected route's policy requirements must hold. The verified-main cursor advances separately from the original intent and landing-parent audit anchor. OPENCLAW_PR_STRICT_DRIFT=1 restores abort-on-main-change during observation and final Crabbox validation, in addition to its merge-verify drift gate. Prior-CI authority retains its existing ordering: For already-selected REST, the last complete observation and main materialization precede one final live authority verification. GraphQL retains its post-authority local-only reread (no lazy or explicit fetch), refusing a newly unavailable main before intent; late REST fallback retains that boundary and rechecks authority. No materialization follows final authority verification. OPEN/CLOSED/pending/uncertain reconciliation retains exact full PR/main snapshot stability. Only a validated MERGED receipt may accept forward main advancement between its two observations: every PR fact must remain equal, acquire the reread's exact main commit through the same canonical trusted URL when absent locally, and prove the original observed main is its ancestor. Equal snapshots keep the fast path. Both snapshots stay pinned; never add a third reread loop. This completes an already-proven merge, never grants authority for a future merge; historical tree/source-base checks and receipt/comment/cleanup ownership remain unchanged.

  • Local object-availability probes and strict retained-record reads use command-scoped GIT_NO_LAZY_FETCH=1. Upstream Git 2.45 first supports this environment variable; older Git may still hydrate objects implicitly and cannot promise local-only probes. The immutable-head reuse probe and final GraphQL prior-CI local-only check also use Git's explicit --no-lazy-fetch switch: unsupported Git falls back to canonical head acquisition or refuses that final main-advance optimization. This is not a new all-command minimum or an offline workflow: explicit canonical fetches and actual tree/diff/archive/push/checkout operations remain available. Completed-receipt correctness depends on pinned facts and ancestry/tree proof, not this download avoidance.

  • A pinned commit missing locally is fetched from the observed repository's URL, not origin, leaving refs and FETCH_HEAD unchanged. In a partial clone that fetch applies origin's promisor filter for that one command, so Git takes its promisor-pack connectivity shortcut instead of parsing every promisor object. Omitted blobs are lazily fetched from origin.

  • Fresh initial admission and later admission stability checks give UNKNOWN mergeability a 60-second settle window starting at the first observed UNKNOWN, sleeping 2 then 4 seconds with subsequent pauses capped at 8 seconds. Remote reads and backoff consume this budget; completed local Git materialization and merge-tree proof do not. The separate 900-second admin authority deadline still includes all elapsed time. Each requalification round consumes its first fresh projection before applying a carried settlement deadline; an expired budget still refuses admission after that observation. Between complete REST observations, projection-only hints use the selected reader without repeating policy, check-suite, or authority reads. GraphQL keeps its single-request complete observations without an additional hint. A known hint only requests another complete observation; it never changes the retained snapshot, selected transport, main cursor, or authority, and never closes or extends the settle window. The complete observation must still pass every original head, main, policy, projection, and authority check. PR and policy facts and each already-known projection stay pinned; a known authoritative projection ends its UNKNOWN episode. Retained-outcome reconciliation never polls. Before intent on PRs without a merge queue, ordinary merges reject gh's BLOCKED/BEHIND/DIRTY refusals and admin merges reject DIRTY; queue and auto retain their distinct admission contracts.

  • Explicit prior-CI admission may select the complete REST observation owner after a valid GraphQL snapshot has an UNKNOWN projection. The next observation must preserve every known PR/projection fact; REST rereads retain repository identity, exact head, main, rules, and complete required-check evidence without converting BLOCKED to CLEAN. That reader remains selected through the attempt. During active prior-CI admission, both main endpoints of a complete REST read pass through the same forward-ancestry and merge-composition owner before normalization; branch policy is rechecked, and transient read bounds never enter retained outcomes. The latest validated main is tracked separately from the intent anchor. Only a new proven forward advance may open a 60-second recalculation window (2/4/8-second capped backoff); exact PR/policy/check facts and original known projection values stay pinned, each subsequent main must advance from the latest read, and UNKNOWN never authorizes dispatch. The final already-selected REST window materializes both endpoints and the verified anchor before authority verification, including recalculation reads. GraphQL and late REST fallback retain their post-authority local-only window. If that GraphQL window observes a new main whose raw object is conclusively absent, it discards the active authority proof and returns to pre-authority materialization of that exact tip. Both earlier pins must remain readable; failed queries, stderr, corruption, permission errors, and unsupported Git never imply absence. Each new round preserves the observed tip as an ancestry lower bound and repeats complete live CI, head, review, evidence, security, and admin verification against the original proof fingerprint. Authority requalification is bounded by 900 seconds and 32 rounds, with round timings and refusal before intent or dispatch on exhaustion; no fetch occurs inside a qualified final authority window. Outside active admission, OPEN/CLOSED snapshot stability remains strict. Both observation and new intent record REST transport, while the existing prior-CI verifier still owns all CI exceptions, enforced reviews, and security clearance. Already-selected REST runs it once after the final complete reread, before unchanged evidence/artifact checks and intent CAS; it does not reopen a redundant observation and verification window. Unknown or malformed REST projections, conflicts, unsupported policy, and changed authority refuse admission. Ordinary REST remains passing-check/CLEAN-only; Crabbox and retained-outcome reconciliation gain no new dispatch authority.

  • When GraphQL is selected, ordinary immediate squash dispatch uses the selected writer's exact-head mutation directly after one final explicit pre-merge revalidation. It preserves the captured body, omits the headline so GitHub retains its existing defaults, and cannot enqueue or arm auto-merge. Its initial and final public snapshots bind the head; existing REST source acquisition binds the branch, and both independent post-dispatch receipt observations remain fresh. Queue, auto, admin, merge, and rebase retain native gh pr merge dispatch and their additional authority windows.

  • Fresh direct PR/main reads and stable re-reads narrow races; they do not provide global exactly-once execution or a base-OID merge precondition. Immediate squash refuses NO NET CHANGE without claiming the PR merged or all intended content remains present. Normal squash/merge receipts reconstruct the tree at the actual landed parent; merge also requires prepared-head ancestry. Rebase and queue receipts verify the aggregate reviewed delta in the historical landed tree using the unique source fork base of retained main/head, not the final rebased parent or recorded main itself. Missing or ambiguous source bases fail closed. Later main advancement or reverts do not authorize reapplication. A normal recorded squash that was empty at its landed parent warns for investigation; its receipt remains confirmed, with no resubmission or automatic revert.

  • Before recording intent, --auto-merge selects immediate pinned squash for MERGEABLE/CLEAN or auto for MERGEABLE/BEHIND or MERGEABLE/BLOCKED, subject to all admission gates and queue policy. Accepted auto/queue requests are visible pending outcomes, not completion. The request carries --match-head-commit; confirmation still requires the exact attempted head. This is a submission-time head precondition, not a server-side freeze against later collaborator pushes; if GitHub merged the pushed head, use the explicit merge-recover --merged-head <SHA> receipt route. Existing or ambiguous requests are never automatically cancelled, re-armed, or followed by an immediate fallback; an explicitly investigated accepted auto request uses the cancellation recovery. Ordinary gh pr merge can enqueue when queue policy applies.

  • --auto-merge selects immediate squash for MERGEABLE/UNSTABLE only after one fresh scripts/watch-pr-ci.mjs --completion rollup --once pass at the exact prepared head exits GREEN; --once evaluates one attach and one rollup observation without waiting, and --timeout bounds only that pass's evidence reads. GitHub's rollup and merge projection retain runs superseded by a newer same workflow/event/job-name run on that head, such as a draft opened ClawSweeper Dispatch run after ready_for_review. The watcher's classifyRollup owns supersession; the pass also requires the attached ci.yml run to succeed. Any unsuperseded failure, hidden or paginated context, missing run identity, pending check, moved head, conflict, or watcher error refuses admission; the watcher's existing auto-response exclusion applies unchanged. This is a one-shot admission predicate, not a pinned snapshot fact: GitHub still enforces required checks at dispatch, the exact-head mutation pins the head, and the final stability reread pins the UNSTABLE projection. Pinning rollup contexts would extend the Octopool-allowlisted landing snapshot query and retained-outcome schema for a risk server enforcement already bounds. Accepted edge case: a new non-required failure on the same head between the pass and dispatch is not rechecked. Retained intents never rerun the predicate or redispatch; explicit recovery reruns admission.

Complete check-suite reads

Required-check admission keeps the complete suite inventory bounded to 1,000 suites, matching GitHub’s reference check-run endpoint limit. Unrepresented non-success suites from a required app are proved irrelevant using one complete, paginated latest-check-run snapshot without a name filter, grouped by suite ID, then a second complete suite inventory. Every selected suite must have its exact check count, unique check identities, matching head and app, no required context, and unchanged status, conclusion, update time, and count. Missing or contradictory pages and changed inventories refuse admission. The limit is suites, not check runs; many skipped or empty suites do not require per-suite API subprocesses.

Was this useful?