feat(pre-commit): roll pr-guard out by default now that a release carries it #1149

Merged
coilysiren merged 1 commit from fix/pr-guard-default into main 2026-08-20 06:55:13 +00:00
Owner

What

Completes the rollout #1146 could not do at the time.

pr-guard shipped in #1146 but was deliberately kept out of DEFAULT_HOOK_IDS, because the agentic-os#187 guard correctly refuses to list a hook that the pinned release tag does not carry. Doing it anyway breaks every consumer's pre-commit init. That precondition is now satisfied:

aos-precommit-v0.32.0   pr-guard entries=0
aos-precommit-v0.33.0   pr-guard entries=0
aos-precommit-v0.34.0   pr-guard entries=2   <- the hook definition, plus the header example

latest_release_tag() sorts --sort=-v:refname and returns the newest, so default_rev() resolves v0.34.0, which carries the hook. The #187 guard passes with pr-guard in the list.

Until this lands the hook is inert for every consumer that has not named it explicitly, which is the whole point of #1146.

Also: the release paths gap

aos-precommit-release.yml filters on paths and names hook scripts individually, but only scripts/trufflehog-scan.sh was listed. scripts/pr-guard-pre-push.sh was not.

The consequence is delayed rather than immediate. The first release fired fine, because #1146 also touched .pre-commit-hooks.yaml. But once the hook entry is stable, a later fix to pr-guard-pre-push.sh alone touches no listed path, so no release is cut, no tag moves, and every consumer pinned to rev=aos-precommit-vX.Y.Z keeps running the old script with no signal a fix exists. For a hook whose job is guarding pushes to default branches, silently shipping a stale copy is the wrong failure mode.

The test

Rather than fix the one path and leave the class open, tests/test_precommit_release_paths.py asserts the invariant: every scripts/ entry in .pre-commit-hooks.yaml appears in the release paths filter. It is the sibling of #187's rev/hook-list guard, and it fails with the offending hook named.

I audited the existing hooks before writing it, so it is not adding a rule the repo already violates:

pr-guard     scripts/pr-guard-pre-push.sh    MISSING
trufflehog   scripts/trufflehog-scan.sh      in paths

Only pr-guard was the gap. A second small case asserts .pre-commit-hooks.yaml itself stays in the filter, since adding or retiring a hook id must move the tag consumers pin.

Verification

The new test discriminates. Removing the path line and rerunning:

assert not missing
hook scripts absent from the aos-precommit-release paths filter: {'pr-guard': 'scripts/pr-guard-pre-push.sh'}
1 failed, 1 passed

Full suite, same private pytest basetemp both sides:

clean origin/main:  28 failed, 534 passed, 2 skipped
with this branch:   28 failed, 536 passed, 2 skipped

Plus two, exactly the new cases, no regressions. test_default_hook_ids_present_at_default_rev passes with pr-guard in the list. The 28 are pre-existing native-Windows failures, mostly test_statusline.py, that CI does not see.

just pre-commit-all passes clean. One note for anyone reproducing on Windows: shellcheck fails on a fresh clone with SC1017 against .agents/skills/tooling-image-zoom/scripts/crop-image, because .gitattributes pins *.sh to LF but not extensionless scripts. Pre-existing and unrelated, worked around locally with core.autocrlf=input. Worth a .gitattributes line of its own sometime.

closes #1148

🤖 Generated with Claude Code

## What Completes the rollout #1146 could not do at the time. `pr-guard` shipped in #1146 but was deliberately kept out of `DEFAULT_HOOK_IDS`, because the agentic-os#187 guard correctly refuses to list a hook that the pinned release tag does not carry. Doing it anyway breaks every consumer's `pre-commit` init. That precondition is now satisfied: ``` aos-precommit-v0.32.0 pr-guard entries=0 aos-precommit-v0.33.0 pr-guard entries=0 aos-precommit-v0.34.0 pr-guard entries=2 <- the hook definition, plus the header example ``` `latest_release_tag()` sorts `--sort=-v:refname` and returns the newest, so `default_rev()` resolves `v0.34.0`, which carries the hook. The #187 guard passes with `pr-guard` in the list. Until this lands the hook is inert for every consumer that has not named it explicitly, which is the whole point of #1146. ## Also: the release paths gap `aos-precommit-release.yml` filters on `paths` and names hook scripts individually, but only `scripts/trufflehog-scan.sh` was listed. `scripts/pr-guard-pre-push.sh` was not. The consequence is delayed rather than immediate. The first release fired fine, because #1146 also touched `.pre-commit-hooks.yaml`. But once the hook entry is stable, a later fix to `pr-guard-pre-push.sh` alone touches no listed path, so no release is cut, no tag moves, and every consumer pinned to `rev=aos-precommit-vX.Y.Z` keeps running the old script with no signal a fix exists. For a hook whose job is guarding pushes to default branches, silently shipping a stale copy is the wrong failure mode. ## The test Rather than fix the one path and leave the class open, `tests/test_precommit_release_paths.py` asserts the invariant: every `scripts/` entry in `.pre-commit-hooks.yaml` appears in the release paths filter. It is the sibling of #187's rev/hook-list guard, and it fails with the offending hook named. I audited the existing hooks before writing it, so it is not adding a rule the repo already violates: ``` pr-guard scripts/pr-guard-pre-push.sh MISSING trufflehog scripts/trufflehog-scan.sh in paths ``` Only `pr-guard` was the gap. A second small case asserts `.pre-commit-hooks.yaml` itself stays in the filter, since adding or retiring a hook id must move the tag consumers pin. ## Verification The new test discriminates. Removing the path line and rerunning: ``` assert not missing hook scripts absent from the aos-precommit-release paths filter: {'pr-guard': 'scripts/pr-guard-pre-push.sh'} 1 failed, 1 passed ``` Full suite, same private pytest basetemp both sides: ``` clean origin/main: 28 failed, 534 passed, 2 skipped with this branch: 28 failed, 536 passed, 2 skipped ``` Plus two, exactly the new cases, no regressions. `test_default_hook_ids_present_at_default_rev` passes with `pr-guard` in the list. The 28 are pre-existing native-Windows failures, mostly `test_statusline.py`, that CI does not see. `just pre-commit-all` passes clean. One note for anyone reproducing on Windows: shellcheck fails on a fresh clone with `SC1017` against `.agents/skills/tooling-image-zoom/scripts/crop-image`, because `.gitattributes` pins `*.sh` to LF but not extensionless scripts. Pre-existing and unrelated, worked around locally with `core.autocrlf=input`. Worth a `.gitattributes` line of its own sometime. closes #1148 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(pre-commit): roll pr-guard out by default now that a release carries it
All checks were successful
ci / aos-eval-tests (pull_request) Successful in 4s
ci / aos-cli-tests (pull_request) Successful in 19s
ci / ward-doctor (pull_request) Successful in 13s
ci / gate (pull_request) Successful in 52s
ae46563560
pr-guard shipped in #1146 but stayed out of DEFAULT_HOOK_IDS, because the
agentic-os#187 guard correctly refuses to list a hook the pinned release tag
does not carry. aos-precommit-v0.34.0 now carries it, and default_rev()
resolves the newest tag, so the guard is satisfied and the rollout can
include it.

Also add scripts/pr-guard-pre-push.sh to the release workflow's paths
filter. The filter names hook scripts individually, and trufflehog-scan.sh
was the only one listed. Without its script there, a later fix to
pr-guard-pre-push.sh alone would cut no release and move no tag, leaving
every consumer pinned to a tag running the old copy with no signal.

Cover that invariant with a test rather than leaving it to review: every
scripts/ entry in .pre-commit-hooks.yaml must appear in the release paths
filter. Audited the existing hooks first, and pr-guard was the only gap.

closes #1148

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
coilysiren deleted branch fix/pr-guard-default 2026-08-20 06:55:14 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
coilyco-flight-deck/agentic-os!1149
No description provided.