archsentinel
v0.3.0
Published
Architectural quality gate for human and AI-generated code.
Maintainers
Readme
ArchSentinel
Architectural quality gate for human and AI-generated code.
What is ArchSentinel?
ArchSentinel is a command-line tool intended to verify that a codebase follows its declared architecture and quality rules. Projects describe that intent in architecture.yaml.
Current status
ArchSentinel validates version 1 of the architecture contract and deterministically analyzes projects through language-specific adapters. TypeScript and Python 3.11+ are supported. Their analyzers map source files to layers, resolve local imports, build a dependency graph, detect cycles, and enforce direct layer dependencies, forbidden package imports, and clean-code metrics.
All configured clean-code metrics are enforced for TypeScript. Git-aware analysis and semantic review are not implemented yet; their configuration fields are validated but not enforced.
Installation for development
Requirements:
- Node.js 20 or newer
- pnpm 10
- Python 3.11 or newer when analyzing Python projects
pnpm install
pnpm buildNo global installation is required. Run the built package binary through its package script:
pnpm archsentinel --helpFor source-based development runs:
pnpm dev -- --helpCommands
pnpm archsentinel --help
pnpm archsentinel --version
pnpm archsentinel init
pnpm archsentinel check
pnpm archsentinel check --format json
pnpm archsentinel check --language pythonMCP server
ArchSentinel also provides a stdio MCP server for coding agents. Build the project and start it with:
pnpm build
pnpm archsentinel:mcpThe server writes only MCP protocol messages to stdout and exposes:
archsentinel_list_languages: lists the registeredpythonandtypescriptanalyzers.archsentinel_check: checks a project and accepts optionalproject_rootandlanguagearguments.archsentinel_init: createsarchitecture.yamlwithout overwriting an existing file.
Relative project roots are resolved from the server's startup directory. The distributed server defaults to TypeScript for compatibility; pass language: "python" for Python projects. Custom servers must provide a language when multiple analyzers are registered without a default. A quality-gate FAIL is a successful tool response containing findings, while configuration and analysis failures are MCP tool errors.
MCP is an additional delivery adapter rather than a replacement for the CLI. CI pipelines can continue to use archsentinel check and its stable exit codes.
init creates a default architecture.yaml in the current working directory. It is non-interactive and never overwrites an existing file.
check validates architecture.yaml and analyzes the project rooted in the current directory. It defaults to TypeScript for compatibility; use --language python for Python. Exit codes are:
0: successful execution / pass1: architecture quality-gate failure2: configuration, analysis, or runtime error
architecture.yaml
Version 1 supports the hexagonal style, named layers and their permitted dependencies, layer-specific forbidden imports, clean-code warning/error thresholds, and quality-gate settings.
version: 1
architecture:
style: hexagonal
layers:
domain:
paths: [src/domain/**]
can_depend_on: []
application:
paths: [src/application/**]
can_depend_on: [domain]
rules:
domain:
forbidden_imports: [express]
clean_code:
excluded_paths: [test/**, tests/**, api/generated/**]
max_method_lines: { warning: 30, error: 60 }
max_class_lines: { warning: 200, error: 300 }
max_parameters: { warning: 4, error: 6 }
max_cyclomatic_complexity: { warning: 10, error: 20 }
quality_gate:
fail_on: [CRITICAL]
max_major: 3
semantic_confidence_threshold: 0.8Layer dependencies must name declared layers. Paths cannot be empty, warning thresholds cannot exceed error thresholds, and semantic confidence must be between 0 and 1.
Architecture analysis
Layer paths and forbidden imports use glob matching. Same-layer imports are always allowed. ArchSentinel checks direct file dependencies only; it does not infer transitive layer violations.
Files matching no layer remain unassigned. They stay in the dependency graph and can participate in cycle detection, but ArchSentinel does not infer layer-policy violations from them. A file matching multiple layers produces the critical MAP-001 finding and is not assigned arbitrarily.
Implemented findings:
HEX-001(CRITICAL): forbidden direct layer dependencyHEX-002(CRITICAL): forbidden external package importDEP-001(MAJOR): circular file dependencyMAP-001(CRITICAL): ambiguous layer assignmentCC-001(MINORorMAJOR): callable exceeds the configured warning or error maximum for parametersCC-002(MINORorMAJOR): callable exceeds the configured warning or error maximum for implementation linesCC-003(MINORorMAJOR): class exceeds the configured warning or error maximum for body linesCC-004(MINORorMAJOR): callable exceeds the configured warning or error maximum for cyclomatic complexity
Functions, methods, constructors, arrow functions, and function expressions with bodies are evaluated by max_parameters, max_method_lines, and max_cyclomatic_complexity. Method lines cover the implementation body, including its opening and closing lines but excluding decorators and multiline signatures. Class lines cover the class body and exclude decorators. Overload signatures are not counted as separate implementations.
Cyclomatic complexity starts at one. TypeScript decisions include if, loops, catch, ternaries, non-default case, &&, ||, and ??, including logical assignments. Python decisions include if, for, async for, while, except, conditional expressions, non-default match cases, case guards, boolean operators, and comprehensions. Decisions inside nested callables belong only to the nested callable. clean_code.excluded_paths accepts glob patterns for tests, generated sources, or other files that should not receive clean-code findings. All configured maxima are inclusive: exceeding warning produces a minor finding, while exceeding error produces a major finding.
For example, with domain.can_depend_on: [], this produces HEX-001:
// src/domain/order-service.ts
import { saveOrder } from '../infrastructure/order-repository';Any finding whose severity appears in quality_gate.fail_on fails the gate. The gate also fails when the number of major findings is greater than quality_gate.max_major.
Source discovery honors tsconfig.json include/exclude settings when that file exists. Otherwise it discovers .ts and .tsx recursively. node_modules, dist, build, coverage, .git, and declaration files are always excluded. Paths are reported relative to the project with / separators.
Static imports, side-effect imports, and module re-exports are analyzed. Relative .ts, .tsx, and index modules resolve through TypeScript. Common baseUrl and paths aliases are supported through TypeScript resolution. Dynamic import() and CommonJS require() are not analyzed in this iteration.
Python discovery recursively analyzes .py files while excluding virtual environments, caches, build output, coverage output, and VCS metadata. Absolute imports support both root packages and the common src/ layout; relative package imports resolve through modules and __init__.py. Python's standard ast parser is invoked in an isolated process, and project modules are never imported or executed. Dynamic imports are not analyzed. ArchSentinel uses python3 by default on Unix and python on Windows; set ARCHSENTINEL_PYTHON to override the executable.
JSON reports use the same application result as console output:
pnpm archsentinel check --format jsonDevelopment
pnpm format
pnpm format:check
pnpm lint
pnpm typecheck
pnpm test
pnpm buildTests use isolated temporary directories and focused YAML fixtures. See docs/architecture.md for the internal boundaries.
Preflight
Run every required validation in sequence:
pnpm preflightRoadmap
- [x] CLI foundation
- [x] Architecture Contract
- [x] Configuration validation
- [x] TypeScript AST analyzer
- [x] Python AST analyzer
- [x] Layer assignment
- [x] Dependency graph
- [x] Hexagonal dependency rules
- [x] Forbidden import rules
- [x] Circular dependency detection
- [x] MCP server
- [x] Clean Code metrics
- [x] TypeScript API corpus validation
- [ ] Git diff analysis
- [ ] Semantic LLM review
- [ ] Baseline
- [ ] CI/SARIF integrations
