Link an ADR to policy as code by giving the policy a stable rule ID, referencing the governing decision ID, declaring its exact scope and documenting what a failure proves. CI output should link back to the decision's rationale and offer remediation. Keep the prose authoritative and the policy limited to consequences it can evaluate deterministically.
Rationale and verification belong together
A policy engine can report a forbidden dependency or invalid configuration, but the failed expression rarely explains why the organisation chose the rule. An ADR provides context, alternatives and consequences; the policy supplies repeatable verification. Linking them makes both more maintainable.
The relationship is many-to-many. One decision may require an architecture test, a Semgrep rule and an infrastructure policy. One shared policy may implement consequences from several decisions in different scopes.
Define an explicit mapping
Store the mapping beside the decision or policy and validate both references. Include the engine and severity so consumers do not mistake an advisory check for a merge-blocking guarantee.
rule_id: no-domain-infrastructure-import
decision_ids: [ADR-0017]
engine: dependency-cruiser
scope: src/domain/**
severity: error
remediation: depend on a domain-facing interfaceMake failures decision-aware
A useful CI message names the affected file, detected fact, decision ID and approved remediation. Link to the exact decision revision evaluated by the check. This shortens review and helps an agent correct the implementation without inventing a workaround.
State coverage honestly. A dependency rule may prove the absence of one import direction; it cannot prove that the full design satisfies the intent of ‘keep the domain independent’. Preserve human review for the unencoded remainder.
Test the controls themselves
Keep positive and negative fixtures for each rule, pin policy versions and fail visibly when a declared enforcement file disappears. Review policy changes with the same owners as the governing decision. When a decision is superseded, update or retire its mapped checks in the same change where practical.
- Fixture that must pass.
- Representative violation that must fail.
- Scope boundary that must not be evaluated.
- Message that identifies the governing decision.