Skip to content

Commit f7c165a

Browse files
authored
feat(boundaries): add architecture boundary checks
Add boundary CLI/MCP/check support with presets, custom zones/rules, docs, roadmap sync, and chained tests.
1 parent 0356f15 commit f7c165a

22 files changed

Lines changed: 936 additions & 33 deletions

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ npx codebase-intelligence duplicates ./src --mode mild --min-tokens 30
3131
npx codebase-intelligence impact ./src parseCodebase
3232
npx codebase-intelligence dead-exports ./src --limit 20
3333
npx codebase-intelligence changes ./src --json
34+
npx codebase-intelligence boundaries ./src --preset layered --list --json
3435
```
3536

3637
### MCP (optional)
@@ -57,7 +58,7 @@ claude mcp add -s user -t stdio codebase-intelligence -- npx -y codebase-intelli
5758

5859
## Features
5960

60-
- **23 CLI commands** for architecture analysis, dependency impact, duplicate families, focused map/context packs, content drift, health scoring, Highways convergence, improvement opportunities, dead code detection, search, CI rules, and agent setup
61+
- **24 CLI commands** for architecture analysis, dependency impact, duplicate families, focused map/context packs, content drift, health scoring, boundary enforcement, Highways convergence, improvement opportunities, dead code detection, search, CI rules, and agent setup
6162
- **Machine-readable JSON output** (`--json`) for automation and CI pipelines
6263
- **Auto-cached index** in `.codebase-intelligence/` for fast repeat queries
6364
- **Cache migration facts** in JSON (`cacheDir`, `legacyCacheDir`, `migrated`, `gitignoreUpdated`, `warnings[]`)
@@ -71,7 +72,7 @@ claude mcp add -s user -t stdio codebase-intelligence -- npx -y codebase-intelli
7172
- **Highways analysis** — find repeated routes that bypass canonical dataflow paths and synthesize safe proposed highways
7273
- **Community detection** — Louvain clustering for natural file groupings
7374
- **Agent adoption**`init` writes per-agent instruction files + installs a skill so AI agents query CI before grep/read
74-
- **MCP parity (secondary)** — same analysis and rules gate available as 24 MCP tools, 2 prompts, and 3 resources
75+
- **MCP parity (secondary)** — same analysis and rules gate available as 25 MCP tools, 2 prompts, and 3 resources
7576

7677
## Installation
7778

@@ -117,6 +118,7 @@ codebase-intelligence <command> <path> [options]
117118
| `map` | Focused codebase graph + token-bounded context pack |
118119
| `drift` | Report-only content drift findings with evidence and recommendations |
119120
| `health` | CI-gateable health score with maintainability, CRAP, coverage, and risk hotspots |
121+
| `boundaries` | Architecture boundary zones, allow/forbid import rules, and violation evidence |
120122
| `highways` | Repeated route convergence, canonical path opportunities, and synthesis proposals |
121123
| `clusters` | Community-detected file clusters |
122124
| `check` | Rules-engine gate for CI, including opt-in dead-code and dependency gates |
@@ -139,6 +141,8 @@ codebase-intelligence <command> <path> [options]
139141
| `--context-budget <n>` | Bound `map` context pack size |
140142
| `--min-score <n>` | Minimum drift score for `drift` findings; minimum health score before `health` exits 1 |
141143
| `--score` | Print compact `health` score text |
144+
| `--preset <name>` | Run `boundaries` with `bulletproof`, `layered`, `hexagonal`, or `feature-sliced` |
145+
| `--list` | List resolved `boundaries` zones and rules |
142146
| `--format <fmt>` | Export `map` as `markdown`, `json`, `dot`, or `graphml`; export `check` as `text`, `json`, or `sarif` |
143147
| `--operation <verb>` | Focus `highways` on one operation verb |
144148
| `--shape <name>` | Focus `highways` on one type/DTO shape |

docs/architecture.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Core (shared computation)
2525
| typed descriptors, input schemas, CLI/MCP adapters, result wrappers, text formatters
2626
v
2727
MCP (stdio) CLI (terminal/CI)
28-
| 24 tools, 2 prompts, | 23 commands with text + JSON
28+
| 25 tools, 2 prompts, | 24 commands with text + JSON
2929
| 3 resources for LLMs | output for humans and CI
3030
```
3131

@@ -50,8 +50,9 @@ src/
5050
map/index.ts <- Focused codebase maps + token-bounded context packs
5151
drift/ <- Content drift scoring, profiles, findings, tokens, and stable evidence
5252
health/ <- Health score, maintainability, CRAP, coverage lookup, and risk scoring
53+
boundaries/ <- Architecture zones, allow/forbid edge rules, and violation evidence
5354
highways/index.ts <- Repeated route convergence + bypass/cowpath/synthesis evidence
54-
mcp/index.ts <- 24 MCP tools for LLM integration
55+
mcp/index.ts <- 25 MCP tools for LLM integration
5556
mcp/hints.ts <- Operation-keyed next-step hints for MCP tool responses
5657
impact/index.ts <- Symbol-level impact analysis + rename planning
5758
search/index.ts <- BM25 search engine
@@ -86,7 +87,7 @@ analyzeGraph(builtGraph, parsedFiles)
8687
}
8788
8889
startMcpServer(codebaseGraph)
89-
-> stdio MCP server with 24 tools, 2 prompts, 3 resources
90+
-> stdio MCP server with 25 tools, 2 prompts, 3 resources
9091
9192
runOperation(operation, codebaseGraph, input, context)
9293
-> { ok: true, data } | { ok: false, error, data? }
@@ -104,6 +105,7 @@ runOperation(operation, codebaseGraph, input, context)
104105
- **Codebase map context packs**: `map` / `get_codebase_map` builds deterministic file/symbol/test/scope graphs with stable evidence IDs. `get_scope_graph` and `get_context_pack` are MCP-only filtered views derived from the same result, so agents get compact context without a second analyzer path.
105106
- **Content drift**: `drift` / `detect_content_drift` compares path/name/export intent with import/call/type/side-effect/test behavior. Findings are deterministic, evidence-backed, report-only, and baseline-gated before any future CI enforcement.
106107
- **Health score**: `health` / `get_health_score` computes one gateable score plus per-file maintainability, CRAP, coverage, and risk evidence. `hotspots --metric risk` uses the same file-risk formula.
108+
- **Architecture boundaries**: `boundaries` / `check_boundaries` evaluates graph import edges against preset or custom zones and directed allow/forbid rules. The `no-boundary-violations` check rule reuses the same analyzer so CLI, MCP, and CI emit one stable finding shape.
107109
- **Shared graph-load pipeline**: CLI commands and MCP stdio startup both use `src/graph-loader/` for path checks, legacy cache migration, cache reuse, parse/build/analyze, optional persistence, and stderr progress events.
108110
- **graphology**: In-memory graph with O(1) neighbor lookup. PageRank and betweenness computed via graphology-metrics.
109111
- **Batch git churn**: Single `git log --all --name-only` call, parsed for all files. Avoids O(n) subprocess spawning.

docs/cli-reference.md

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# CLI Reference
22

3-
23 commands for terminal and CI use. The 21 analysis commands have full parity with MCP tools and auto-cache the index to `.codebase-intelligence/`; `check` runs the rules gate; `init` sets up agent adoption.
3+
24 commands for terminal and CI use. The 22 analysis commands have full parity with MCP tools and auto-cache the index to `.codebase-intelligence/`; `check` runs the rules gate; `init` sets up agent adoption.
44

55
## Commands
66

@@ -202,6 +202,22 @@ codebase-intelligence health <path> [--score] [--min-score <n>] [--json] [--forc
202202

203203
**Exit codes:** `0` when score is at least `minScore`; `1` when score is below `minScore`; `2` for invalid input.
204204

205+
### boundaries
206+
207+
Evaluate architecture boundary zones and import rules.
208+
209+
```bash
210+
codebase-intelligence boundaries <path> [--config <path>] [--preset <preset>] [--list] [--json] [--force]
211+
```
212+
213+
**Presets:** `bulletproof`, `layered`, `hexagonal`, `feature-sliced`.
214+
215+
**Config:** top-level `boundaries.zones[]` defines named areas with `patterns[]` and optional `autoDiscover`; `boundaries.rules[]` defines directed `from -> allow/forbid` import rules. Explicit `--preset` overrides discovered boundary config for ad hoc inspection.
216+
217+
**Output:** resolved zones, rules, checked edge count, unassigned file count, stable boundary violation IDs, `forbidden-edge`, `disallowed-edge`, and `risky-re-export-chain` kinds, source/target files, zones, imported/re-exported symbols, evidence, and advisory actions.
218+
219+
**Exit codes:** `0` when no boundary violations are found; `1` when violations are found; `2` for invalid input.
220+
205221
### highways
206222

207223
Find repeated routes that should converge on one canonical operation path.
@@ -238,7 +254,7 @@ codebase-intelligence check <path> [--config <path>] [--format <fmt>] [--fail-on
238254

239255
**Output:** pass/warn/fail verdict, findings, suppression ledger, and summary counts. Findings include stable `fingerprint`; cleanup findings may also include `kind`, `confidence`, and `evidence`. Summary counts include `suppressed` and `staleSuppressions`; `--summary` prints those counts when present. Exit code `0` on pass, `1` when the configured gate fails, `2` for invalid config or arguments.
240256

241-
**Rules:** `no-comments` (off by default), `no-circular-deps` (error), `no-dead-exports` (warn), `no-stale-suppressions` (warn), plus opt-in cleanup gates: `no-dead-files`, `no-unused-types`, `no-unused-members`, `no-unused-deps`. Dependency findings are scoped to the nearest `package.json` / workspace manifest and include unused, unlisted, type-only, test-only, and runtime-from-devDependencies drift. `ci-ignore-file`, `ci-ignore-next-line`, and JSDoc `@expected-unused` suppressions are reported as active/stale; JSDoc `@public` protects exported cleanup declarations while `@internal` remains checkable. Configure severities in `codebase-intelligence.json`.
257+
**Rules:** `no-comments` (off by default), `no-boundary-violations` (error when top-level `boundaries` config exists), `no-circular-deps` (error), `no-dead-exports` (warn), `no-stale-suppressions` (warn), plus opt-in cleanup gates: `no-dead-files`, `no-unused-types`, `no-unused-members`, `no-unused-deps`. Dependency findings are scoped to the nearest `package.json` / workspace manifest and include unused, unlisted, type-only, test-only, and runtime-from-devDependencies drift. `ci-ignore-file`, `ci-ignore-next-line`, and JSDoc `@expected-unused` suppressions are reported as active/stale; JSDoc `@public` protects exported cleanup declarations while `@internal` remains checkable. Configure severities in `codebase-intelligence.json`.
242258

243259
### init
244260

@@ -282,6 +298,8 @@ codebase-intelligence init [path] [--agents <list>] [--all] [--skill] [--gitigno
282298
| `--context-budget <n>` | map | Approximate token budget for context pack |
283299
| `--min-score <n>` | drift, health | Minimum drift score to report; minimum health score before exit 1 |
284300
| `--score` | health | Print compact score text |
301+
| `--preset <name>` | boundaries | Preset: bulletproof, layered, hexagonal, feature-sliced |
302+
| `--list` | boundaries | List resolved zones and rules |
285303
| `--operation <verb>` | highways | Focus on one operation verb |
286304
| `--shape <name>` | highways | Focus on one type/DTO shape |
287305
| `--min-routes <n>` | highways | Minimum routes reaching a sink before reporting |

docs/data-model.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,48 @@ HealthFileResult {
346346
}
347347
```
348348

349+
## Boundaries Result
350+
351+
`boundaries --json` and MCP `check_boundaries` return deterministic architecture-boundary findings. CLI `boundaries` exits `1` when violations exist.
352+
353+
```typescript
354+
BoundariesResult {
355+
preset: "custom" | "none" | "bulletproof" | "layered" | "hexagonal" | "feature-sliced"
356+
zones: Array<{
357+
name: string
358+
patterns: string[]
359+
matchedFiles: string[]
360+
}>
361+
rules: Array<{
362+
from: string
363+
allow?: string[]
364+
forbid?: string[]
365+
}>
366+
violations: BoundaryViolation[]
367+
summary: {
368+
checkedEdges: number
369+
violations: number
370+
unassignedFiles: number
371+
}
372+
verdict: "pass" | "fail"
373+
}
374+
375+
BoundaryViolation {
376+
id: string
377+
kind: "forbidden-edge" | "disallowed-edge" | "risky-re-export-chain"
378+
ruleId: string
379+
source: string
380+
target: string
381+
fromZone: string
382+
toZone: string
383+
symbols: string[]
384+
isTypeOnly: boolean
385+
message: string
386+
evidence: string[]
387+
actions: Array<{ command: string; reason: string }>
388+
}
389+
```
390+
349391
## Highways Result
350392

351393
`highways --json` and MCP `analyze_highways` return deterministic route-convergence opportunities.

docs/mcp-tools.md

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# MCP Tools Reference
22

3-
24 tools available via MCP stdio.
3+
25 tools available via MCP stdio.
44

55
Operation tools return JSON text payloads. Invalid operation inputs return `isError: true` with `{ "error": "..." }` using the same descriptor validation messages as CLI bad-argument exits.
66

@@ -219,7 +219,17 @@ Compute a CI-gateable codebase health score.
219219
**Use when:** Gating PR quality, ranking complexity/churn/coupling/size hotspots, or tracking maintainability.
220220
**Not for:** Route discipline (use analyze_highways) or naming drift (use detect_content_drift).
221221

222-
## 22. analyze_highways
222+
## 22. check_boundaries
223+
224+
Evaluate architecture boundary zones against import edges.
225+
226+
**Input:** `{ preset?: "bulletproof"|"layered"|"hexagonal"|"feature-sliced", list?: boolean }`
227+
**Returns:** preset, zones, rules, summary, verdict, and violations. Violations include stable IDs, kind (`forbidden-edge`, `disallowed-edge`, `risky-re-export-chain`), source/target files, source/target zones, symbols, evidence, and advisory actions.
228+
229+
**Use when:** Enforcing layering, ports/adapters, feature-sliced imports, or custom zone rules.
230+
**Not for:** General quality gates with suppressions/new-only behavior (use check).
231+
232+
## 23. analyze_highways
223233

224234
Detect repeated entry-to-sink routes that should converge on one canonical operation path.
225235

@@ -229,7 +239,7 @@ Detect repeated entry-to-sink routes that should converge on one canonical opera
229239
**Use when:** Enforcing dataflow discipline, finding ad-hoc routes, or planning canonical shared paths.
230240
**Not for:** Raw execution flow listing (use get_processes).
231241

232-
## 23. get_clusters
242+
## 24. get_clusters
233243

234244
Community-detected clusters of related files.
235245

@@ -239,14 +249,14 @@ Community-detected clusters of related files.
239249
**Use when:** "What files are related?" "Find natural groupings." Discovering emergent groupings that differ from directory structure.
240250
**Not for:** Directory-based modules (use get_module_structure).
241251

242-
## 23. check
252+
## 25. check
243253

244254
Run the configurable rules engine and gate on findings.
245255

246256
**Input:** `{}` (uses the loaded graph + discovered config)
247257
**Returns:** `{ verdict: "pass"|"warn"|"fail", summary: { error, warn, suppressed, staleSuppressions, rules }, configPath, suppressions[], findings[] }`. Each finding has ruleId, severity, file, line, column, message, fingerprint, optional `kind`, optional `confidence`, optional `evidence[]`, and optional advisory `actions[]` (the tool is read-only — actions are hints, never applied). Each suppression records directive, status, file, line, targetLine, matched rule IDs, and suppressed count.
248258

249-
Rules: `no-comments` (off by default), `no-circular-deps` (error), `no-dead-exports` (warn), `no-stale-suppressions` (warn), and opt-in cleanup gates `no-dead-files`, `no-unused-types`, `no-unused-members`, `no-unused-deps`. Dependency findings are scoped to the nearest `package.json` / workspace manifest and include unused, unlisted, type-only, test-only, and runtime-from-devDependencies drift. `ci-ignore-file`, `ci-ignore-next-line`, and JSDoc `@expected-unused` suppressions are reported as active/stale; JSDoc `@public` protects exported cleanup declarations while `@internal` remains checkable. Configure severities and options in `codebase-intelligence.json` (validated by `schema.json`).
259+
Rules: `no-comments` (off by default), `no-boundary-violations` (error when `boundaries` config exists), `no-circular-deps` (error), `no-dead-exports` (warn), `no-stale-suppressions` (warn), and opt-in cleanup gates `no-dead-files`, `no-unused-types`, `no-unused-members`, `no-unused-deps`. Dependency findings are scoped to the nearest `package.json` / workspace manifest and include unused, unlisted, type-only, test-only, and runtime-from-devDependencies drift. `ci-ignore-file`, `ci-ignore-next-line`, and JSDoc `@expected-unused` suppressions are reported as active/stale; JSDoc `@public` protects exported cleanup declarations while `@internal` remains checkable. Configure severities and options in `codebase-intelligence.json` (validated by `schema.json`).
250260

251261
**Use when:** Linting a codebase or enforcing a CI gate. "What rule violations exist?"
252262
**Not for:** Architecture metrics (use analyze_forces).
@@ -277,6 +287,7 @@ Rules: `no-comments` (off by default), `no-circular-deps` (error), `no-dead-expo
277287
| "What are the riskiest files?" | `find_hotspots` (risk, coupling, churn, or blast_radius) |
278288
| "Which files need tests?" | `find_hotspots` (coverage) |
279289
| "What is the PR quality score?" | `get_health_score` |
290+
| "Which imports violate architecture boundaries?" | `check_boundaries` |
280291
| "What should I improve first?" | `find_opportunities` |
281292
| "Find refactoring opportunities." | `find_opportunities` |
282293
| "Where is logic duplicated?" | `find_duplicates` |

0 commit comments

Comments
 (0)