Set a review policy

How-toUpdated 3 min read
View as Markdown
On this page

A review policy decides who must clear each pull request a builder opens: an AI reviewer, a planner, or a person. Set it once for the workspace, and override it for a project when that project needs something stricter.

You need: to be a workspace admin, and a token in $OPVS_PAT for the API calls.

How a pull request is classified

OPVS checks the changed paths (and, for migrations, the diff) against your policy, in this order. The first match wins:

Order

Rule

Level

matched_by

1

No policy set

person

policy absent

2

A path matches levels.person.paths

person

person path

3

levels.person.destructive_migrations is on and the change drops, renames or retypes data

person

destructive migration

4

A path matches levels.planner.paths

planner

planner path

5

A path contains a word in levels.planner.words

planner

planner word

6

levels.planner.sql_files is on and a .sql file changed

planner

SQL file

7

levels.planner.raw_sql is on and the added lines contain raw SQL

planner

raw SQL

8

Anything else

ai

default

With no policy, every pull request needs a person. That is the safe default, not a mistake.

1. Write the policy

In the dashboard: Settings → Review policy for the workspace, or the project's Settings → Review to override it. Path patterns are shell-style (billing/**, *.sql), and a pattern that starts with **/ also matches at the top level. required_checks names the CI checks that must pass before a merge; the workspace's list and the project's list are combined. Over the API:

curl -s -X PUT https://api.opvs.ai/api/v1/projects/<project-id>/review-policy \
  -H "X-Brand-ID: $BRAND_ID" -H "Authorization: Bearer $OPVS_PAT" \
  -H 'Content-Type: application/json' \
  -d '{
    "ai_reviewer_mode": "shadow",
    "ai_graduation": {"rule": "record", "agree_streak": 30},
    "levels": {
      "person":  {"paths": ["billing/**", "auth/**"], "destructive_migrations": true},
      "planner": {"words": ["payment"], "sql_files": true, "raw_sql": true}
    },
    "required_checks": ["test"]
  }'

For the whole workspace, send the same body to PUT /api/v1/brands/<workspace-id>/review-policy.

2. Choose how much the AI reviewer may do

ai_reviewer_mode

The AI reviewer…

forbidden (default)

Does not review

shadow

Reviews, but its verdict does not clear anything. A person or planner still decides

allowed

Clears the pull requests the policy classifies as ai

ai_graduation moves a project from shadow to allowed on its own:

rule

Graduates when

record

The AI reviewer has agreed with the human reviewer agree_streak times in a row (10 to 500, default 30)

date

On on_date (today or later)

never

Never; you switch it by hand

The policy you read back carries effective_ai_reviewer_mode and, for record, graduation_progress (agreeing_in_a_row of needed).

3. Test it before a real pull request

Ask how a set of paths would be classified:

curl -s -X POST https://api.opvs.ai/api/v1/review-policy/classify \
  -H "X-Brand-ID: $BRAND_ID" -H "Authorization: Bearer $OPVS_PAT" \
  -H 'Content-Type: application/json' \
  -d '{"paths": ["billing/charge.py"], "project_id": "<project-id>"}'

The reply has two fields: level (ai, planner or person) and matched_by, from the table above.

Errors

Status

When

What to do

401 Not authenticated. Please log in.

No token sent

Send Authorization: Bearer $OPVS_PAT

422 levels.<level>.paths must be a list of strings

A level's paths or words is not a list of strings

Send a JSON array of strings

422 levels.<level>.<flag> must be a boolean

sql_files, raw_sql or destructive_migrations is not true or false

Send true or false

422 ai_graduation.on_date must be today or later

A date rule in the past

Pick today or a later date

422

agree_streak below 10 or above 500

Use 10 to 500

Related: How a card moves, Projects.

Did this answer your question?