Did this patch make your architecture better or worse?
PatchCourt reviews the architectural impact of C++ changes, separates new risk from legacy debt, and produces evidence down to files, include/import edges, layers, public contracts, findings, runtime-risk signals, and review questions.
Large C++ systems rarely lose architecture in one dramatic commit.
They drift one patch at a time:
API code starts including vendor-specific implementation headers.
Domain code pulls infrastructure details.
Public interfaces change without related tests.
Old dependency cycles become “it has always been like that”.
Reviewers cannot tell whether the patch introduced new risk or only touched old debt.
Most dependency tools show the whole existing architecture mess.
PatchCourt focuses on the patch:
What got worse?
What got better?
What was already legacy debt?
Where exactly is the evidence?
What should the reviewer inspect first?
PatchCourt is not a compiler, clang-tidy replacement, generic linter, security scanner, or AI reviewer.
It is a deterministic evidence engine for architecture review.
project facts
-> dependency graph
-> architecture rules
-> patch diff
-> findings
-> review bundle
-> local viewer / JSON / LLM context / SARIF
PatchCourt answers one review question:
Did this C++ patch make the architecture better or worse?
And it answers with structured evidence:
| Signal | Example |
|---|---|
| New forbidden dependency | api -> cameras/sony |
| New layer edge | domain -> infrastructure |
| Public contract changed | method::ICameraAdapter::RunPreflight |
| Missing test-like changes | public interface changed, tests did not |
| Runtime architecture risk | this captured into async callback |
| Existing debt | old cycle was already present before the patch |
| Better change | forbidden dependency removed |
The key split:
Worse -> introduced or amplified by this patch
Better -> improved by this patch
Unchanged debt -> already existed before this patch
That split is the product.
git clone https://github.com/orurh/PatchCourt.git
cd PatchCourt/core/go
make build
make viewer-buildRun a lightweight project check with default/auto-discovered configuration:
./bin/patchcourt check . --out .patchcourt/out/checkOr through Makefile:
make check PROJECT=. CONFIG=CONFIG= intentionally disables an explicit .patchcourt.yaml and lets PatchCourt use default/auto-discovered configuration.
The easiest review workflow is the local viewer:
cd PatchCourt/core/go
./bin/patchcourt open . \
--base origin/main \
--worktree \
--review-nowPatchCourt starts a local API/viewer server and creates an initial review bundle.
By default it tries to find built viewer assets automatically:
./viewer-dist
viewer-dist next to the patchcourt binary
web/viewer/dist in development checkout
For headless use:
./bin/patchcourt open . \
--base origin/main \
--worktree \
--review-now \
--no-browserUseful API checks while the server is running:
curl -s http://127.0.0.1:8787/api/health
curl -s http://127.0.0.1:8787/api/reviews/latest/graph | jq '{nodes: (.nodes | length), edges: (.edges | length)}'PatchCourt can write a self-contained review bundle:
./bin/patchcourt review \
--base origin/main \
--worktree \
--root . \
--out .patchcourt/out/latestThe bundle contains:
manifest.json
review.json
project-before.json
project-after.json
graph.json
runtime.json
tree.json
findings.json
contracts.json
dependencies.json
review-context.md
patchcourt.sarif
This bundle is the source of truth for the local viewer and integrations.
The old static-HTML-first workflow is no longer the primary path. The current product direction is bundle/data-first + local viewer.
Build a release archive with the binary and viewer assets:
cd core/go
make release-archive RELEASE_VERSION=v0.2.2-alphaExpected archive structure:
patchcourt-v0.2.2-alpha/
patchcourt
viewer-dist/
index.html
assets/...
After unpacking:
./patchcourt open /path/to/project --review-nowNo manual --viewer-dir should be needed for release archives.
Run the demo:
cd core/go
make camera-demoThe demo generates bad/better review outputs under:
.patchcourt/out/examples/camera-service/
Current bundle-oriented demo artifacts include:
bad-review.txt
bad-review.md
bad/review.json
bad/review-context.md
bad/patchcourt.sarif
better-review.txt
better-review.md
better/review.json
better/review-context.md
better/patchcourt.sarif
Open the old static demo reports only if they are present in your checkout:
make open-camera-demo| Artifact | Purpose |
|---|---|
manifest.json |
Bundle manifest and schema version |
review.json |
Machine-readable PatchCourt review result |
project-before.json |
Before-project model |
project-after.json |
After-project model |
graph.json |
Review graph for the local viewer |
tree.json |
Project tree for the local viewer |
runtime.json |
Runtime architecture risk report |
findings.json |
Finding changes and evidence |
contracts.json |
Public contract changes and impact |
dependencies.json |
Dependency and layer-edge changes |
review-context.md |
Deterministic LLM-ready context pack |
patchcourt.sarif |
CI/code scanning export |
SARIF is an integration layer. The primary PatchCourt artifact is the review bundle.
PatchCourt prepares a deterministic context pack for LLM-assisted review:
review-context.md
It contains:
patch summary
raw changed files
analyzed changed files
touched layers
architecture impact
contract changes
dependency changes
finding changes
runtime risks
risk reasons
review questions
Principle:
LLM may summarize, explain, and generate review questions.
LLM must not invent files, symbols, dependencies, or findings.
PatchCourt collects facts first. LLM assistance should work on top of evidence.
PatchCourt writes SARIF into the review bundle:
.patchcourt/out/latest/patchcourt.sarif
Minimal CI flow:
name: PatchCourt
on:
pull_request:
push:
branches: [main]
permissions:
contents: read
security-events: write
jobs:
patchcourt:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Run PatchCourt review
run: |
patchcourt review \
--base origin/main \
--head HEAD \
--root . \
--out .patchcourt/out/latest
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: .patchcourt/out/latest/patchcourt.sarif
- name: Upload PatchCourt artifacts
uses: actions/upload-artifact@v4
with:
name: patchcourt-review-bundle
path: .patchcourt/out/latestMore examples:
core/go/docs/ci/github-actions.md
core/go/docs/ci/gitlab-ci.md
Recommended alpha behavior:
generate review bundle
upload SARIF where supported
upload review artifacts
do not fail CI by default
Blocking mode should be explicit and project-owned.
PatchCourt can inspect the current project architecture:
./bin/patchcourt check /path/to/project --out /path/to/project/.patchcourt/out/checkTypical artifacts:
project-model.json
scan.md
layer-graph.json
layer-graph.dot
layer-graph.mmd
Use this for:
understanding project structure
finding suspicious layer edges
generating dependency graphs
building an initial baseline config
Explain a concrete layer dependency:
./bin/patchcourt edge \
--model .patchcourt/out/check/project-model.json \
api camerasExample output shape:
PatchCourt edge
Edge: api -> cameras
Count: 3
Top source files:
src/api/camera_routes.cc
Top target files:
src/cameras/sony/sony_camera_manager.h
Dependencies:
src/api/camera_routes.cc
-> src/cameras/sony/sony_camera_manager.h [used]
Graphs are useful. Evidence is better.
PatchCourt can run without a config first.
./bin/patchcourt check . --out .patchcourt/out/check
./bin/patchcourt review --base origin/main --worktree --root . --out .patchcourt/out/latestUse .patchcourt.yaml when the project wants explicit architecture policy.
Example:
ignore:
paths:
- build/**
- cmake-build-*/**
- third_party/**
- external/**
- generated/**
- "**/*.pb.cc"
- "**/*.pb.h"
cpp:
compile_commands:
auto_discover: true
include_paths:
- src
- include
layers:
api:
paths:
- src/api/**
- src/server/**
may_depend_on:
- controllers
- domain
controllers:
paths:
- src/controllers/**
may_depend_on:
- domain
- cameras
domain:
paths:
- src/domain/**
may_depend_on: []
cameras:
paths:
- src/cameras/**
may_depend_on:
- domain
forbidden_imports:
- from_layer: api
patterns:
- src/cameras/sony/**
- src/cameras/*_impl/**Generate a starting config:
./bin/patchcourt init /path/to/project > /path/to/project/.patchcourt.yamlFor legacy projects, start with report-only review and add policy gradually.
| Area | Status |
|---|---|
| C++ file indexing | works |
| C++ include graph | works |
compile_commands.json discovery |
works |
| configured include paths | works |
| Go import baseline | works |
layer rules via .patchcourt.yaml |
works |
| architecture findings | works |
| edge drill-down | works |
| before/after review | works |
| git base/head review | works |
| worktree review | works |
review bundle output via --out |
works |
local viewer via patchcourt open |
alpha |
| viewer asset auto-discovery | alpha |
| project tree / architecture graph viewer | alpha |
| public contract diff | alpha |
| runtime architecture risk signals | alpha |
| LLM context pack | alpha |
| SARIF export | alpha |
PatchCourt is not:
a C++ compiler frontend
a clang-tidy replacement
a proof of correctness
a generic security scanner
a Go linter replacement
a full AI code reviewer
a SaaS product in the current alpha
PatchCourt is:
a deterministic architecture-impact reviewer for patches
PatchCourt is alpha-stage software.
Current limitations:
- C++ analysis is lightweight and does not use Clang AST yet.
- Include resolution quality depends on
compile_commands.json, project layout, or.patchcourt.yaml. - CMake lightweight extraction is not a full CMake evaluator.
- Public contract extraction is heuristic.
- Runtime risk rules are intentionally conservative and evidence-first.
- Risk score is review prioritization, not a correctness verdict.
- SARIF is an export/integration layer, not the core PatchCourt model.
- Go support is baseline-level and not the main product focus.
- False positives are possible and should be reviewed with the provided evidence.
v0.2.2-alpha focuses on making the bundle/viewer workflow usable:
review bundle via --out
local viewer via patchcourt open
automatic viewer-dist discovery
release archive with binary + viewer-dist
full review graph in open --review-now
SARIF and LLM context generated as bundle artifacts
make release-check
make release-archive
Not included in this release:
mandatory Clang backend
VS Code extension
SaaS/web platform
GitHub PR bot as the main workflow
deep cache
suppressions UI
broad Go/C++ risk-rule expansion
AI architect behavior
From core/go:
make help
make ci
make viewer-build
make camera-demo
make open-self-nobrowser OPEN_REVIEW_NOW=true BASE=origin/main
make release-check
make release-archive RELEASE_VERSION=v0.2.2-alphaArchitecture guardrails are enforced by tests.
Core/usecase/analyzer packages return structured results and must not write directly to stdout/stderr.
Apache-2.0.