Skip to content

Goal

The Kotlin Coding Standards were a document, and the machinery that enforced them lived inside one repository. Two consequences followed.

A standard nothing checks drifts silently. A second Kotlin repository had five custom rules on a different engine, four of them duplicating rules the first repository already had, judged against a different syntax tree. Nothing kept the two in agreement, and nothing would have said so if they diverged.

A rule and the claim it enforces were not connected. A finding reported a fixed tool message. Nothing pointed the reader at the section of the standard that made the claim — and when this project tried to build those citations, it found three rules with nothing to cite at all, two of which had been settled by ruling in conversation and implemented the same day without ever reaching the documentation. The gap was invisible until something tried to link to the standard. → DT-013.

  • Extract the rules, the catalog, the scope classification, the reporting and the CI wiring into one published plugin any Arda Kotlin repository can adopt.
  • Give the plugin a second consumer, because a seam proved against one consumer is not proved at all.
  • Give it an extension surface, so a repository can add rules of its own without forking the plugin.
  • Make every finding cite the standard that defines it.

These are the ones that shaped the result rather than merely describing it.

A rule that ran and found nothing must never look like a rule that never ran. Every silent miss this apparatus has met came through that gap, and the repository it came from catalogues six independent forms of silent non-execution — each producing a plausible-looking clean report. The three-state report is the answer, and it is why none reports SKIPPED rather than clean.

Carry rules ahead of their subject. The exemplar carries what its siblings will need, which makes the liveness fixture mandatory rather than advisory. → DT-002, DT-007.

Nothing may be a quiet way out. Facets, scope and site departures are the three axes, and each is audited: the facet declaration is exhaustive and checked against the code, every scope override is printed in every report beside the plugin’s default, and a @Suppress is visible in the diff, inventoried, and fails the gate if it is waiving nothing. → DT-005.

The extraction must be behaviour-preserving, and shown to be. Not asserted from a green test suite — the donor repository had already had a stale service-registration file take its entire ruleset offline while all forty rule tests passed.

Behaviour preserved. print-module reports 0 findings, 24 rules clean consuming the published plugin — the same numbers as before the extraction, over the same tree.

The gate was proved able to fail rather than assumed to work. Three probes were introduced, each confirmed to turn the gate red, and each reverted. That distinction matters here more than usual: this is a project about tools that report zero, and a tool that cannot be seen failing has not been seen working.

The seam holds across two consumers with opposite postures. operations ratchets rules for which it has a standing backlog; print-module holds the same rules at tree because its baseline is empty. Same rules, same citations, different posture, both correct — which is the load-bearing claim of DT-005 rather than an exception to it.

  • The CI action surface — what the GitHub Actions must do, and how reports are posted as pull-request comments. Still open as DT-008; it is the only design topic the extraction did not need answered before it started.
  • Kover thresholds and the JUnit platform pin, which stay with PDEV-1304. → DT-012.
  • Pure rule-authoring repositories that publish rules for others to consume. The extension surface serves a repository that authors and uses its own rules; MP placed the other case in the distant future, and that narrowing is what settled the packaging question. → DT-011.

Copyright: (c) Arda Systems 2025-2026, All rights reserved