This directory contains both automatic readiness gates and intentionally
opt-in support tools. A script is not an automatic PR gate merely because it
lives under scripts/dev/; use the invocation surface documented below as the
source of truth.
Fast finder for the most common contributor tasks. Each entry names the
maintained entry point; run uv run python scripts/dev/<script>.py --help
(shell helpers: scripts/dev/<script>.sh --help) for flags and exit codes.
| I want to... | Use |
|---|---|
| Check whether my branch is ready for a PR | pr_ready_check.sh (see Required readiness gates) |
| Format and lint my changes | ruff_fix_format.sh |
| Run the test suite | run_tests_parallel.sh, run_focused_tests.sh, run_ci_local.sh |
| Run a bounded command without flooding the terminal | run_compact_validation.py |
| Count collected tests for validation metadata | pytest_collect_count.py |
| Create a linked worktree for isolated work | create_worktree.sh |
| Restore files without losing uncommitted work | safe_checkout.sh |
| Reuse the main checkout environment in a worktree | run_worktree_shared_venv.sh |
| Check worktree disk capacity or reclaim space | check_worktree_capacity.py |
| Diagnose a worktree or stale CI state | worktree_hygiene_snapshot.py, recover_stale_ci_run.py, diagnose_actions_job.py |
| Check CI status for a PR | check_pr_ci_status.py, watch_pr_ci_status.py, compact_ci_snapshot.py |
| Post a Markdown-heavy GitHub comment or review | gh_comment.sh, gh_pr_review_rest.py |
| Reconcile a PR title/body after a fix push | gh_pr_body_rest.py |
| Read issue or PR state without deprecated GraphQL fields | gh_issue_rest.py, gh_issue_view.sh, snapshot_issue_batch.py, snapshot_pr_queue.py |
| Claim an issue for cross-machine agent work | issue_claim.py |
| Audit what the scripts catalog tracks | check_scripts_catalog.py, scripts_catalog.py |
| Regenerate generated docs surfaces | render_scripts_readme.py, generate_cli_reference.py, generate_environment_config_reference.py, generate_skills_readme.py, generate_quickstart_notebooks.py |
| Check documentation link and evidence integrity | check_curated_doc_links.py, check_docs_evidence_integrity.py, check_context_notes.sh |
| Run docstring TODO ratchets | check_docstring_todos_ratchet.sh, check_docstring_todos_diff.sh |
| Audit code-size, assert, config-family, or helper drift | audit_function_lengths.py, audit_production_asserts.py, audit_config_families.py, audit_validation_helpers.py |
| Run an offline smoke of the local workflow | run_offline_smoke.py |
| Check optional dependencies without importing project code | check_worktree_optional_deps.py |
Full narrative contracts for the numbered sections below cover the tools that need more explanation than a table row.
BASE_REF=origin/main scripts/dev/pr_ready_check.sh is the local readiness
entry point for ordinary PR work. CI workflows and the documented PR process
own the required checks that run for every applicable change.
If readiness receives a termination signal, it preserves a private,
bounded receipt under output/validation/pr_ready/ with the active phase,
lane, process-group cleanup result, and small host/cgroup resource snapshot.
Set PR_READY_TERMINATION_RECEIPT=/absolute/path/receipt.json when a caller
needs a stable handoff path. The receipt never includes the command line or
environment, and readiness still returns the conventional signal status (143
for SIGTERM, the termination signal).
When quoting readiness counts, use the named selectors in
docs/dev/local_ci.md,
including --collect-only -q when only the collected count is needed.
pr_ready_artifact_contract.py validates and
reconciles machine-readable readiness receipts with an optional human summary
and command log. It emits JSON from byte zero and exits non-zero when artifacts
are malformed, terminated, interim, unavailable, or inconsistent:
python scripts/dev/pr_ready_artifact_contract.py \
--machine-json <readiness.json> \
[--human-summary RESULT.md] [--command-log readiness.log]check_base_drift.py backs the readiness gate's base-drift recheck (issue
#5782). The gate captures the concrete base SHA before the expensive lanes and invokes this check
immediately before recording the stamp, so it can tell whether origin/main moved during the run.
Drift that touches none of the PR's changed files recommends reuse; drift that intersects them
requires revalidation. One regenerable exception exists: when the intersection is exactly
scripts/validation/docstring_todo_baseline.json, the gate re-runs the targeted docstring baseline
and ratchet gates and, only on success, revalidates through that narrow path with a recorded
baseline_revalidation receipt; mixed drift stays fail-closed. The checker exits 0 when the base
is current or the drift is reusable, 1 when revalidation is required, and 2 when the base ref
or drift cannot be resolved.
The native merge queue enforcement path is
merge_queue_gate.py, invoked by
.github/workflows/merge-queue-gate.yml
on merge_group. The standalone protection audit below does not replace that
workflow or change branch protection.
check_instruction_references.pyvalidates the agent instruction graph: the single task-route owner, theInstruction Precedenceblock, the execution-profile manifest, the maintainer-values drift rule, and repository-local reference resolution. Runuv run python scripts/dev/check_instruction_references.py [--json].check_skills.pyvalidates the repo-local skill registry and runs a skill preflight; use--preflight <skill>before relying on a skill's declared requirements.scripts/tools/sync_ai_config.py --checkkeeps provider adapters thin, scoped, and linked to canonical sources (see.agents/README.md).check_agent_instructions.shcomposes the three checks above into one entry point for instruction-contract changes; runscripts/dev/check_agent_instructions.sh(optional--json). It is also available as the VS Code taskAgent Instruction Checks.
These are contract checks for repository instructions, not PR merge gates;
pr_ready_check.sh remains the required readiness entry point.
check_pr_closing_reference.py verifies that
GitHub's GraphQL closingIssuesReferences for a specific PR contains an issue
number supplied by an already authorized work packet. It must not infer the
expected issue from PR prose.
uv run python scripts/dev/check_pr_closing_reference.py \
<pr-number> <expected-issue-number> --repo ll7/robot_sf_ll7Add --json for the machine-readable result. Exit status is 0 when the
expected issue is present, 1 when it is absent, and 2 when the result is
unavailable or the input is invalid. The command is read-only; it does not
edit PR bodies, labels, issues, or branches. Because it queries GitHub, an
API failure is an unknown result and must remain a blocker.
check_merge_queue_protection.py is a
read-only audit for the maintainer-owned merge-queue activation dimensions
from issue #6404. Run its deterministic offline contract test with:
uv run python scripts/dev/check_merge_queue_protection.py --self-testAfter a maintainer changes branch/ruleset settings, run the live audit with:
uv run python scripts/dev/check_merge_queue_protection.py \
--check --repo ll7/robot_sf_ll7 [--pr <enqueued-pr-number>]--pr is optional and is only meaningful for a PR that is actually enqueued;
it probes the live ALLGREEN strategy. The audit fails closed when a required
dimension is unsatisfied or unverifiable. It performs no ruleset, branch,
queue, PR, issue, or workflow mutation, and it cannot claim that a real
merge_group run exists unless GitHub provides that evidence.
prune_stale_remote_branches.py is the
dry-run-first sweep for stale remote heads (issue #9087). It deletes only two
safe classes: merged_code_branch (tip already an ancestor of origin/main
with no open PR) and claim_ref_closed_issue (agent-claims/issue-<n> whose
issue is closed). Everything else is kept, including protected refs, open-PR
heads, claims whose issue is open or unresolved, and any ref whose state cannot
be determined. Run a scan (no deletion) at a cadence of roughly once a month or
after a large campaign:
uv run python scripts/dev/prune_stale_remote_branches.py --report /tmp/prune.jsonApply is explicit and bounded; rerunning is idempotent because deleted refs no longer classify:
uv run python scripts/dev/prune_stale_remote_branches.py --apply --limit 25 --report /tmp/prune.jsonThe CI aggregate workflow extracts its reusable executable logic into tested helpers (issue #7666):
-
model_cache_key.pyderives the exact-repeat model-cache key from registry-pinned digests:uv run python scripts/dev/model_cache_key.py --config <ppo-config.yaml> --machine
-
merge_test_durations.pyvalidates and merges the four pytest-split duration shard stores:uv run python scripts/dev/merge_test_durations.py \ --artifact-dir .duration-artifacts --output .test_durations
-
check_ci_needs.pyevaluates the aggregate job's required needs results with event-specific coverage rules:uv run python scripts/dev/check_ci_needs.py --event-name pull_request --results '{"fast-feedback": "success"}'
Focused tests live in tests/dev/test_ci_helpers.py; the workflow-contract parity
checks live in tests/test_ci_script_contract.py.
prepare_open_issue_contracts.py consumes the
report-only open_issue_contract_audit.v1 output from
audit_open_issue_contracts.py and emits per-issue
goal-autopilot preparation packets (issue #7929). Plan, render, and verify modes
are report-only; apply requires an explicit reviewed plan and a bounded, CAS-guarded
batch. Real apply additionally requires the exact selected issue list and its
content_sha256 passed as --reviewed-plan-digest.
uv run python -m scripts.dev.prepare_open_issue_contracts \
--audit-json /tmp/open_issue_audit.json \
--plan-json /tmp/open_issue_preparation_plan.json \
--batch-id <stable-batch-id>See docs/ai/open-issue-contract-preparation.md
for the operator contract. Focused offline tests live in
tests/dev/test_prepare_open_issue_contracts.py.
ready_triage_reconcile.py repairs the contradictory
state:ready + needs-triage pair on open issues (issue #9012): report mode
derives one evidence-backed action per issue from its classification with the triage
label ignored, and apply mode performs only the planned label removal with a
per-issue drift check. It never closes issues, merges pull requests, or edits
Project #5 state.
uv run python scripts/dev/ready_triage_reconcile.py --json
uv run python scripts/dev/ready_triage_reconcile.py --apply --jsonFocused offline tests live in tests/dev/test_ready_triage_reconcile.py.
goal_autopilot_controller.py is the
machine-checked parent arbiter for the continuous implement/review/merge/
discover loop. Child workers may report only lane-local exhaustion, such as
implementation_queue_exhausted; only the parent can emit
genuine_zero_work. A terminal result includes a fresh
goal_autopilot_zero_work_proof.v1 receipt bound to the origin/main SHA,
issue/claim state, PR heads, preparation audit, and discovery inputs.
uv run python scripts/dev/goal_autopilot_controller.py \
--snapshot /tmp/goal_autopilot_controller_snapshot.json --jsonThe arbiter routes merge, review, recovery, implementation, readiness-gate,
formalization, and discovery work before considering a terminal result. Focused
regression coverage lives in tests/dev/test_goal_autopilot_controller.py.
- Required automatic enforcement belongs in an explicit workflow or readiness entry point and must have a corresponding contract test.
- Issue-scoped verification requires explicit authoritative arguments and is run only from the relevant work packet.
- Repository-administration audits are read-only evidence collectors; they do not become merge gates by implication.
worktree_receipt.py is the opt-in pre-write boundary for repository-owned delegated workers.
Pair create_worktree.sh --receipt PATH --task-id ID with --exec; creation writes an atomic
receipt and checks it before launching the command. The check is read-only, fail-closed, and
machine-readable. It validates the current working directory, assigned absolute worktree, linked
Git common directory, branch/ref, and base ancestry. Human callers that omit receipt options retain
the ordinary path.
Receipts may additionally declare the issue's path scope with repeated
--allowed-path GLOB (recorded at creation, enforced at check time). With a scope declared,
check also rejects cross-scope changes before commit/push or at the handoff boundary: branch
commits on the first-parent line touching paths outside the scope (intentional current-main merge
commits are exempt) and staged or untracked paths outside the scope. Without a scope the check keeps
its identity-only behavior, so existing receipts and human callers are unaffected (issue #9115).
Use create_worktree.sh --mode review for review-only or synthetic-integration work. It installs
the worktree-local push guard, inert push destinations, and push-only URL rewrites;
review_worktree_guard.py integrate then performs an aborting no-commit merge, restores
ORIG_HEAD, and compares all remote refs before returning success. Review mode separates push
rejection from read operations, keeping direct git fetch and git ls-remote commands operational.
If the selected base predates the guard files, the creator temporarily uses the invoking checkout's
tracked hook and guard; keep that checkout available for the review worktree's lifetime. The barriers
cover ordinary Git invocation paths, but are not an operating-system sandbox: a deliberate per-command
Git configuration override can bypass them. In particular, a remote added after activation with an
explicit remote.<name>.pushurl remains protected by the ordinary hook path, while a deliberate
--no-verify bypass must use the stronger process boundary described below.
Review setup never edits the shared config to mask url.*.pushInsteadOf entries. If an effective
repository, global, system, or pre-existing worktree alias could outrank the worktree push barrier,
setup fails closed before enabling review mode; remove or relocate the alias and retry. A
guard-specific lock would not serialize arbitrary Git processes in other linked worktrees. Read-side
url.*.insteadOf rewrites remain enabled for safe configurations.
For the stronger adversarial contract, run the complete command as a descendant of the guard:
python scripts/dev/review_worktree_guard.py run \
--worktree <review-worktree> -- \
git -c url.<actual-file-url>.insteadOf=<blocked-file-url> push \
--no-verify --receive-pack=git-receive-pack origin HEAD:refs/heads/exampleThis run path installs Linux Landlock application binary interface (ABI) 4+ before exec: reads
and execution remain available, filesystem mutation is allowed only in the review worktree and
linked Git admin directory, inherited file descriptors are closed, and TCP bind/connect is denied.
It fails closed when that policy cannot be installed. This is a Linux-only process boundary for
local filesystem remotes, not a portable all-host guarantee. It does not attach to the directory,
so commands launched later from another terminal or raw Git invocations outside run are outside
the contract; use run -- ... bash for a bounded session. Landlock's policy also deliberately
excludes remotes inside its writable roots, Unix-domain/existing privileged helper channels, and
privileged host escapes.
The creation helper clears copied per-worktree configuration before applying the requested mode, so
an implementation worktree created from a protected review checkout remains independently
pushable. Implementation worktrees keep the default pushable behavior. See
worktree_lifecycle.md for the complete invocation and
restoration procedure.