Skip to content

gate(policy): wire pr_budget.t27 into a pull_request_target gate -- draft the 21st open PR, promote held drafts, exempt queen-* bees #10074

Closed

Description

@gHashTag

#10070 writes the PR budget down as a t27 card, specs/policy/pr_budget.t27: at most 20 open non-draft PRs per author, the excess held as drafts, drafts promoted in order as slots free. Nothing reads the card yet. This issue wires it into a gate.

Measured 2026-10-18: open PRs are dmitrii-f-t27 128 (all 128 from forks), gHashTag 163 (131 of them on queen-* branches), dependabot 5. Because the fork PRs carry a read-only token on pull_request, the gate runs on pull_request_target and checks out only the base branch's gen/c/policy (no PR code is built or run).

Owner decision 2026-10-18: PRs on queen-* branches are exempt -- they do not count against the cap and are never drafted -- but only when the branch lives in gHashTag/t27 itself, so a fork cannot claim the exemption by naming a branch queen-1. Everyone else is capped, the owner's hand-opened PRs included.

Shape, following the issue-shape gate (needs-boundary.yml + gen/c/policy/issue_shape.c): the logic is in the card, lowered by t27c gen-c; the workflow is a one-line C main around the generated function plus gh calls. The workflow feeds the card one line for the event PR and one line per other open PR of the same author (oldest first); the card prints the actions (draft N / ready N). A held draft carries the label pr-budget-held, so a draft its author made on purpose is never promoted. No existing PR is closed; existing ready PRs are not touched until their own next event.

Boundary

  • specs/policy/pr_budget.t27
  • gen/c/policy/pr_budget.c
  • .trinity/seals/policy_PolicyPrBudget.json
  • .github/workflows/pr-budget.yml
  • specs/claw/gates.t27
  • specs/claw/gates_pins.t27
  • gen/c/claw/gates.c
  • docs/claw/README.md
  • scripts/trinity-pellis-pipeline/fix_bugs.py
  • scripts/trinity-pellis-pipeline/fix_bugs_v2.py

User Scenarios

  • Given dmitrii-f-t27 holds 20 or more open ready PRs, when they open one more, then the gate converts it to a draft, labels it pr-budget-held and comments that it is held by specs/policy/pr_budget.t27 until a slot frees.
  • Given an author holds 17 ready PRs and 5 held drafts, when one ready PR merges, then the gate promotes the 4 oldest held drafts to ready, so the author is back at 20.
  • Given a PR on a queen-* branch of gHashTag/t27, when it is opened, then it is never drafted and does not count against the cap.
  • Given a fork PR on a branch named queen-1, when it is opened by an author at the cap, then it is drafted like any other PR.

Requirements

  • FR-001: The card MUST define the exemption as branch prefix queen- with the head repository equal to the base repository, with tests for both sides.
  • FR-002: The card MUST expose one function that reads the event line and the author's other open PRs and writes the drafts and promotions, using admit() and promoted().
  • FR-003: gen/c/policy/pr_budget.c MUST be the unedited t27c gen-c output of the card, with its seal.
  • FR-004: The workflow MUST run on pull_request_target, MUST NOT check out or run PR code, and MUST stay under 40 added lines.
  • FR-005: The gate MUST NOT close any PR.

Success Criteria

  • The card's tests pass on the Railway lab with t27c test-report, 0 vacuous, and the harness from the workflow, compiled on the lab against gen/c/policy/pr_budget.c, prints draft N for a 21st PR: exit 0.
  • Negative control: the same harness with OPEN_CAP raised to 200 prints nothing for that PR, and a fork queen-1 row is still drafted.
  • The PR changes 10 files, 0 outside the Boundary; .github/workflows/pr-budget.yml adds at most 40 lines, and the foreign-line total shrinks (the two orphaned one-off scripts scripts/trinity-pellis-pipeline/fix_bugs*.py, 99 lines, zero references, are deleted).
  • The TRI CLAW inventory specs/claw/gates.t27 carries the new pr-budget row (67 workflows, census 62/3/2), its tests pass on the lab, gen/c/claw/gates.c is its regenerated output, and the claw-drift harness prints matrix is current (negative control: without the row it prints DRIFT).
  • 0 existing PRs are closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions