Files
skills/agents
mathiasandClaude Opus 5 0dcf5cc136 feat(pr-gatekeeper): review a staged diff pre-push, for GitOps repos with no PR
infra#470 resolved a doctrine conflict: root rule 5 wants a PR for risk/medium+,
and mathias/infra forbids branches because Flux watches main — a branch there can
be linted but never reconciled, so a PR reviews a state that was never deployed.
The agreed lane is that such work stays on main and gets a recorded adversarial
review pass BEFORE the push.

That lane names this agent as its reviewer, and the definition only knew how to
review an open PR. A lane whose reviewer cannot see the diff resolves to "the
author was careful", which is what rule 5 was written to replace.

ONE AGENT, TWO MODES — NOT A SECOND FILE

Only three of twelve sections were PR-specific: the diff command, the CI step, and
the verdict. Everything else — the iron laws, "the test is the claim", the three
attack habits, probing without causing the incident, escalation — is diff-agnostic.
Forking a near-duplicate 226-line definition would give the estate two
implementations of one review standard, and they would drift; the same argument
tests/litellm-validate_test.sh makes about its own consolidation.

WHAT DIFFERS, AND WHY

- Diff: three commands, run all of them. Which one holds the change is itself
  information — work that is neither staged nor committed is a working tree, not a
  diff under review. Untracked files appear in neither diff, so `git status
  --porcelain` is how a control that exists only in an unstaged file gets noticed.
- CI: it CANNOT have run, nothing is pushed. So "CI absent" must not block here —
  that rule is for a pushed branch with no runs, which is a platform failure;
  unpushed with no runs is arithmetic. Instead run the local gate and check its
  EXIT CODE, because a grep over gate output has hidden a failing test in this
  estate before.
- Verdict: nothing to merge, no PR to close, no branch to delete. The entire output
  is a comment on the issue. That is what makes the lane RECORDED rather than a
  conversation — a verdict living only in a chat transcript is indistinguishable
  from no review having happened.

The report must state that it carries strictly less external evidence than PR mode:
"nothing I could find blocks this push", never "CI confirms this".

TDD, and one vacuous assertion caught

Five assertions written first, all red. One passed spuriously — an unscoped grep
for "do not merge" matched line 202, the ESCALATION step talking about a PR. A pass
for entirely the wrong reason, which is what rule 9 is about. Now scoped to the
pre-push section, and the comment records why, so nobody re-loosens it.

agents_test 19/19. Repo check exit 0, 45 skills, manifest matches tag.

Refs mathias/infra#470

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-30 10:31:31 +02:00
..