Skip to content

docs: add portable VSA vs Clean Architecture decision guide#51

Merged
emeraldleaf merged 3 commits into
mainfrom
docs/vsa-vs-clean-guide
Jun 3, 2026
Merged

docs: add portable VSA vs Clean Architecture decision guide#51
emeraldleaf merged 3 commits into
mainfrom
docs/vsa-vs-clean-guide

Conversation

@emeraldleaf

@emeraldleaf emeraldleaf commented May 29, 2026

Copy link
Copy Markdown
Owner

Summary

A reusable, system-agnostic synthesis of the VSA-vs-Clean decision, distilled from a multi-turn architecture discussion. Written to be lifted into any project; NextAurora is the worked example at the end, not the premise. Same pattern as docs/messaging-transport-selection.md (#49) — portable reference knowledge, kept out of CLAUDE.md (which holds this repo's rules).

Core points it lands

  • "Clean Architecture" is two things: the dependency rule (always-on, not earned, not in tension with VSA) and the 4-project structure (the only part with ceremony, the only part the "is it worth it?" question is actually about).
  • VSA and Clean are orthogonal axes — organization/cohesion vs dependency direction. "Combine" = organize by feature + keep the domain decoupled.
  • VSA doesn't auto-enforce the dependency rule — you enforce it on a spectrum: convention → architecture tests → project split. The middle rung (NetArchTest/ArchUnitNET) gives the same enforcement as the 4-project split without the ceremony, at the namespace level in a single project (code example included).
  • Two meanings of "combine" — orthogonal axes + per-slice complexity gradient.
  • Testcontainers shifted the calculus — integration-default for IO-touching code beats mock-heavy unit tests, which collapses the repository-interface-for-testability argument. But it's a Testing Trophy, not a pure rectangle — keep fast unit tests for pure domain logic; mind the Docker dependency + speed cost.
  • The duplication tradeoff — cross-cutting concerns in pipeline behaviors (not per-slice), prefer duplication over the wrong abstraction; cost scales with slice count and bites hardest on pure CRUD.
  • When-to-use table + common mistakes (incl. "don't add a repo interface per slice on EF Core," "don't 4-project-split just to get the dependency rule," "don't mix layered + sliced services in one solution").

Scope

Test plan

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Added a comprehensive architectural decision guide comparing Vertical Slice Architecture and Clean Architecture, clarifying dependency-rule vs. project-structure distinctions; outlines enforcement options (including architecture tests), tradeoffs and costs, modern integration-testing practices, guidance on handling duplication and cross-cutting concerns, common pitfalls, and a worked example demonstrating practical application.

A reusable, system-agnostic synthesis of the VSA-vs-Clean decision,
distilled from a multi-turn architecture discussion. Written to be lifted
into any project; NextAurora is the worked example at the end, not the
premise. Same pattern as docs/messaging-transport-selection.md — portable
reference knowledge, kept OUT of CLAUDE.md (which holds THIS repo's rules).

Core points it lands:
- "Clean Architecture" is two things: the DEPENDENCY RULE (always-on, not
  earned, not in tension with VSA) and the 4-PROJECT STRUCTURE (the only
  part with ceremony, the only part the "is it worth it" question is about).
- VSA and Clean are orthogonal axes — organization/cohesion vs dependency
  direction. "Combine" = organize by feature + keep the domain decoupled.
- VSA does NOT auto-enforce the dependency rule; you enforce it on a
  spectrum: convention → architecture tests → project split. The middle
  rung (NetArchTest/ArchUnitNET) gives the SAME enforcement as the
  4-project split WITHOUT the ceremony, at the namespace level in a single
  project. Code example included.
- Two meanings of "combine": orthogonal axes + per-slice complexity
  gradient.
- Testcontainers shifted the calculus: integration-default for IO-touching
  code beats mock-heavy unit tests, which collapses the
  repository-interface-for-testability argument. But it's a Testing
  Trophy, not a pure rectangle — keep fast unit tests for pure domain
  logic; mind the Docker dependency + speed cost.
- The duplication tradeoff: keep cross-cutting concerns in pipeline
  behaviors (not per-slice), prefer duplication over the wrong
  abstraction; cost scales with slice count and bites hardest on pure CRUD.
- When-to-use table + common mistakes (incl. "don't add a repo interface
  per slice on EF", "don't 4-project-split just to get the dependency
  rule", "don't mix layered + sliced services in one solution").

README Documentation table updated to index it. No CLAUDE.md edit here
(kept separate to avoid colliding with the open promotion-signal PR #50,
which is where the in-repo deep-dive pointer will be added).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e87fcde9-3ab7-4fd2-9ece-49f5c7919bf3

📥 Commits

Reviewing files that changed from the base of the PR and between 6d1a344 and f4f71bb.

📒 Files selected for processing (1)
  • README.md

Walkthrough

This PR adds a new architecture decision guide documenting Vertical Slice Architecture (VSA) and Clean Architecture as orthogonal organizational and dependency concepts, with enforcement mechanisms, testing trade-offs, and a practical NextAurora example.

Changes

Architecture Decision Guide Documentation

Layer / File(s) Summary
Core positioning and enforcement mechanisms
README.md, docs/vsa-vs-clean-architecture.md
Reframes Clean Architecture into two separate concepts (dependency rule and multi-project layered structure), positions VSA and the dependency rule as orthogonal axes, and describes three enforcement rungs: convention/code review, architecture tests, and project splits. README updated with documentation index link.
Testing and duplication trade-offs
docs/vsa-vs-clean-architecture.md
Discusses testing strategy shifts enabled by modern integration tooling (Testcontainers), favoring integration-default tests for IO-touching handlers over mock-heavy unit tests. Analyzes VSA's primary cost (cross-slice duplication) and describes when duplication is manageable through shared middleware/pipelines.
Decision matrix, common mistakes, and worked example
docs/vsa-vs-clean-architecture.md
Provides "when to use which" guidance, lists common pitfalls (treating VSA and Clean as either/or, unnecessary repository wrappers for DB independence, over-applying integration tests to pure CRUD), and details NextAurora's applied structure: VSA folders with single-project enforcement via convention plus architecture tests, integration-default handler tests, and direct DbContext usage without repository wrappers.

🎯 1 (Trivial) | ⏱️ ~5 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and clearly summarizes the main change: adding a new decision guide document contrasting VSA with Clean Architecture, which matches the primary content of the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/vsa-vs-clean-guide

Comment @coderabbitai help to get the list of available commands and usage tips.

emeraldleaf added a commit that referenced this pull request May 29, 2026
Adds a deep-dive link from the refined "Promotion signal" section to the
new portable decision guide (docs/vsa-vs-clean-architecture.md, PR #51):
the CLAUDE.md section is NextAurora's specific rule; the doc is the
general two-meanings-of-Clean / enforcement-spectrum / testing-shift /
duplication-tradeoff reference behind it. Pointer only — no rule change.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@codecov

codecov Bot commented May 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/vsa-vs-clean-architecture.md (1)

1-205: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Propagate this new architecture pattern to canonical rule artifacts before merge.

This doc encodes reusable architecture-review patterns, but the required rule-propagation updates are missing from this PR (or an explicit deferral entry in docs/STATUS.md). Please sync the canonical governance files in the same change set or mark/document the deferral explicitly.

As per coding guidelines, "when encoding a pattern discovered via review, write to CLAUDE.md (most relevant section, new section only if no fit), .coderabbit.yaml path_instructions, .claude/agents/architecture-reviewer.md checklist, .claude/skills/ (if non-trivial multi-step), docs/STATUS.md (if deferred), and supporting docs (if the why deserves more than a one-liner)".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/vsa-vs-clean-architecture.md` around lines 1 - 205, The PR added a
VSA-vs-Clean Architecture guide but didn’t propagate the pattern to our
canonical governance artifacts; update CLAUDE.md (add the new pattern into the
most relevant section or create a new section), add path_instructions in
.coderabbit.yaml to reference the new doc, extend
.claude/agents/architecture-reviewer.md checklist with the new enforcement
options (rung 1/2/3 and NetArchTest example), add any multi-step guidance under
.claude/skills/ if needed, and either record a clear deferral entry in
docs/STATUS.md or include explicit “deferred” notes in the above files per the
coding guidelines.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@docs/vsa-vs-clean-architecture.md`:
- Around line 1-205: The PR added a VSA-vs-Clean Architecture guide but didn’t
propagate the pattern to our canonical governance artifacts; update CLAUDE.md
(add the new pattern into the most relevant section or create a new section),
add path_instructions in .coderabbit.yaml to reference the new doc, extend
.claude/agents/architecture-reviewer.md checklist with the new enforcement
options (rung 1/2/3 and NetArchTest example), add any multi-step guidance under
.claude/skills/ if needed, and either record a clear deferral entry in
docs/STATUS.md or include explicit “deferred” notes in the above files per the
coding guidelines.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 83daed9a-a04b-4b32-aa23-a5e80798e3b6

📥 Commits

Reviewing files that changed from the base of the PR and between 6f340be and 6d1a344.

📒 Files selected for processing (2)
  • README.md
  • docs/vsa-vs-clean-architecture.md

coderabbitai[bot]
coderabbitai Bot previously approved these changes May 29, 2026
@emeraldleaf
emeraldleaf merged commit 142d4a2 into main Jun 3, 2026
4 of 5 checks passed
@emeraldleaf
emeraldleaf deleted the docs/vsa-vs-clean-guide branch June 3, 2026 00:24
emeraldleaf added a commit that referenced this pull request Jun 3, 2026
…ject split (#50)

* chore(claude): refine the Clean promotion signal — dependency rule vs project split

Sharpens the "Promotion signal" section after a discussion surfaced that
the prior framing ("Clean is earned / for complex services") conflated two
separable things that both wear the name "Clean Architecture":

- The DEPENDENCY RULE (Domain -> nothing; IO at the edges) is already in
  force in VSA, applies at every scale, and is NOT what the promotion
  signal gates. Decoupling the domain from frameworks is always worth it.
- The MULTI-PROJECT STRUCTURE (4 csprojs) is the only part with ceremony
  and the only thing the promotion signal gates — all it buys over
  single-project VSA is compile-time enforcement of the dependency rule
  via project references.

Adds the real axis: how you ENFORCE the dependency rule, escalating with
the cost of a violated boundary — convention -> architecture tests ->
project split. Names the middle rung most teams skip: an architecture test
(NetArchTest / ArchUnitNET / Roslyn analyzer) asserting "Domain references
no EF/Infrastructure namespaces" enforces the same boundary the 4-project
split does, deterministically in CI, without the ceremony. So the project
split is rarely needed for enforcement alone — reach for it only when
domain complexity makes you want the compiler (not a test) to hold the
line, or when separate deploy/versioning units justify it.

New table row for the architecture-tests rung; existing "5+ aggregates"
row reframed as "when you want the compiler to hold the boundary" rather
than "consider Clean" (which blurred principle into structure).

Notes NextAurora enforces the rule today via convention + the
architecture-reviewer agent + CodeRabbit; adding architecture tests would
be the next rung without changing the VSA shape (a candidate future
improvement, not mandated here).

Paraphrase-drift audit: run /check-rules locally to audit paraphrases
against this diff. Done — the refinement is net-new nuance; no existing
See-CLAUDE.md marker paraphrases the promotion signal or the
dependency-rule-vs-structure distinction, and it's consistent with the
"Layer Dependencies" rule it references. No drift.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* chore(claude): point the promotion-signal rule at the VSA-vs-Clean guide

Adds a deep-dive link from the refined "Promotion signal" section to the
new portable decision guide (docs/vsa-vs-clean-architecture.md, PR #51):
the CLAUDE.md section is NextAurora's specific rule; the doc is the
general two-meanings-of-Clean / enforcement-spectrum / testing-shift /
duplication-tradeoff reference behind it. Pointer only — no rule change.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant