Skip to content

[Feature Request] Enforce architecture rules with executable architecture tests (fitness functions) #1430

Description

@bodote

Problem

Two current threads leave a gap between them:

What neither covers: structural architecture rules — layer boundaries, allowed dependency directions, forbidden imports, cycle bans — enforced deterministically. Prose rules in rules/*.md are advisory: an agent optimizing to make a feature work will happily import across a boundary that a Markdown file told it to respect. Scenario-derived tests won't catch that either, because the feature works — the architecture just eroded.

This class of drift is exactly what AI agents produce at scale, and it is also the class of rules that is cheapest to enforce deterministically, because mature tooling already exists in every major ecosystem.

Proposal

OpenSpec should not implement architecture checking itself — it should be the bridge from spec to existing enforcers:

  1. A structured architecture rules format. E.g. openspec/rules/architecture.rules.md (fits the Enhancement: Rules #447 layout) with a machine-readable block (YAML frontmatter or fenced block) declaring layers/modules, allowed dependencies, and constraints (no cycles, naming, etc.).

  2. A compile step. Something like openspec arch generate that translates those rules into config for the ecosystem's standard tool:

    • JS/TS → dependency-cruiser or eslint-plugin-boundaries
    • Python → import-linter
    • Java → ArchUnit
    • .NET → NetArchTest, Go → arch-go, …
  3. Verification integration. The verification flow proposed in Integration with Verification #433 (and the lightweight variant in Add lightweight verification step (implementation vs spec) #381) runs these architecture tests alongside scenario tests; CI blocks merges on violations.

The result: architecture rules stop being instructions the agent may follow and become gates the implementation must pass — regardless of which agent or model wrote the code. This is the "living spec" idea from #433 extended from behavior to structure.

Suggested MVP

  • One stack (TypeScript + dependency-cruiser), one rules schema, generate + verify wiring.
  • Everything else (more languages, more rule types) is adapters on a stable core.

Prior art

  • ArchUnit / ArchUnitTS / import-linter / dependency-cruiser — mature, declarative architecture enforcement per ecosystem.
  • "Fitness functions" (Ford/Parsons/Kua, Building Evolutionary Architectures) — the established name for executable architecture constraints.

Relationship to existing issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    future-roadmapStrategically important direction, but not yet scoped enough for the backlog

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions