Review and policy

Oversized PR close policy

Oversized PR close policy

  • Status: active
  • Owner: ClawSweeper maintainers
  • Source of truth: src/clawsweeper-oversized-pr-policy.ts, the review admission
  • hook, the guarded apply writer, and .github/workflows/sweep.yml

  • Verified scope: shared review admission, exact-event handoff, and synthetic
  • GitHub apply on the policy branch; production closing is not exercised

  • Update when: admission order, metadata fields, exemptions, close gates,
  • repository apply rules, or record publication changes

An open pull request whose GitHub-reported additions plus deletions exceeds CLAWSWEEPER_MAX_PR_CHANGED_LINES receives the deterministic oversized_pull_request close proposal before structural-cache inspection, review-start comments, list/blob hydration, scanning, or model review. The threshold defaults to 50,000. It must be a positive integer; invalid values fall back to the default. Exactly 50,000 lines is admitted; 50,001 is oversized. Missing or invalid size/head metadata admits the PR normally.

Drafts and owner/member-authored PRs are subject to the policy. The existing PR_AUTO_CLOSE_EXEMPT_LABEL_NAMES labels (clawsweeper:human-review, clawsweeper:manual-only, clawsweeper:autofix, clawsweeper:automerge) and size: accepted-large exempt a deliberately large change. PR status label synchronization creates the maintainer-owned size label but never applies it on a maintainer's behalf. Existing security/protected-label and repository apply restrictions remain in force; the maintainer label alone does not exempt an oversized PR.

Exact events, scheduled work admitted through the exact queue, and shard review share the predicate. The exact-event live-state check saves its raw PR payload and invokes the built predicate. Oversized items skip target checkout, review-tool setup, reactions, and reservation, then use the same review CLI to write the report. Ordinary admitted PRs reuse the payload during hydration. Each head or label change is evaluated again. This policy never reopens a PR.

CLAWSWEEPER_OVERSIZED_PR_CLOSE_ENABLED gates apply; it defaults off in a standalone CLI and defaults to true in the sweep workflow. The normal close-reason filter includes this reason when CLAWSWEEPER_AUTO_CLOSE_REASONS=all. Dry-run, comment-only publication, or a closed policy/reason gate leaves the proposal in records/<slug>/items/<n>.md with decision: close and its additions, deletions, changedFiles, threshold, and head evidence. The report also records a metadata source fingerprint and comment counts. No scanner or model provenance is asserted.

Apply requires complete recorded metadata and repeats the live PR size, head, open-state, lock, and exemption checks immediately before closing. Changed metadata or unreadable live state blocks the close. The source record also carries the observation time taken before the PR metadata read; initial activity at that second or within the one-second clock margin is ambiguous and keeps the proposal open. Missing handoff observation times fall back conservatively to the PR update timestamp. Submitted reviews expose no edit timestamp, so a PR update timestamp in that observation window also blocks initial receipt creation when reviews exist. Before comment publication, apply captures bounded issue-comment, timeline, inline-comment, and review metadata, with a maximum of three 100-entry pages per stream. Incomplete reads keep the proposal open. The receipt excludes only the exact owned review-comment ID and verifies that comment against its write response; all other activity remains fingerprinted. The baseline is persisted before publication, and the exact owned write identity is persisted before any post-publication read, including when subsequent validation fails. Forced checks before closing catch body edits and same-second human comments after publication, and persisted receipts preserve that protection across retries. PR files, commits, blobs, scanner work, and model review are not hydrated by this guard.

Changed metadata or unreadable live state blocks the close. The public notice uses proposal wording until GitHub confirms the close, so an aborted close never claims success. After closing, apply updates that same comment to the template below without replacing a newer canonical review. Normal freshness and durable-comment guards still apply. The existing writer posts the one policy comment and closes the PR; archiveClosed moves the report to closed/ only after success. Bay's observer projection treats the pending proposal and actual close exactly as other reasons; it gains no action controls.

The public comment is:

ClawSweeper closed this pull request because it changes {total} lines ({additions} added, {deletions} removed) across {files} files, above this repository's {threshold}-line limit for review. Changes this large cannot be reviewed safely or scanned within limits and usually indicate a stale branch merged against an old base. Please open a fresh pull request from current main containing only the intended change, or split it into focused pull requests. A maintainer can apply size: accepted-large to exempt a deliberately large change.

#Reproducible proof

node scripts/proof-oversized-pr-close.mjs exercises metadata admission and dry-run retention, with a 29,999-line control. node scripts/proof-oversized-pr-close-effects.mjs drives the built CLI through a loopback HTTP GitHub adapter and inspects service state plus items/closed records for eligible closing, protected-label refusal, and late exemption, body, and human-comment changes. This uses synthetic data and transport; it does not close a live GitHub PR. The workflow test also executes a HTTP-409 finalization branch and verifies that supersession prevents publication.