🔴 Your architecture rules are dying in Confluence. Here's how to make them bite back.

Published: (March 3, 2026 at 12:36 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

The 3‑Step Process

Step 1 — Copy your arch rules from Confluence/Wiki

Just grab the raw text. It doesn’t need to be perfectly formatted.

Example rules I copied

  • Classes extending a parent must use the parent name as suffix
    e.g., CacheDataProvider extends DataProvider

  • No string literals inside methods — use static final class members
    e.g., static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"

  • Controllers must live under *.controller.* package only

  • Domain objects must NOT be instantiated with new inside methods
    e.g., new CacheHelper() inside a method ❌

Step 2 — Feed them to Claude Code with this prompt

Open Claude Code and paste the following prompt:

You are an expert Java architect specializing in ArchUnit — a Java library for checking architecture rules as unit tests.

You will receive architecture rules in plain english format and must convert it into a complete, compilable ArchUnit JUnit5 test class.

Rules:

  A. Class must have parent class name as suffix while extending. 
    Ex: class CacheDataProvider when extends DataProvider
  B. No string literals inside a method, always have static final class member. 
    Ex: String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";
  C. Package Naming Conventions like edu.pk.demo.archunit.controller.* 
  D. Method should not create domain object locally using "new" keyword. 
    Ex: final CacheHelper cacheHelper = new CacheHelper();

Requirements:
- Use @AnalyzeClasses(packages = "edu.pk.demo.archunit")              # Use your project package name
- One @ArchTest per rule, named descriptively
- Use ArchUnit's fluent API (classes(), noClasses(), methods())
- Add a brief comment above each test explaining the rule intent
- Base package: edu.pk.demo.archunit  

ArchUnit API Reference
  - Class-level setup:
  @AnalyzeClasses(packages = "com.example", importOptions = ImportOption.DoNotIncludeTests.class)
  public class MyArchTest { ... }

  - Rule declaration (always static final):
  @ArchTest
  static final ArchRule ruleName = ...;

  - Fluent API for common patterns:
  # CONTAINMENT (CONTAINED WITHIN / CONTAINS):
  classes()
    .that().resideInAPackage("com.example..")
    .should().resideInAnyPackage("com.example.domain..", "com.example.service..")
    .as("...").because("...");

  # NO DEPENDENCY ON:
  noClasses()
    .that().resideInAPackage("com.example.web..")
    .should().dependOnClassesThat().resideInAPackage("com.example.db..")
    .as("...").because("...");

  # CYCLE FREE:
  slices()
    .matching("com.example.(*)..")
    .should().beFreeOfCycles();

  # MUST USE LIBRARY (CONTAINS library):
  classes()
    .that().resideInAPackage("com.example.api..")
    .should().dependOnClassesThat().resideInAPackage("com.security..")
    .as("...").because("...");

Output Rules:
- Output ONLY valid Java source code
- No markdown code fences
- No explanation text before or after the class
- Full import statements required
- Class must be immediately runnable with ArchUnit + JUnit5 on the classpath

Step 3 — Drop the generated tests into your project and run

Claude generates something like this:

@AnalyzeClasses(packages = "edu.pk.demo.archunit")
public class ArchitectureRulesTest {

    // Rule: Subclass name must end with the parent class simple name
    @ArchTest
    static final ArchRule subclassesShouldUseSuperclassNameAsSuffix =
        classes()
            .that().areAssignableTo(DataProvider.class)
            .should().haveSimpleNameEndingWith("DataProvider")
            .because("Subclasses must use the parent class name as suffix for discoverability");

    // Additional rules would follow here …
}

Why this matters

Architecture drift happens because rules live in documents, not in pipelines.

When you encode rules as tests:

  • ✅ Every PR is verified automatically
  • ✅ New developers can’t accidentally break conventions
  • ✅ Architecture decisions are self‑documenting in code
  • ✅ No more “we agreed not to do this” code‑review comments

The best part? Claude Code handles the ArchUnit API fluency. You just describe what you want to enforce — it figures out how to write it.

Your architecture doc shouldn’t be a suggestion. Make it a compiler error.

Have you automated architecture enforcement in your team? What rules do you wish you’d enforced from day one? Drop them below 👇.

0 views
Back to Blog

Related posts

Read more »