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.

alice/invoices › branchscope.json
{
  "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.

alice/invoices › Changes › #7

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.

alice/invoices › PLAN.md
# 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.

ci · review
$ bscope change review 7 --wait --fail-on deny
#7 Add invoice creation: review of 1a2b3c4d → 9c1d22a0
1 rule violation, 1 needing review, 0 against the plan.
Breaks controllers-no-data
InvoicesController.Create() uses BillingDbContext InvoicesController.cs:20
bscope: #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.