Project Configuration (aic-check.yaml)¶
A scanned project can carry its own check policy in an aic-check.yaml file that the tool
auto-discovers (logback-style) — controlling all quality gates and the architecture check. This means
CI can run a bare --scan=<path> and the project's own rules are applied.
Precedence¶
Configuration is layered, lowest to highest:
So a project file overrides the built-in defaults, and a CLI flag (--fail-on-distance, --no-cycles,
--arch) overrides the file for a one-off run.
Discovery¶
The first existing of these, relative to the scanned project, is used:
src/main/resources/aic-check.yaml(or.yml)aic-check.yaml(or.yml) at the project root
File format¶
Every section and field is optional — anything omitted keeps its default.
gates:
max-package-distance:
enabled: true
threshold: 0.7
forbidden-zones:
enabled: false
max-average-distance:
enabled: false
threshold: 0.5
no-cycles:
enabled: true
max-complexity: # fail if any method's cyclomatic complexity exceeds threshold
enabled: false
threshold: 15
# Forbidden APIs — a gate. Each rule bans a class / method / package; allowedIn exempts matching classes.
banned-apis:
enabled: false
rules:
- method: java.lang.System.exit
message: "Don't call System.exit"
- class: java.util.Date
message: "Use java.time"
- package: java.sql
message: "DB access only in the repository layer"
allowedIn: ['.*\.repository\..*', '.*\.repo\..*']
# Dead-code report (class-level). Report-only — never fails the build (DI/reflection → false positives).
dead-code:
enabled: false
# Module granularity. By default a module is a direct sub-package of the root package (Spring-Modulith).
analyze:
rootPackage: # optional: analyze this root explicitly (lets a non-Spring-Boot project opt in).
# When blank the root is resolved: @SpringBootApplication, else the common prefix.
depth: 1 # analyze N levels below the root package (default 1)
expand: # split only these depth-1 packages one extra level into their sub-packages
- dto # e.g. dto.admin, dto.auth, dto.webapi each become their own module
architecture:
enabled: true
template: layered # a built-in template (layered | hexagonal | onion) …
# … OR inline the spec instead of a template:
# spec:
# name: Custom
# components:
# - name: Web
# matches: ['.*\.web\..*']
# - name: Service
# matches: ['.*\.service\..*']
# access:
# Web: [Service]
# Service: []
# options:
# forbidCycles: true
gates— see CLI & CI Gates for what each gate means.architecture—enabledplus either a built-intemplateor an inlinespec(same schema as Architecture Checks).specwins if both are given.analyze— root package & module granularity.rootPackageanalyzes that root explicitly (so a non-Spring-Boot project can opt in); when blank the root is resolved automatically (@SpringBootApplication, else the inferred common prefix). By default a module is a direct sub-package of the root.depth: Nanalyzes N levels deep for every branch;expand: [dto, …]splits only the named depth-1 packages one extra level (e.g. sodto.admin/dto.webapiget their own A/I/D instead of all rolling up intodto). Classes are never dropped — a class shallower than the target depth maps to its own package.
Example: enforce in CI with no flags¶
Commit src/main/resources/aic-check.yaml to your project, then the CI step is simply:
The gates and architecture come from the file; the process exits non-zero on any violation.