Skip to content

Let an Operational Repository Commit in Place Through a Repo Agent Policy - #3889

Merged
ptr727 merged 4 commits into
developfrom
feature/agent-policy-guard-section
Nov 5, 2026
Merged

ptr727 merged 4 commits into
developfrom
feature/agent-policy-guard-section

Conversation

@ptr727

@ptr727 ptr727 commented Nov 5, 2026

Copy link
Copy Markdown
Owner

Summary

The standard for an operational repository is a direct commit to develop in place, in the live checkout the running service reads. Both the maintainer and an agent work this way. The write guard's primary-checkout rule (requirement 6) denied that commit. The only way around it was GH_WRITE_GUARD_ALLOW_PRIMARY_CHECKOUT, which lifts every rule-6 denial for the whole session, including reset, stash and clean.

This PR adds a narrow exemption for each repository, recorded in a repo-local agent policy file. That file also holds the review policy that already existed.

  • One policy file per repository. .github/pr-review.json becomes .github/agent-policy.json.
    • Its current contents move under a review section, and a new guard section sits beside it.
    • The spec files are renamed to spec/agent-policy.schema.json and spec/agent-policy.default.json.
    • No repository carries the old file yet, so nothing downstream has to move.
    • Each section stands on its own. A file with no review section reads the hub default's review, and backlog_metrics marks it (default).
  • The guard exemption. The setting is guard.primaryCheckout.commitInPlace.branches.
    • The guard reads it from origin/main only, never from the working tree or develop. An agent can push develop directly in an operational repository, so reading it there would let an agent grant itself the exemption. Reading it from main means only the maintainer's merge grants it.
    • A missing ref, a missing file, or a malformed section means no exemption.
  • What the exemption allows, on a listed branch:
    • add, rm and mv of explicit paths. An add path cannot be a directory or a run-time word.
    • A commit that names no pathspec and carries no -a, -p, -i, -o or --amend, nor any of their long forms.
    • An unforced push of that branch to origin.
    • It never applies when the same command switches branch.
    • Everything else rule 6 denies stays denied, and requirement 4 still judges every push.
  • The rule text says the same thing. That covers GOVERNANCE.md "Operational Repositories" and "Repository Boundaries and Write Safety", the branching-and-release-model and repo-worktree skills, the host-wide safety block, and agent-safety requirement 6.
  • The hook-bypass check is fixed too. _skips_hooks now shares one commit-option reader with the exemption. That fixes a latent bug: a short cluster ending in an attached value, such as -minit, used to skip the word that followed it.

Not in this PR: provisioning the file. repo-config/configure.sh will write .github/agent-policy.json from the registry, with workflowModel: operational filling in the guard section. That lands in the follow-up provisioning PR on the review-cutover track. Until it does, an operational repository needs the file merged to main by hand for the exemption to take effect.

Verification

  • gh-write-guard.py --selftest passes.
    • The new cases cover both what the exemption allows and the shapes it must deny.
    • A new live case builds a real repository. It checks that a policy only in the working tree, or committed on develop with origin/main not yet moved, gives no exemption. It checks that origin/main listing develop does, that a real directory add is denied, and that a malformed policy gives none.
    • A copy of the guard that reads HEAD: instead of origin/main fails the live case.
  • A separate end-to-end probe in throwaway repositories ran the hook's JSON through the guard. It allowed add and commit on develop while main carried the policy. It denied the same commands on a topic branch, and again once the policy left main.
  • The full unittest suite passes: 3545 tests, 11 skipped. So do spec/validate.py, the installer tests, build_dist.py --check and the pre-commit gate.
  • local-strict-review ran three passes:
    • Round one raised 11 findings. Ten are fixed, and one is declined: an add of a directory created earlier in the same command can only sweep in files that command made, so the hardening rule declines it.
    • Round two raised five findings, all fixed.
    • Round three raised none.

Closes #3200

🤖 Generated with Claude Code

ptr727 and others added 3 commits November 5, 2026 10:59
…licy

An operational repository's standard is a direct commit to develop in the
live checkout its service reads, by the maintainer and an agent alike. The
write guard's primary-checkout rule denied that, leaving only a session-wide
override that also lifts reset, stash, and clean.

The per-repository review policy becomes one agent policy file,
.github/agent-policy.json, with a review section and a guard section. The
guard reads its section from origin/main, so only the maintainer's merge
grants an exemption, and a listed branch allows explicit-path add, rm, and
mv, a commit that stages and amends nothing, and an unforced push of that
branch. Everything else the rule denies stays denied. The review reader
reads its own section, and a file without one reads the hub default.

Closes #3200

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A commit with a pathspec, a push carrying a tag or an unread refspec, a
branch switch earlier in the same command, and an add of a directory named
through a drive or home spelling each passed the exemption. Each now denies.
A move into a directory is allowed, the policy read is tested against a real
repository, and a file stating only a guard section reads as the review
default in the backlog metrics.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A short cluster ending in an attached value, such as -minit, skipped the next
word, so a pathspec or a -n after it went unread. The live self-test now
tells a read of origin/main from a read of HEAD and skips rather than fails
where it cannot commit, and the spec states the commit shapes the code denies.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings November 5, 2026 19:23
@coderabbitai

coderabbitai Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@ptr727

ptr727 commented Nov 5, 2026

Copy link
Copy Markdown
Owner Author

A recorded local strict-review pass covers head ce32cfe6f78445d00f834c7503fdbe06b4d7d7dd, the content this pull request carries at that commit against develop, and it recorded 0 findings.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Four active findings remain, including three critical issues that could allow malformed policy data, an unverified local ref, or ambiguous push targets to bypass the guard.

4 open issues
What changed in this PR

This pull request consolidates repository review settings into .github/agent-policy.json and adds a narrowly scoped, main-controlled exemption for operational repositories committing in place.

Changes:

  • Replaces the standalone review policy with unified review and guard policy sections.
  • Adds constrained primary-checkout support for approved staging, commit, and push operations.
  • Updates the guard, schemas, tests, governance documentation, skills, generated distributions, and digests.
  • The review identified four unresolved findings: three critical P1 issues concerning policy validation, local origin/main trust, and explicit push refspecs; and one moderate P2 issue involving option scanning after --.
File Description
tests/​test_pr_review_policy.py Updates review-policy tests for the unified policy file.
tests/​test_backlog_metrics.py Updates backlog metrics tests for the renamed policy structure.
spec/​pr-review.schema.json Removes the superseded review-only schema.
spec/​pr-review.default.json Removes the superseded review-only default.
spec/​agent-policy.schema.json Defines the combined review and guard policy schema.
spec/​agent-policy.default.json Provides the unified default policy.
scripts/​README.md Documents the unified policy location and fallback behavior.
scripts/​pr_review_policy.py Reads review settings from the unified policy with default fallback.
scripts/​backlog_metrics.py Reports review settings from the unified policy.
host-setup/​agent-safety/​README.md Documents the primary-checkout exemption contract.
host-setup/​agent-safety/​claude/​gh-write-guard.py Implements policy-controlled in-place Git operations and shared option parsing.
host-setup/​agent-safety/​claude/​claude-md-safety.md Updates host safety guidance for operational repositories.
GOVERNANCE.md Documents operational in-place commits and policy authorization.
docs/​pr-reviewer-reference.md Updates reviewer-policy references.
.github/​skills/​repo-worktree/​SKILL.md Documents the operational checkout exception.
.github/​skills/​pr-review-conduct/​SKILL.md Updates the review-policy path.
.github/​skills/​branching-and-release-model/​SKILL.md Documents in-place operational commits.
.github/​copilot-instructions.md Updates review-policy references.
.claude-plugin/​fleet-skills/​skills/​repo-worktree/​SKILL.md Regenerates distributed worktree guidance.
.claude-plugin/​fleet-skills/​skills/​pr-review-conduct/​SKILL.md Regenerates distributed review guidance.
.claude-plugin/​fleet-skills/​skills/​branching-and-release-model/​SKILL.md Regenerates distributed branching guidance.
.claude-plugin/​fleet-skills/​.source-digests/​repo-worktree Updates the generated worktree Skill digest.
.claude-plugin/​fleet-skills/​.source-digests/​pr-review-conduct Updates the generated review Skill digest.
.claude-plugin/​fleet-skills/​.source-digests/​branching-and-release-model Updates the generated branching Skill digest.
.agents/​skills/​repo-worktree/​SKILL.md Updates the authored worktree Skill.
.agents/​skills/​pr-review-conduct/​SKILL.md Updates the authored review-conduct Skill.
.agents/​skills/​branching-and-release-model/​SKILL.md Updates the authored branching-model Skill.

Review effort: Lite

@codecov

codecov Bot commented Nov 5, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 25.92593% with 80 lines in your changes missing coverage. Please review.
✅ Project coverage is 77.52%. Comparing base (b38e084) to head (0a8c192).
⚠️ Report is 104 commits behind head on develop.

Files with missing lines Patch % Lines
host-setup/agent-safety/claude/gh-write-guard.py 12.08% 80 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #3889      +/-   ##
===========================================
- Coverage    81.60%   77.52%   -4.09%     
===========================================
  Files           26       33       +7     
  Lines         9070    11736    +2666     
===========================================
+ Hits          7402     9098    +1696     
- Misses        1668     2638     +970     
Flag Coverage Δ
python-3.13 77.52% <25.92%> (-4.09%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

…ption

A bare push follows configured push defaults and can update other branches,
so the exemption now takes only git push origin <branch>. A policy whose
version is not 1 grants nothing, a commit carrying -- is denied, and the
hook-bypass scan stops at --. The Windows-path self-test skips the new live
case, which builds a real checkout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@ptr727

ptr727 commented Nov 5, 2026

Copy link
Copy Markdown
Owner Author

A recorded local strict-review pass covers head 0a8c1927ae481cc80f9d6387d550131698cfef9f, the content this pull request carries at that commit against develop, and it recorded 0 findings.

@ptr727
ptr727 merged commit 30a7cf7 into develop Nov 5, 2026
13 checks passed
@ptr727
ptr727 deleted the feature/agent-policy-guard-section branch November 5, 2026 20:02
ptr727 added a commit that referenced this pull request Nov 5, 2026
… Bot Settings (#3891)

## Summary

`repo-config/configure.sh` now renders each repository's
`.github/agent-policy.json` from `registry/repos.json`, through the new
`scripts/agent_policy.py`. It also applies and checks the bot-side
settings the render implies. This is step 1 of the review-cutover track
(#3877), built on the `agent-policy.json` shape #3889 introduced.

- **Render.** The hub default policy, plus a repo entry's optional
`agentPolicy` override (a shallow merge per bot), plus a `guard` section
derived from `workflowModel`. An operational repository lists `develop`.
`spec/validate.py` refuses a malformed override.
- **Rulesets.** The `copilot_code_review` rule lands on the `main` or
`develop` ruleset only where the render has an automatic Copilot
covering that branch. `repo-config/main.json` stays the template for the
rule's parameters.
- **`apply --checkout <path>`.** Writes three things into a local
checkout of the repository: the policy file, CodeRabbit's
`reviews.auto_review.enabled` and `base_branches`, and Qodo's `[config]
disable_auto_feedback`. Every other key and comment is kept. A dry run
checks the checkout before any API write. The caller commits the files
through the ordinary PR flow.
- **`check`.** Compares all three files on the default branch with the
render. A missing bot file is drift by design: once account-level auto
review turns off, a repository without the explicit keys would lose its
reviews silently.
- **Requirements.** A plain `apply` or `check` derives the facts with
the stdlib interpreter, now probed for 3.10. `uv` is needed only for
`apply --checkout` and the policy check.

## What to expect after merge

- `configure.sh check` reports agent-policy drift on every repository
until `apply --checkout` has been run there and the files merged. Today
only this hub carries `.coderabbit.yaml` and `.pr_agent.toml`. That
rollout is the pilot step on #3877.
- On this hub, `apply --checkout` leaves `.coderabbit.yaml`
byte-identical. It adds `[config] disable_auto_feedback = false` to
`.pr_agent.toml` and writes `.github/agent-policy.json`.

## Local review

Three recorded `local-strict-review` passes, at `frontier`. The first
found 8 findings and the second found 3. All were fixed except one
consolidation in a file this change does not touch, filed as #3890. The
third pass, over the final content, found none.

## Pre-existing findings, not filed

- `spec/host-tools.json:90` (`pre-existing`): the `why` string says
`removesuffix` is called "in spec/audit.py alone", while
`scripts/carry.py` and the host-setup scripts call it too. This is a
description, not an instruction, and is left as it is.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
ptr727 added a commit that referenced this pull request Nov 6, 2026
…t Policy (#3892)

## Summary

Promotes #3881, #3884, #3886, #3888, #3889, and #3891 to `main`.

Closes #3200.
Closes #3885.
Closes #3887.

- **Per-repository review policy (#3881).** `scripts/pr_review.py` reads
which bots review a repository, on which bases, when, and how often,
from the repository's own policy, with the hub default reproducing
today's behavior.
- **Review return on cost (#3886).** `scripts/backlog_metrics.py`
measures reviewer cost per useful finding. It is now a uv script, so the
metrics server's weekly timer must run it as `uv run --no-project
--script scripts/backlog_metrics.py` from this release on.
- **After-checks side reviewer (#3888).** An explicit after-checks
CodeRabbit or Qodo is asked once CI settles, and ask times compare in
UTC.
- **Commit in place for an operational repository (#3889).** The policy
file became `.github/agent-policy.json`, with its schema under `review`
and a `guard` section that lets `gh-write-guard` allow an in-place
commit on a listed branch.
- **Agent policy rendered from the registry (#3891).**
`repo-config/configure.sh` renders `.github/agent-policy.json` from
`registry/repos.json` and applies the bot settings it implies: the
Copilot ruleset rule, CodeRabbit's auto-review keys, and Qodo's
auto-feedback key. Once this is on `main`, `configure.sh check` reports
agent-policy drift on every repository until `apply --checkout` has been
run there.
- **Dependabot (#3884).** The actions-deps group bump.

Each feature pull request carried recorded local strict review passes,
with every finding fixed, declined with evidence, or filed (#3890).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants