0015. Code rules are checked, not reviewed
Status: accepted, 2026-10-02. Deciders: jjforge maintainers.
Context
Section titled “Context”Apprentices write most of the code, and a rule that only review holds is
applied unevenly. The server read its one setting with @Value and never
validated it, and vcsd parsed its address by hand. Formatting was the only
rule a tool checked.
The server’s architecture rules could use Konsist, which reads Kotlin source, or ArchUnit, which reads compiled classes. Konsist’s latest release predates Kotlin 2.4. ArchUnit doesn’t depend on the Kotlin version, and Spring Modulith builds on it.
Decision
Section titled “Decision”Every rule below fails the build. None has a baseline.
Server, in gradle build:
- Settings live in
@ConfigurationPropertiesclasses named*Properties, annotated@Validated, and constrained with Jakarta Validation, so an invalid setting stops the server at startup. Nothing reads@Value. - A component gets its dependencies through its constructor. It has no
@Autowiredorlateinitfield. ArchitectureTestchecks both rules with ArchUnit.ControllerContractTestchecks the controllers, as ADR 0011 decides.ModulesTestruns Spring Modulith’s verification: a module uses another only through its top-level package.- detekt 2 checks complexity, naming, and likely bugs. ktlint formats.
- Compiler warnings are errors.
- Kover fails below 80 percent line coverage of the hand-written code.
vcsd and jf, in mise run rust:lint:
- Each binary reads its settings from flags or the environment into one clap struct. An invalid value stops it with a usage message.
- clippy’s
pedanticgroup is denied, and so areunwrapandexpectoutside tests.unsafeis forbidden. - rustdoc warnings are errors.
- cargo-machete fails on an unused dependency, and cargo-deny on a disallowed license, a security advisory, or an unknown source.
The whole repository, in mise run lint: actionlint checks the workflows,
hadolint the Dockerfiles, and shellcheck the task scripts.
Consequences
Section titled “Consequences”detekt 2 is still an alpha release. detekt 1.23 can’t run on JDK 25, so the alpha is the only choice, and a release candidate replaces it once one exists.