Architecture rules and plans
Your architecture, written down and checked
Say which layers may depend on which in branchscope.json, and what a change means to touch in PLAN.md. Every review checks the change against both, from the code graph, and the same change always gets the same findings.
Layers and rules
Rules that live with the code
A layer selects graph nodes by ID, kind or tag. A rule names the edges from one layer to another that are forbidden (deny) or need a look (review). The file sits at the repository root and is versioned with the code it describes; an invalid one fails the graph build with a message instead of being guessed at.
{
"layers": {
"controllers": { "nodes": ["dotnet:src/Billing.Api|Billing.Api.Controllers*"] },
"data": { "nodes": ["dotnet:src/Billing.Api|Billing.Api.Data*"] },
"tables": { "kinds": ["table"] }
},
"rules": [
{ "id": "controllers-no-data", "from": "controllers", "to": "data",
"edges": ["imports", "references"], "effect": "deny" },
{ "id": "table-writes", "to": "tables",
"edges": ["writes"], "effect": "review" }
]
}Findings
Down to the file and line
A review lists each edge a change makes that breaks a rule, with the file and line, as not allowed or needing review. Breaks that were there before the change are counted, not blamed on it, and code that was only renamed or moved isn't a new break. The target branch's rules apply, so a change can't remove the rule it breaks.
Findings
Breaks controllers-no-data
InvoicesController.Create() uses BillingDbContext
src/Billing.Api/Controllers/InvoicesController.cs:20
Needs review: table-writes
InvoicesController.Create() writes invoices
src/Billing.Api/Controllers/InvoicesController.cs:20
Plans
What a change may touch, and what it mustn't
A branchscope block in PLAN.md names the files, nodes and layers a change touches, and those it must not. The review lists what the plan rules out and what falls outside it, as warnings for the reviewer: they don't fail the review's check, but an agent that strayed from the plan it wrote is plain to see.
# Plan
Add invoice export: an endpoint in the API.
```branchscope
{
"touches": { "files": ["src/Billing.Api/Controllers/**"] },
"mustNotTouch": { "layers": ["data"] }
}
```Plan: outside what it says it touches
src/Billing.Api/Services/TaxService.cs
Required
A broken rule can hold back the merge
Each change's review is the check branchscope/review, failed by a new violation of a deny rule. A ruleset can require it like any other check, and only Branchscope can report it. From a script or an agent, bscope change review --wait --fail-on deny exits with an error code instead.
$ bscope change review 7 --wait --fail-on deny#7 Add invoice creation: review of 1a2b3c4d → 9c1d22a01 rule violation, 1 needing review, 0 against the plan.Breaks controllers-no-dataInvoicesController.Create() uses BillingDbContext InvoicesController.cs:20bscope: #7: 1 rule violation, 1 needing review$ echo $?3
Write your first rule
Add a branchscope.json with two layers and a rule, open a change, and read its findings.