Your ADRs Are Just Wishful Thinking Without Automated Enforcement

Your ADRs Are Just Wishful Thinking Without Automated Enforcement

Why manually checking PRs against architecture decisions is dying, and how agentic fitness functions make governance scale with AI-assisted development

Your ADRs Are Just Wishful Thinking Without Automated Enforcement

Somewhere in your repo, there’s a docs/adr/ folder with 47 markdown files that document every architectural decision your team has ever made. ADR-014 explains why you use event-driven communication between checkout and payment. ADR-023 justifies the shared kernel between the web and mobile APIs.

Nobody reads them. Fewer enforce them.

When a developer asks “should I route this through the event bus or just call the service directly?” senior engineers and architects become the enforcement mechanism. They’re the human CI/CD pipeline, manually diffing PRs against decisions that were written months or years ago. And now that AI coding tools are generating 59% more workflow runs year over year, that model doesn’t just crack, it shatters.

CI/CD pipeline diagram showing the integration of automated architecture fitness functions and agentic checks for enforcing ADR compliance
Automated enforcement in CI/CD: deterministic gates and agentic fitness functions work together to keep architecture decisions alive.

The Manual Review Bottleneck Is a Governance Trap

Here’s what the reality of architecture enforcement looks like at most companies: a senior engineer hunts for violations in pull requests. They look for new dependencies requiring design review, logic bypassing service boundaries, duplicated implementations that should have been abstracted. It’s exhausting, inconsistent, and increasingly impossible at AI-assisted development speed.

A practitioner on r/softwarearchitecture described it bluntly: for many architectural decisions, there’s no deterministic way to verify compliance with linters or code checks. The best you can do is trust the developer, or spawn a review agent to cross-check changes against the ADR list. But neither approach is deterministic, and neither catches everything.

That’s the same problem that makes strict code reviews a velocity killer in the AI era. When humans are the only enforcement gate, you create a bottleneck that doesn’t just slow delivery, it forces developers to batch changes to survive the wait, which defeats the entire purpose of continuous integration.

Deterministic Fitness Functions: The Rules That Actually Work

Before we talk about AI agents doing architectural judgment, let’s be clear about what’s already automatable. Fitness functions turn architectural intent into executable feedback. A dependency rule protects package boundaries. A contract test protects integration compatibility. A latency budget protects performance. Security scans protect policy compliance.

These checks are deterministic. They’re simple. They work.

An evolutionary architecture treats these fitness functions as first-class citizens, automatically failing builds on architectural violations instead of hoping a reviewer catches them. For every constraint that can become a rule, schema, threshold, or executable experiment, you should already have a CI gate. No senior engineer needed. No judgment call required.

The problem starts when you move beyond the reducible stuff.

Where Deterministic Rules Fail

A dependency rule can tell you that orders-service now imports from payment-service-core. It cannot tell you whether that import is intentional shared-kernel collaboration, an accidental shortcut, or the first sign that someone is hollowing out a service boundary to avoid a properly designed event.

A schema diff can prove the API still parses. It cannot judge whether the new field preserves the domain semantic or leaks a UI concern into a domain event, the kind of drift that quietly creates the exact DDD enforcement hell that chokes system scale.

These aren’t exotic edge cases. This is the normal way architecture decays: through individually reasonable changes that pass every written rule while slowly moving the implementation away from the intent the team believed it had protected.

Manual review used to catch this. But manual review doesn’t scale down to every pull request when AI agents generate thousands of lines of technically-correct, architecturally-wrong code.

Agentic Fitness Functions: Judgment as a Service

This is where the concept of agentic fitness functions enters, and it’s the most promising architecture governance pattern to emerge in the agentic AI era.

An agentic fitness function is an architecture governance check whose evaluator is a calibrated AI agent. It evaluates bounded evidence, a PR diff, changed API specs, relevant ADRs, ownership metadata, and returns a structured verdict with scores, confidence levels, and escalation guidance. It doesn’t replace deterministic checks. It sits beside them, handling the judgment-heavy interpretation that previously required a human architect.

The recent InfoQ deep dive on this pattern provides a concrete reference implementation on GitHub that models the entire pipeline.

Anatomy of a Structured Verdict

The output is machine-readable and auditable:

{
  "fitness_function": "checkout-boundary-fidelity",
  "rubric_version": "2026.07.01",
  "score": 0.68,
  "confidence": 0.74,
  "decision": "advisory_warn",
  "violated_criteria": ["semantic coupling"],
  "evidence": ["ADR-014", "OrderEvent.diff", "PaymentSession DTO"],
  "recommended_action": "Move PaymentSession behind a checkout-owned adapter or create an explicit shared-kernel ADR.",
  "deterministic_rule_candidate": "Disallow public events from exporting internal payment-state DTOs."
}

Notice what’s happening here. The agent reads ADR-014, sees that the diff exports PaymentSession DTOs through OrderEvent, and flags a semantic coupling violation. It recommends moving the DTO behind an adapter, or, crucially, proposing a new ADR if the team decides this coupling is intentional.

This isn’t a blocking gate. It’s an advisory signal that gets escalated based on confidence and blast radius. The architecture community keeps the final say when the trade-offs get real.

Real-World Implementation: Statically Analyzing the Graph

One developer building exactly this tool described the hardest challenge: statically analyzing a continuous graph across multiple systems and languages.

Consider a straightforward MVC architecture: TypeScript frontend, Go backend, PostgreSQL database. The most likely ADR violations involve models and views communicating directly without a controller intermediary, or views and controllers reaching into the database directly.

An agentic fitness function must:

  • Classify every component as model, view, or controller
  • Validate that models cannot reach views without controller mediation
  • Verify views and controllers never talk to storage
  • Confirm controllers and models never touch UI concerns

That’s a clean analytical graph for TypeScript, Go, and PostgreSQL. Now imagine adding Python services, MongoDB, Kafka, Redis, and infrastructure-as-code sprawl across Terraform and Kubernetes. The graph analysis becomes hideous, but it’s exactly where AI-powered analysis excels.

The Hard Truth: Verification Without Verification

Here’s the uncomfortable part that everyone building this tooling eventually hits: an agent can catch most things if it has the complete list of requirements and the common gotchas, especially when running at high reasoning levels. But there’s no way to verify the agent actually caught everything without reviewing its work yourself.

This isn’t a flaw in implementation. It’s a fundamental limitation. The agentic fitness function reduces the review burden from “read everything in this PR” to “read the structured verdict and spot-check the evidence.” That’s a massive improvement, but it’s not hands-off delegation, and treating it as such is how architectural drift accelerates.

The safe pattern: deterministic gates block critical violations. Agentic checks produce advisory warnings with confidence scores. Low-confidence findings, judge disagreements, and high-blast-radius decisions escalate to humans. And when agentic findings recur with enough consistency, teams promote them into deterministic rules, closing the drift gap permanently.

Calibrating Your AI Architecture Judge

If you’re building this pattern, the calibration process follows a standard ML loop:

  1. Collect 20 to 50 prior changes that your architecture community has already classified as acceptable, risky, or unacceptable
  2. Run the judge against those examples
  3. Tune the rubric until false positives, false negatives, and variance are understood
  4. Re-run the calibration set whenever the model, prompt, rubric, or evidence contract changes

Never average away disagreement between judges. Disagreement is often the signal that the architectural trade-off is real and deserves human attention.

You also need guardrails against the failure modes that plague AI judgment:

Failure Mode How It Appears Control
Position bias Judge favors the first design it reads Evaluate both orderings for high-impact changes
Verbosity bias Rich PR descriptions look more convincing than code Score against evidence, not prose length
Self-enhancement bias Model favors patterns it generates Use separate judge model
Non-determinism Same evidence, different scores Repeat runs, treat variance as low confidence
Prompt injection Diff comments tell the judge to ignore criteria Treat repo content as evidence, never judge instructions
Rubric drift Criteria slowly stop reflecting ADR intent Version rubrics, require review, run calibration checks

This realism is what separates the pattern from the hype.

The ADR Drift Monitor: Governing Past Decisions

The most underrated use case for agentic enforcement isn’t checking new changes, it’s checking whether old decisions still hold.

Architectural decisions stay valid only while the assumptions behind them remain true. An ADR might justify synchronous communication because traffic is low, accept a shared database as temporary, or tolerate a trade-off based on operational constraints that have since evaporated.

An ADR Drift Monitor periodically compares documented ADR assumptions against operational metrics, incidents, cost trends, dependency graphs, and deployment patterns. It doesn’t fail builds. It proactively prompts architects to revisit decisions whose rationale no longer holds.

This is the illusion of control that AI coding agents expose, systems evolve whether or not anyone is watching, and the ADR folder remains authoritative only if someone verifies its assumptions still hold.

What This Means for Your Team

The era of “the senior engineer is the enforcement mechanism” is ending. Not because senior engineers are obsolete, but because at AI-generated code speed, the review pipeline needs automated sieves before humans apply judgment.

Your CI pipeline should already be running deterministic architecture checks. New dependencies triggering design review? That’s a CI gate. Package boundaries enforced? Also a gate. Everything expressible as a rule or schema should already be blocking merges.

For the judgment-heavy stuff, semantic coupling, boundary fidelity, stale ADR assumptions, the emerging pattern is agentic fitness functions running as advisory signals that escalate to humans when uncertainty is high. The reference implementation is open source. The calibration methodology is documented. The failure modes are cataloged.

The only thing left is deciding whether your architecture governance evolves before the AI-generated code makes the choice for you.


Want to dig deeper? Check out why your architecture should fail the build for the case on making architecture violations blocking gates, and how to implement that pattern in your CI pipeline without grinding velocity to zero.

Share:

Related Articles