Can we require more evidence for changes to critical code, and enforce it in
CI without a hosted service? Yes. Rules in .repowise/policies.yaml select
components by name, tag or criticality and test the change's
evidence checklist.
repowise check evaluates them locally or in CI and writes a table, JSON,
SARIF or JUnit. Nothing is sent anywhere.
# .repowise/policies.yaml
version: 1
rules:
- name: payments-need-tests
match:
components: {tags: [pci]} # also names, criticality; each list is any-of
when:
reaching_tests: missing # a changed file in scope has no reaching test
action: require_tests
- name: agent-changes-to-critical-code
match:
components: {criticality: [critical]}
when:
attribution: agent
action: require_owner_review
- name: no-silent-contract-breaks
when:
contract_break: true
action: fail
- name: no-new-secrets
gate: security
with: {fail_on: high}
action: failWhat a rule can test
A rule selects components (match,
exclude), then tests conditions that must all hold (when), and names an
action.
| Condition | Values | Read from |
|---|---|---|
attribution | agent, human_attested, unknown | AI attribution on the change's commits |
agent_tier | 1 near-autonomous, 2 human-driven, 3 assisted | The autonomy tier of an agent commit's marker |
reaching_tests | missing, present | Tests that reach the changed files, measured or inferred |
contract_break | true, false | A breaking change to a contract the change touched |
decision_crossed | true, false | An accepted decision governs a changed file |
bus_factor_below | a whole number, 1 or more | The bus factor of a touched component |
There is no risk-score condition. Rules rest on evidence a reviewer can check, not on a statistic.
A rule can also wrap an existing gate (security, coverage, doc_drift or
health) with that command's options under with. It runs exactly as the
command does on its own, and doc_drift is scoped to the change unless the
rule says otherwise.
| Action | Effect |
|---|---|
warn | Reported |
require_owner_review | Reported as a requirement; advisory |
require_tests | Reported as a requirement; advisory |
fail | Reported, and repowise check exits 1 |
Evidence that is not there
A condition whose evidence is not available (no index, attribution turned off) leaves the rule not evaluated, and it never fires. The report lists it as not evaluated, so a missing input is visible and never reads as a pass or a failure.
Running it
repowise check main..HEAD
repowise check main..HEAD --sarif-file policy.sarif --junit-file policy.xml
repowise check --format json > check.jsonWith no revspec it reads the CI change (the pull request's target branch
...HEAD), the same way the other gates do. --sarif-file and
--junit-file write both reports from one run.
| Exit code | Meaning |
|---|---|
0 | No fail rule fired |
1 | A fail rule fired |
2 | The policy is invalid (every problem is listed), or a fail gate could not be evaluated |
SARIF 2.1.0 feeds GitHub code scanning or reviewdog. JUnit shows up in any CI test view. See Gates in CI for wiring the gates into a pipeline.
Using OPA
Teams that already write Rego can use the evidence object of
repowise check --format json as OPA input. It is the change's evidence
checklist, one item per kind (components_touched, provenance,
reaching_tests, decisions_crossed, contracts) with its status, basis and
per-file details.
repowise check main..HEAD --format json > check.json
opa eval --input check.json --data policy.rego 'data.repowise.deny'Rego rules then read input.evidence.items next to, or instead of,
policies.yaml.
Limits
require_owner_reviewandrequire_testsare advisory: they are reported in every format and the command still exits 0. Usefailto block.- A policy reads what the index knows. Reviews and approvals are not in git, so a rule cannot test whether a review happened.
- Gate rules re-run the gate.
repowise report changesreports the condition rules' verdict per change but does not re-run gates. - An unknown key, condition or gate option, a bad action or a duplicate rule name makes the policy invalid (exit 2).