Overview
vg scan answers how far behind is the stack? Vibgrate Review answers a
different question about the same repository:
Did this change move the system toward its declared architecture, weaken a security control, or create an implication the author did not account for?
It answers it locally, from the Vibgrate Graph, with deterministic
scanners and a policy-owned decision. The result is a versioned receipt
(vg.review.receipt.v1) that can stay on disk or be pushed to
Vibgrate Cloud and shown commit by commit.
AI coding agents write changes faster than anyone can judge their architectural consequences. Review is the layer that reads the change the way a senior reviewer would — before the pull request, not after the incident.
Usage
vg review # the working tree + index, vs HEAD
vg review --base origin/main # merge-base of HEAD and the base branch
vg review explain arch-01 # the evidence behind one finding
Review reads the code map. If there isn't one, vg review builds it first and
shows a progress bar; if the map has drifted from the working tree, it refreshes
it incrementally. Pass --no-auto-build to turn that off — then a missing or
stale map exits 6, never 0.
The first run in a repository with no .vibgrate/review.toml also writes a
starter one, seeded with the layering shape the repository already exhibits, and
tells you it did. It is written after the review, so it never lands in the change
set being reviewed; it is enforcement = "advisory", so it cannot turn a green
build red; and --base runs skip it, so a pull request review never writes to
the tree. Pass --no-setup to turn that off too.
Options
| Flag | Default | Description |
|---|---|---|
--base <ref> | — | Review HEAD against the merge-base with <ref> |
--format <fmt> | text | text, json (the receipt), sarif (security findings only), md |
-o, --out <file> | — | Write the formatted result to a file |
--push | off | Send the receipt to Vibgrate Cloud (needs a DSN) |
--fail-on <level> | fail | fail, or needs_review to gate on that too |
--explain | off | Add local-model explanations. Requires a local model; fails closed without one |
--include-spans | off | Include evidence line ranges in the pushed receipt |
--include-snippets | off | Include capped source snippets in the pushed receipt |
--no-auto-build | — | Don't build or refresh the code map; exit 6 when it is missing |
--no-setup | — | Don't write a starter .vibgrate/review.toml |
Decisions
Policy owns the decision, and it is the only layer that writes one. Findings — from the scanners, or from the optional local model — have nowhere to put a verdict.
| Decision | Exit | Meaning |
|---|---|---|
pass | 0 | No material delta, or every finding is target-aligned |
fail | 1 | An unresolved protected finding, or a high-severity finding above the confidence threshold |
needs_review | 2 | Findings a human should look at |
undetermined | 2 | Not enough evidence to decide — deliberately not a pass |
You get needs_review or undetermined instead of a fake pass when the system
does not have enough peers or tests to judge the change. That is the point: a
green tick nobody earned is worse than an honest "I could not tell".
Protected findings
An unguarded entrypoint, a removed guard, a validated taint flow, and a
known-vulnerable dependency are protected. While one is unresolved, policy
cannot emit pass — not through an approved exception, not through low
confidence, not through the quick path, and not through anything a model says.
Turn a rule off in .vibgrate/review.toml if it does not apply to your
repository. That is the only way to stop it gating.
Configuration
# .vibgrate/review.toml
[review]
enforcement = "advisory" # advisory | enforced
fail_on = "fail" # fail | needs_review
target_pattern = "layered" # the architecture you say you want
[review.protected]
unguarded_entrypoint = true
known_vulnerable_dependency = true
validated_taint = true
Read from the trusted base branch when --base is given, so a pull request
cannot weaken the policy applied to itself.
Declaring target_pattern is what turns a layering observation into a
regression. Without it, a dependency that skips a tier is reported as a medium
finding about the repository's own majority — because a majority is not a
decision, and Review will not treat it as one.
In CI
The same binary, the same policy, the same receipt schema as on a laptop.
vg review --base "origin/$BASE_REF" --format json --out review-receipt.json
Review builds the map itself on a cold runner, so a separate vg build step is
optional. Keep one if you want the map build timed and cached as its own CI step.
Start with the default --fail-on fail so only a fail stops the build, and
move to --fail-on needs_review once a repository has opted into enforcement.
--format sarif uploads the security findings to GitHub code scanning.
Architectural findings stay on the receipt and the check summary on purpose:
code scanning is a security surface, and filling it with layering observations
trains reviewers to ignore it.
Privacy
Source stays on your machine. --push sends the receipt — decisions, claims,
evidence ids, paths, digests, versions — never the analysis capsule and never
source text. Line ranges are opt-in with --include-spans; snippets are a
second, explicit opt-in with --include-snippets, and are capped. With no DSN,
the receipt stays local.
What it does not claim
- It does not prove code is secure, correct, or free of vulnerabilities.
- It does not replace Semgrep, CodeQL, a compiler, or your tests.
- It does not govern AI-system fairness or model risk — that is a different category.
- Absence of findings is not a certification.
Related
- vg scan — stack currency, the other half of the picture
- CI integration — wiring the gate into your pipeline