Back to Development
developmentL3 SystematicCode Review & Quality

Lint-as-architecture (standards = enforced rules)

Custom lint rules that enforce architectural decisions turn code review comments into machine-checked constraints - so architectural violations are caught at CI time, not weeks later in production.

  • ·AI review agent runs as a first-pass reviewer on every PR before human review
  • ·Lint rules enforce architectural standards (not just style) - the "Bug to Codify to Lint Rule" pipeline is active
  • ·At least 3 architectural guardrail rules have been created from past bugs or incidents
  • ·AI review agent findings are categorized by severity (info, warning, blocking)
  • ·New lint rules are proposed automatically when recurring review comments are detected

Evidence

  • ·CI configuration showing AI review agent as required check
  • ·Lint rule change history showing rules created from incident post-mortems
  • ·AI review agent output logs with severity categories

What It Is

Lint-as-architecture is the practice of encoding architectural decisions as custom lint rules that run in CI. Instead of communicating architecture through documentation (which people don't read) or code review comments (which are reactive and inconsistent), you express the decision as a machine-executable rule that fails the build when violated.

Consider these common architectural decisions that teams currently communicate through review comments:

  • "Don't call the database directly from HTTP handlers - use the service layer"
  • "All API responses must use our standard Result<T, ApiError> type"
  • "The auth module must not import from billing - they're separate bounded contexts"
  • "Don't use fmt.Println in production code - use the structured logger"
  • "External HTTP calls must go through the HTTP client abstraction, not the standard library directly"

At L2, these rules exist as expectations in people's heads, enforced through review comments when a reviewer remembers to check. At L3 (Systematic), these rules are encoded in the linting configuration and enforced automatically by CI. The architectural constraint exists as code, not as institutional memory.

Tools that support custom rules: ESLint custom rules (JavaScript/TypeScript), Pylint plugins (Python), custom golangci-lint linters (Go), ArchUnit (Java/Kotlin), NetArchTest (.NET), Rubocop custom cops (Ruby), and many others. Most modern linting frameworks are designed to be extended with domain-specific rules.

The shift from L2 to L3 on this dimension is a mindset shift as much as a tooling shift: architecture is only real if it's enforced. A decision recorded in Confluence but not in CI is a suggestion, not a constraint.

Why It Matters

Encoding architecture as executable rules has compounding benefits:

  • Prevents regression - A constraint that exists only in institutional memory degrades over time. New team members don't know it. Existing team members forget it during a crunch. A lint rule enforces the constraint forever.
  • Shifts enforcement left - Architectural violations caught in CI (seconds after commit) are dramatically cheaper to fix than violations caught in code review (hours later) or in production (days or weeks later).
  • Makes architecture visible - The lint configuration is a machine-readable record of the team's architectural decisions. New team members can read the rules to understand what constraints exist and why.
  • Enables faster code generation - When AI agents generate code at L4-L5, they often violate architectural constraints that aren't in their context. Custom lint rules catch these violations automatically, making AI code generation safer.
  • Reduces reviewer cognitive load - Reviewers who know that architectural constraints are machine-enforced can stop mentally checking for violations. This is real cognitive capacity recovered for higher-order review.

The progression to L4 (auto-merge) and L5 (autonomous agents) depends critically on trusting your quality gate. Custom lint rules are a core component of that trust: they let you say with confidence that a Green PR has not introduced known architectural violations.

Tip

Write the "why" as a comment in every custom lint rule. Six months from now, no one will remember why no-direct-db-from-handler was added. A single-sentence comment in the rule definition ("Added after incident-2024-11: N+1 query problem in HTTP handlers") makes the constraint legible to the future team.

Getting Started

6 steps to get from here to the next level

Common Pitfalls

Mistakes teams actually make at this stage - and how to avoid them

How Different Roles See It

B
BobHead of Engineering

Bob's team has had three incidents in the past six months caused by direct database access in HTTP handlers - each resulted in N+1 queries under load that crashed the service. After each incident, they added a note to the architecture documentation. The notes are there, but developers keep making the same mistake because no one reads the architecture docs before writing code.

What Bob should do - role-specific action plan

S
SarahProductivity Lead

Sarah is tracking post-merge bugs (bugs that were introduced in a PR that passed review). She's noticed that many of them fall into patterns: the same architectural violations appearing repeatedly across different PRs and different developers. Her team is fixing the same class of bugs every quarter.

What Sarah should do - role-specific action plan

V
VictorStaff Engineer - AI Champion

Victor keeps writing the same review comment: "Don't call the database from the HTTP handler layer." He's written it on 12 PRs in the past 3 months. He knows exactly what the bad pattern looks like and what the correct pattern is. He's confident he can write a lint rule for it.

What Victor should do - role-specific action plan