[Proposal] The Design Principle Behind VSA × DDD × Multi-Tier Harness: Share What's Stable, Separate What Changes
This article was generated by AI. The accuracy of the content is not guaranteed, and we accept no responsibility for any damages resulting from use of this article. By continuing to read, you agree to the Terms of Use.
- Target audience: Tech leads, platform engineering leads, and architects running AI coding and Agentic AI at medium-to-large scale
- Prerequisites: Basics of Vertical Slice Architecture (VSA), DDD strategic design concepts such as Bounded Context, hands-on experience using AI coding agents at work
- Reading time: ~35 min
Positioning of this article: This is a new integration proposal, not a report on an organization that ran VSA × DDD × the multi-tier harness in production. It is a connection design inferred from the related patterns of VSA × AI, DDD × multi-agent, and harness design respectively, and it closes with a multi-angle examination of the benefits, drawbacks, and exit conditions.
Overview
Over the past two weeks this blog has published three articles on design decisions in AI development — VSA is a good fit for AI development as 1 slice = 1 context, the VSA × DDD hybrid has several directions running in parallel, and split the harness into organization / shared / project tiers and invest heavily in data and external-tool organizational conventions.
The three articles look like separate themes. VSA is about code structure, DDD is about boundary design, and the harness is about the operational platform for AI agents. But in the field, where each must be turned into an implementation, there are moments when the design decisions collide. VSA says “split things up — don’t generalize.” The multi-tier harness says “generalize — don’t reinvent the wheel in every project.” On the surface they are exact opposites.
This collision is invisible as long as you read the three articles as separate layers. But the moment a single architect decides “which skills go into our shared harness,” the two meet on the same desk. Pour “the domain’s opinion” into the shared tier, and the premature generalization VSA dislikes comes back through the operational platform. Leave the shared tier empty, and the harness loses its value.
The claim of this article is this. VSA’s “split things up” and the multi-tier harness’s “generalize” are not a contradiction, because they operate at different levels of abstraction. Both are two expressions of a single principle: share what’s stable, separate what changes. VSA guards against the premature sharing of business-domain abstractions. The multi-tier harness guards against the scattering of operational-platform abstractions. Once you accept that the layer it’s fine to share (operations, conventions, data) is different from the layer you must not share (business logic, domain interpretation), the two can be used consistently under the same decision axis.
And what mediates this unified principle is DDD’s Bounded Context. A Bounded Context draws the line “beyond here, the domain’s opinion changes.” VSA cuts feature slices vertically inside that boundary. The shared harness tiers stand side by side while respecting that boundary (shared backend / shared compliance / shared inventory, and so on). The CLI guardrail (the mycorp-pr pattern from the previous article) becomes the tool that hard-enforces that boundary.
From the perspective of bringing this back to implementation, the article reads as a single flow. Start small with VSA → the pain of knowledge sharing leads to the shared harness tier → the pain of domain divergence leads to DDD → the pain of regulatory governance leads to the organization harness. The central proposal is that the same decision principle (stable → share, changing → separate) runs through all four stages. The crux of this flow is that the harness appears twice (the shared tier and the organization tier), and that the trigger for DDD is not “scale” but “domain divergence.”
In §1, this article lays out a map of the three articles and their collision points; §2 covers the underlying principle that dissolves the surface-level contradiction; §3 makes the connection points concrete; §4 covers anti-patterns; and §5 covers staged adoption. The following §6 makes the implementation patterns concrete on a typical stack — Next.js (multiple sites) + some Go APIs — and §7 gives a multi-angle evaluation. That this is a proposal, not a case study is emphasized repeatedly to the end.
Sister articles: This article is an integration proposal built on top of three foundational articles. If you have already read any of VSA × AI, VSA × DDD, or the multi-tier harness, the context here snaps into focus much faster.
§1. A Map of the Discussion, and the Collision Points
First, let’s lay the three articles out on a single map and make explicit which layer and which decision axis each one handles.
What each of the three articles covers
| Article | Scope | Central decision axis |
|---|---|---|
| VSA × AI | Code structure (within one repository) | Vertical split per feature slice, minimizing shared abstractions |
| VSA × DDD | Code structure + domain boundaries | Grouping by Bounded Context, adopting strategic design only |
| Multi-tier harness | AI agent operational platform | Separation of responsibility across organization / shared / project, heavy investment in the data layer |
The three articles handle separate layers (code structure, domain design, operational platform). But in the era of AI coding agents, the same prompts and context flow through all three layers. When an agent decides “which slice to edit,” when it decides “which Bounded Context’s rules to follow,” when it decides “which shared skill to use” — all of this happens within the same thought process. If the design decisions are not consistent across the three articles, the agent’s judgment splits.
Making the collision points concrete
The collision happens in three situations.
Collision 1: Should business logic go into a shared skill?
The shared tier of the multi-tier harness holds “skills reusable across multiple projects.” Operate it naively, and domain-leaning skills — an “order processing skill,” a “payment validation skill,” an “inventory allocation skill” — easily flow into the shared tier.
From VSA’s standpoint, this is the textbook case of “premature generalization.” The “order” in the Sales Context and the “order” in the Logistics Context are different concepts. Cram them into a single “order processing skill” in the shared tier, and the Context-specific differences get crushed.
Conversely, if you simply say “don’t write anything in the shared tier,” each project starts copy-pasting similar skills, and the very problem the multi-tier harness set out to solve resurfaces.
Collision 2: How do you reconcile Bounded Context boundaries with the harness’s shared boundaries?
In the multi-tier harness, it is intuitive to cut the shared tier along a tech-stack axis — “shared backend / shared frontend / shared security.” In DDD, on the other hand, you cut Bounded Contexts along a domain axis — “sales / inventory / compliance.”
When the two are orthogonal, shared skills step across Context boundaries. For example, if a “shared backend” skill behaves identically in both the Sales Context and the Inventory Context, the per-Context differences (terminology, invariants, validation rules) disappear.
Collision 3: How do you align slice boundaries with the unit of context supply?
VSA works on the premise that “1 slice = 1 feature = 1 context” is what gets handed to the agent. But the multi-tier harness also assumes that “organizational RAG supplies a wide context.” When the relationship between the two is fuzzy, while editing code inside a slice the agent may pull terminology from a different Context out of the organizational RAG and get the naming conventions wrong.
flowchart TB
A[One edit task for an AI agent] --> B{Which layer's decision applies?}
B --> C[Code-structure decision<br>which slice to edit]
B --> D[Domain decision<br>which Bounded Context's rules]
B --> E[Operational decision<br>which shared skill to call]
C -.->|inconsistent| F[Collision<br>judgment splits]
D -.->|inconsistent| F
E -.->|inconsistent| F
These three collisions are invisible as long as you read each article’s discussion in isolation. This is exactly why an integration proposal is needed.
§2. Dissolving the Surface-Level Contradiction — The Underlying Principle
VSA’s “split things up” and the multi-tier harness’s “generalize” sit at different levels of abstraction. What VSA guards against is premature generalization of the business domain1; what the multi-tier harness guards against is scattering of the operational platform2 — the background for each is detailed in the original articles.
What this article wants to claim here is that these two concerns are merely two expressions of the same principle.
What’s fine to share is what is “stable as an organization and unchanging over the long term.” What should be separated is what “changes meaning depending on context, or becomes obsolete in the short term.”
Made concrete, it looks like this.
| Property | Fine to share | Should be separated |
|---|---|---|
| Code structure (VSA) | Cross-cutting technical infrastructure (HTTP middleware, ORM, logger) | Business logic, domain interpretation, functional requirements |
| Domain design (DDD) | Ubiquitous Language (within a Context), the meta-patterns of strategic design | Concepts across Contexts, Aggregate definitions, invariants |
| Operational platform (harness) | Organizational RAG / data / access control, external-tool organizational-convention CLIs, Must lint | Generic workflows (to be replaced by official features), API wrappers (to be replaced by official features) |
The decision axis is the same across all three layers. The “timescale of change, and the locality of change” determines whether something can be shared.
flowchart TB
P[Unified principle<br>stable: share<br>changing: separate]
P --> V[VSA-layer decision<br>tech base: share<br>business: separate]
P --> D[DDD-layer decision<br>strategic: share<br>tactical: separate]
P --> H[Harness-layer decision<br>data/conventions: share<br>generic workflow: separate]
Think under this single principle, and the collisions of §1 can be reinterpreted.
- Collision 1: Should business logic go into a shared skill? → No. Business logic is a “changing thing” whose meaning shifts per Context. The shared tier holds only operational patterns that contain no Context interpretation — “the etiquette of RAG search,” “the guardrails for PR creation,” “the mode transitions of code review.”
- Collision 2: The relationship between Bounded Context and the harness’s shared boundaries → The shared tier does not step across Context boundaries. Creating a tech-stack-axis shared tier is fine in itself, but its contents must be limited to “technical infrastructure that contains no Context interpretation.” Context-specific rules stay inside the Context.
- Collision 3: Slice boundaries vs. the unit of context supply → A VSA slice = the unit the agent edits; a Bounded Context = the unit of vocabulary the agent references. RAG should respond with Context tags, and the agent should query RAG only after recognizing which Context the slice it is currently editing belongs to.
This is the central finding of the article. The decision axes of the three articles all run on the same principle, and the collisions occur when you mistake “which level of abstraction shares what.”
§3. Making the Connection Points Concrete — Wiring the Three Layers Into One Consistent Design Decision
To turn the unified principle into operations, you need to define concrete connection points. This section presents three.
Connection point 1: A VSA slice = the unit of context supplied to the agent
Connect the “1 slice = 1 context” principle from VSA × AI3 with the multi-tier harness.
When an agent receives an edit task, the boundary of the slice folder becomes the natural division of the context window. The shared harness tier’s Explore → Plan → Implement workflow2 should operate on this unit. Concretely:
- Explore mode: Load all files in the target slice, do not reference adjacent slices (but do check the function signatures of dependencies)
- Plan mode: The plan document should fit “what changes in this slice” onto one page
- Implement mode: The moment an edit ripples into another slice, raise a warning (detection of a VSA violation)
This means mechanically enforcing VSA’s “localize the coupling” principle through the harness’s workflow implementation. The workflow body lives in the shared tier (a generic pattern), but the boundary determination of “what is a slice” lives in the project tier (the project-specific features/ path, etc.).
Connection point 2: A DDD Bounded Context = the parallel boundary of the shared harness
Cut the shared harness tier along the tech-stack axis alone — “shared backend / shared frontend / shared security” — and the problem of Collision 2 in §1 occurs. Instead, incorporate the Bounded Context axis as one of the parallel axes of the shared tier.
As a concrete example, consider the Compliance Context (what a financial institution would call “KYC/AML”). This Context has its own terminology (customer, transaction, risk assessment), its own invariants (transaction amount thresholds, the validity period of identity verification), and its own validation flows (suspicious transaction reporting, regulatory reporting). Group these into a “Compliance Context shared harness.”
flowchart TB
subgraph ORG["🏢 Organization harness"]
OG1["RAG: ADRs, incidents"]
OG2["Must lint: security"]
end
subgraph SBE["🛠 Shared backend<br>tech-stack axis"]
BE1["Go templates"]
BE2["gRPC conventions"]
end
subgraph SCO["🛠 Shared compliance<br>Bounded Context axis"]
CO1["KYC glossary"]
CO2["AML validation flow"]
CO3["Regulator report tmpl"]
end
subgraph PRJ["📦 Project harness"]
PR1["Sales project"]
PR2["Inventory project"]
end
PRJ ==> ORG
PR1 -.->|reference| SBE
PR1 -.->|reference| SCO
There are two points.
First, there is not one shared tier — multiple stand in parallel. Tech-axis shared tiers (shared backend, shared frontend) and Context-axis shared tiers (compliance, order lifecycle, inventory management) may stand side by side. This is consistent with the “selective sharing — neither share everything nor separate everything” shown in the “Learning to Share” paper4.
Second, limit the contents of a Context-axis shared tier to “what is stable within that Context.” The Ubiquitous Language established within the Context, settled strategic decisions, validation logic that rarely changes. Concepts whose meaning changes across Contexts must not rise into the shared tier.
Connection point 3: A CLI guardrail = hard enforcement of the Bounded Context
The CLI guardrail pattern presented by the multi-tier harness (mycorp-pr, etc.)2 was originally discussed in the context of “external-tool organizational conventions.” This can also be applied to boundary enforcement of DDD’s Bounded Context.
Concretely, restrict communication that crosses a Context boundary to going through a CLI. For example:
- Force inter-Context calls to always go through a CLI tool, as in
mycorp-context call --from=sales --to=inventory --event=order-placed --schema=... - Inside the CLI, enforce schema validation and a translation step for the ACL (Anti-Corruption Layer)
- Block violations (direct calls, schema violations) in CI
This is the same direction as the framing Nikita Golovko presented at AI Coding Summit 2026 — “a Bounded Context as the agent’s area of responsibility, the contract as the schema, the ACL as the semantic firewall”5. Golovko presented a conceptual framing; this article’s additional proposal is that the implementation mechanism can be a CLI guardrail.
The benefits of hard-enforcing CLI mediation are, as discussed in the multi-tier harness article2:
- Reusable across agents (common to Claude Code / Codex / Cursor)
- Capable of hard enforcement (a blocked path, not persuasion)
- Humans can use the same abstraction
- Observable (exit codes, structured logs)
Add mechanical enforcement of DDD boundaries to this, and you get a direct answer to the “we drew a Bounded Context but it isn’t upheld in operations” problem.
The three-layer connection on one page
Summarizing the three connection points on one page looks like this.
flowchart TB
subgraph ENG["An AI agent's edit task"]
T1["Receive task"]
T2["Identify slice"]
T3["Determine Context"]
T4["Call shared skill"]
T5["Edit & validate"]
T1 --> T2 --> T3 --> T4 --> T5
end
T2 -.->|conn. 1| V["VSA slice boundary<br>= 1 context unit"]
T3 -.->|conn. 2| B["Bounded Context<br>= shared-tier parallel axis"]
T4 -.->|conn. 3| C["CLI guardrail<br>= hard-enforced Context boundary"]
Through these three connection points, the three articles operate as one consistent design decision. Only when the chain of unified principle (stable / changing) → connection points (made concrete) → guardrails (enforcement) is complete does organization-level consistency stand up.
§4. Anti-Patterns — Typical Failures
An integration proposal comes with typical failure patterns. No direct case study has been found, but here are four inferred from the anti-patterns of related fields.
Anti-pattern 1: The shared tier carries architectural opinions
This is the pattern to watch most. A skill placed in the shared tier implicitly imposes a specific architectural decision (event-driven vs. synchronous RPC, Aggregate vs. Anemic Model, etc.).
For example, suppose a “shared PR-creation skill” has a built-in rule: “a PR that modifies an Aggregate Root must add a Domain Event publication step.” This may make sense in the Sales Context, but in the Compliance Context, event publication becomes subject to audit, so a separate flow may be needed. The shared tier’s opinion overwrites the Context-specific judgment.
The countermeasure is to thoroughly narrow shared-tier skills to “How” (operational procedures) and include no “What” (business judgment) at all. Push judgment back to the Context layer. Note that Bardia Khosravi’s collection of AI coding rules6 also aims to “present predictable patterns,” not to impose business judgment.
Jellyfish’s survey of platform engineering anti-patterns7 also lists “The Platform for Everything” (over-design — a central team trying to absorb every case into templates and becoming a bottleneck) and “Mandated Adoption” as representative failures. When a central team carries “our best practices,” the field’s Context-specific circumstances get crushed. The same trap applies to the AI harness’s shared tier.
Anti-pattern 2: Overusing Bounded Context as the harness’s shared boundary
There is also a failure in the reverse direction. Make the Bounded Context “the sole parallel axis of the harness’s shared tier,” and cross-tech-stack generalization (per-language templates, CI conventions, logger configuration) becomes hard to implement.
The countermeasure is to let the shared tier stand in parallel along two axes — a “tech axis” and a “Context axis” — and explicitly tolerate overlap between them. For example, both a “shared Go backend” and a “shared Compliance Context” may be referenced in the same project, and it’s fine if a function like validateTransaction() is called from both. VSA’s principle that duplication is cheaper than premature abstraction8 applies here too.
Anti-pattern 3: CLI guardrails slow down development speed
Apply CLI guardrails (mycorp-pr, etc.) to Context boundaries, and the friction of having to go through a CLI even for simple changes appears. The agent’s degrees of freedom also drop.
There are two countermeasures.
First, have the shared-tier skill automate the act of calling the CLI itself. When an agent creates a PR, instead of writing “please call mycorp-pr” into the prompt, the “PR creation skill” calls mycorp-pr internally. From the agent’s perspective the abstraction stays as the skill name, and the CLI handles the mechanical enforcement.
Second, narrow the boundaries you hard-enforce. Forcing every function call through a CLI is excessive. Narrow it to just three categories — inter-Context communication, external-tool operations (GitHub, Slack, Jira), and deployment / production operations — and the guardrails work while development speed is preserved.
Anti-pattern 4: Prioritizing integration consistency so much that you reject all local optimization
After adopting the integration, situations frequently arise where “for local optimization, a different choice would be better” in each layer. For example: “this Context wants to put its Aggregate in the shared tier,” “this tech-axis shared tier wants a convenience function spanning two Contexts,” and so on.
Treat the integration’s consistency (the stable / changing principle of §2) as absolute, and you end up rejecting even the legitimate requests for local optimization, losing the field’s productivity and trust. Conversely, allow too much local optimization and the integration’s benefits collapse.
The countermeasure is to operate the unified principle not as “a norm to always follow” but as “a baseline that incurs accountability when deviated from.” In exchange for allowing exceptions, leave the rationale for the deviation and the exit conditions in an ADR. This is an operational problem specific to integration adoption — it does not arise when you run VSA × DDD × harness separately.
Note that the “build all three layers at once” anti-pattern is a matter of the incremental principle discussed in §4-1 of the multi-tier harness article2, so this article handles it under staged adoption in §5.
§5. Staged Adoption — One Step at a Time, From the Layer Where the Pain Appears
The big picture — mapping triggers to what you introduce
Before reading the details, here is the big picture of the four stages, as a table mapping “trigger → what you introduce.”
| Stage | Trigger (signal) | What you introduce |
|---|---|---|
| 1. Start small | One repository, one project | VSA |
| 2. Knowledge sharing | You start copy-pasting the same skills and conventions into another repository | Shared harness tier (tech-axis skills, templates, CLI) |
| 3. Domain divergence | “The same word is used with different meanings” happens frequently | DDD (Bounded Context) + Context-axis shared tier |
| 4. Regulation & governance | Regulatory response and company-wide compliance become a management issue | Organization harness (RAG, Must lint, audit) |
Let me emphasize two points in this mapping table.
Point 1: The harness appears in two separate stages
Of the multi-tier harness2, the shared tier enters at stage 2 with the pain of knowledge sharing, but the organization tier comes at stage 4 with the pain of governance and regulatory response. Think “introduce the harness all at once in one stage,” and you build the organizational RAG before Context boundaries are visible, ending up with a single knowledge base without Context tags (redoing the Context split later is expensive).
Point 2: The trigger for DDD is not “scale” but “domain divergence”
Even at 100 people, if it’s a single domain, DDD is unnecessary; even at 30 people, if there are three business areas, DDD is needed. Decide on the “are Bounded Contexts visible?” axis, not the scale axis. Frame it as “we got bigger, so DDD,” and you approach the textbook failure of layering DDD onto simple CRUD and making it heavy (the Dogmatic DDD critique in §3 of VSA × DDD).
The reason this order is realistic is that this order is natural both in the order the pain appears and in the order the investment ROI stands up. Below, let’s look at the details of each step.
Step 1: Mature your operations with VSA alone
At first, adopt VSA in one repository, one project. This is the area discussed in VSA × AI.
What you should acquire in this phase is “a feel for drawing feature-slice boundaries” and “the line between what’s fine to share and what isn’t.” The Rule of Three (don’t abstract until the same code appears three times)8, Bogard’s “don’t share business logic” principle1, the judgment to adopt only the strategic design of VSA × DDD9 — establish these as team norms.
In this phase you don’t yet need to make Bounded Contexts explicit. In fact, organizations that don’t see multiple Contexts inside one project are the majority.
Sign of completion: When you start copy-pasting the same skills and the same patterns across multiple feature slices. This is the cue for the next phase.
Step 2: When the pain emerges, stand up the shared harness tier
When duplication of operational patterns becomes visible across slices and across projects, start on the shared tier of the multi-tier harness2.
What matters in this phase is to cut the shared tier along the “tech axis” only. Before making Bounded Contexts explicit, stand up one or two tech-stack-common shared tiers (shared backend, shared frontend, shared security).
Why do the tech axis before the Context axis? Because the tech axis is “easy for everyone to agree on.” A Go API skeleton, a React form component, a CI configuration — these contain no Context-specific judgment and are purely about technical infrastructure. They are the ideal footing for the team to get used to operating a shared tier.
In parallel, stand up the external-tool organizational-convention CLI (mycorp-pr, etc.)2. This too contains no Context axis, so it can be introduced as an extension of the tech-axis shared tier.
Sign of completion: When 3–5 shared-tier skills are in operation and are actually reused across multiple projects. A level where you can feel the duplication being resolved.
Step 3: When the domain pain emerges, introduce Bounded Context
Introduce DDD’s strategic design only after the problem of Context mismatch has surfaced. Concrete signals:
- The same word (“order,” “customer,” “inventory”) frequently carries different meanings in different features
- The agent gets naming conventions wrong (writing inventory-side code in sales-side terminology, etc.)
- Dependencies between slices increase and VSA’s benefits weaken
In this phase, bring in the discussion of VSA × DDD9. Make Context boundaries explicit, and let the Context-axis shared tier stand in parallel with the tech-axis shared tier. Extend the CLI guardrail (connection point 3 in §3) to hard-enforce Context boundaries.
Sign of completion: When 3–4 Bounded Contexts are recognized and inter-Context communication is established via a CLI with schemas. When the Ubiquitous Language is documented per Context.
Step 4: Stand up the organization harness (RAG, governance)
Having gone through steps 1–3, stand up the organization harness tier at the timing when regulatory response or company-wide compliance becomes a management issue. By this point you should have multiple shared tiers standing in parallel, Context boundaries made explicit, and CLI guardrails in effect.
Design the organizational RAG to return Context-tagged responses. So that the agent can distinguish “the ‘customer’ in the Sales Context” from “the ‘customer’ in the Compliance Context,” include Context tags in the RAG response metadata.
Apply Must lint (security, compliance) across Contexts. These are items that “the organization must absolutely never violate,” so they sit above the Context boundaries.
Why do the organization harness last? Build the organizational RAG before Context boundaries are visible, and it becomes a single knowledge base without Context tags. Redoing the Context split later is expensive.
flowchart TB
S1[Step 1<br>Mature VSA alone<br>1 project] --> S2
S2[Step 2<br>Tech-axis shared tier<br>+ CLI guardrails] --> S3
S3[Step 3<br>Bounded Context<br>+ Context-axis shared tier] --> S4
S4[Step 4<br>Organization harness<br>RAG, Must lint, audit]
There may be the counterargument that “building it all at once is faster.” But as with the discussion in §4-1 of the multi-tier harness2, the incremental approach has a higher final investment efficiency. Proceeding while checking at each step whether “the pain is actually appearing” lets you avoid unnecessary abstraction.
§6. A Concrete Example — Implementation Patterns on Next.js (Multiple Sites) + Go API
An abstract integration proposal alone makes it hard to grasp a concrete picture to bring back to your own organization. This section makes the contents and connection points of the three layers concrete, on the premise of a typical stack — “running multiple sites in Next.js, with some APIs written in Go.”
6-1. The assumed stack configuration
Premises:
- monorepo (pnpm workspace + Turborepo): multiple Next.js sites under
apps/<site>/, multiple Go API services underservices/<api>/ - Next.js: making use of App Router, Server Components, Server Actions
- Go: gRPC or HTTP/JSON API, VSA under
internal/<context>/features/ - Shared packages: UI components, Context-shared domains, common CLI tools under
packages/
Directory structure (example):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
repo/
├── apps/
│ ├── admin/ # admin console site
│ ├── marketing/ # marketing site
│ └── customer/ # customer-facing site
├── services/
│ ├── billing-api/ # Go: billing API
│ └── notification-api/ # Go: notification API
├── packages/
│ ├── ui-shared/ # shared UI components
│ ├── domain-auth/ # Auth Context shared domain
│ └── tools-mycorp/ # mycorp-* CLI family
└── harness/
├── org/ # organization harness tier
├── shared-frontend/ # Next.js shared tier (tech axis)
├── shared-go/ # Go shared tier (tech axis)
└── shared-auth/ # Auth Context shared tier (Context axis)
There are two reasons to make harness/ an independent directory. First, to keep agent-facing skill definitions and human-facing documentation in one place. Second, so that when shared tiers increase (the state in §3-2 where the tech axis and the Context axis stand in parallel), each one’s area of responsibility can be physically separated and visually grasped.
6-2. How to cut VSA slices concretely
On the Next.js side: Map App Router Route Groups to VSA slices. Place everything for one feature (page, Server Action, data fetching, tests) under app/(features)/<feature>/.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apps/admin/
└── app/
├── (features)/
│ ├── product-listing/
│ │ ├── page.tsx # UI
│ │ ├── actions.ts # Server Action
│ │ ├── query.ts # data fetch (API call)
│ │ └── product-listing.test.ts
│ ├── product-editing/
│ │ ├── page.tsx
│ │ ├── actions.ts
│ │ ├── schema.ts # Zod validation schema
│ │ └── product-editing.test.ts
│ └── inventory-adjustment/
│ └── ...
└── api/ # API Route as needed
On the Go API side: VSA under internal/<context>/features/<feature>/. Keep handler.go, command.go, store.go, and tests in one place.
1
2
3
4
5
6
7
8
9
10
11
12
13
services/billing-api/
└── internal/
├── billing/ # Bounded Context: billing
│ ├── domain/ # minimal Aggregates/VOs
│ ├── acl/ # translation of input from other Contexts
│ └── features/
│ ├── creating_invoice/
│ │ ├── handler.go
│ │ ├── command.go
│ │ └── creating_invoice_test.go
│ └── cancelling_subscription/
│ └── ...
└── shared/ # truly cross-cutting things
The implementation of connection point 1 (a VSA slice = the unit of context supply) is written into CLAUDE.md as a convention for the agent: “Complete an edit task within a single (features)/<feature>/ or features/<feature>/ folder. When it ripples into another slice, make it explicit in Plan mode.”
6-3. How to draw Bounded Contexts
When you run multiple Next.js sites, a site does not become a Context. A site is a unit of UI; a Context is a unit of domain.
The following is a typical, stack-independent split example, but on this stack the Next.js sites and the Go API services end up running across multiple Contexts:
| Context | Domain owned | Related sites | Related services |
|---|---|---|---|
| Auth | Users, sessions, permissions | All sites | auth-api (Go) |
| Content | Products, categories, media | admin, customer | content-api (Go) |
| Billing | Plans, invoices, payments | admin, customer | billing-api (Go) |
| Notification | Email, push, webhooks | All sites | notification-api (Go) |
| Marketing | Campaigns, A/B, analytics | marketing | (completed in Next.js Server Actions) |
Points:
- The
marketingsite “uses” the Auth Context but does not “own” it: the marketing site’s(features)/lead-capture/checks whether the user is authenticated via the Auth Context’s ACL. The Marketing Context owns “leads” and “campaigns,” not “users.” - The same “user” concept differs across Auth, Billing, and Marketing: Auth handles “can they sign in,” Billing handles “are they a billing target,” Marketing handles “are they a targeting attribute.” The model differs within each Context.
- Some Contexts, like the Marketing Context, have no Go API: a Context can hold even when completed in Next.js Server Actions. “A Context = a microservice” is false.
The implementation of connection point 2 (a Bounded Context = a shared-tier parallel axis) puts a Context-axis shared tier such as harness/shared-auth/ in parallel with harness/shared-frontend/ (the tech axis). packages/domain-auth/ consolidates the Auth Context’s Ubiquitous Language (types, errors, flows), and packages/domain-billing/ consolidates the Billing Context’s. Do not create a cross-Context “package that gathers all the types” like packages/types/ — gathering types whose meaning differs across Contexts into one package leads directly to §4 anti-pattern 1 (the shared tier carries architectural opinions).
6-4. Concrete examples of CLI guardrails
Let’s make connection point 3 (a CLI guardrail = hard enforcement of a Context boundary) concrete on this stack.
Example 1: A slice-scaffolding CLI
1
2
3
4
5
6
7
# scaffold a Next.js VSA slice
mycorp-feature new --type=nextjs --site=admin --name=product-listing
# → apps/admin/app/(features)/product-listing/{page.tsx, actions.ts, query.ts, *.test.ts}
# scaffold a Go VSA slice
mycorp-feature new --type=go --context=billing --name=creating_invoice
# → services/billing-api/internal/billing/features/creating_invoice/{handler.go, command.go, *_test.go}
Make it a rule via a skill that the agent “calls mycorp-feature new when adding a new feature.” This mechanically aligns naming, placement, and test-file generation.
Example 2: Enforcing inter-Context calls
1
2
3
4
5
6
7
# call a Go API (a different Context) from a Next.js site
mycorp-context call \
--from=apps/customer \
--to=billing-api \
--action=create-invoice \
--schema=billing.v1.CreateInvoiceRequest
# internally: confirm the contract schema exists, confirm the ACL translation exists, attach the auth token
Code that directly calls fetch('http://billing-api/...') is forbidden by a custom ESLint rule (packages/tools-mycorp/lint/) and by CI. On the Go side too, direct imports from internal/<context-A>/ into internal/<context-B>/ are forbidden by a custom go vet check. This hard-enforces Context boundaries at the code level.
Example 3: PR-creation guardrails
1
2
3
4
5
6
mycorp-pr create
# internally:
# - confirm no edits outside the slice boundary are included (if they are, demand a Plan document)
# - confirm approval via CODEOWNERS
# - require approval from both Context owners for cross-Context changes
# - detect test fixtures that may contain PII
Example 4: Deployment guardrails
1
2
mycorp-deploy --service=billing-api --env=prod
# internally: pre-production-deploy approval, Context owner notification, rollback procedure generation
Place these CLIs in packages/tools-mycorp/, used with the same interface by both agents and humans. Scaffold the implementation with AI and tune it to your organizational conventions. The first version stands up in 1–2 days — throwing a mycorp-feature scaffolding task at Claude Code / Codex and iterating on the tuning is a realistic approach.
6-5. A Next.js + Go version of the staged-adoption map
Reinterpret the abstract four steps of §5 on this stack.
Step 1 (VSA alone): Start from one site, apps/admin/, plus one service, services/billing-api/. Establish the VSA structure of App Router + (features)/ and the Go internal/billing/features/ structure. Do not make Bounded Contexts explicit (implicitly one Context), and make the slice boundaries and naming conventions explicit in CLAUDE.md.
Step 2 (tech-axis shared tier): The time you add apps/customer/ and apps/marketing/. Stand up packages/ui-shared/ with a pnpm workspace and share common Server Component parts. Consolidate App Router conventions, Server Action conventions, and test strategy in harness/shared-frontend/. Consolidate Go handler templates and error-handling patterns in harness/shared-go/. In parallel, stand up mycorp-feature and mycorp-pr in packages/tools-mycorp/.
Step 3 (Bounded Context + Context-axis shared tier): The time you notice through pain that Auth, Billing, and Notification are separate domains. Carve out services/auth-api/ and services/notification-api/, or increase the internal/<context>/ directories inside billing-api. Stand up packages/domain-auth/ and packages/domain-billing/ as the consolidation places for Context Ubiquitous Language. Enforce inter-Context calls with mycorp-context call.
Step 4 (organization harness): Ingest ADRs, incident history, and design documents into the organizational RAG with Context tags. Integrate PII detection, auth-bypass pattern detection, and Context-boundary violation detection into CI as Must lint. Consolidate audit logs in harness/org/. Have the RAG attach metadata such as “this is an Auth Context document” to its responses — this reduces accidents where the agent confuses terminology across Contexts.
flowchart TB
NS1["Step 1<br>apps/admin/<br>+ services/billing-api/<br>establish VSA"] --> NS2
NS2["Step 2<br>pnpm workspace<br>+ packages/ui-shared<br>+ mycorp-feature/pr"] --> NS3
NS3["Step 3<br>services/<ctx>-api/<br>+ packages/domain-<ctx><br>+ mycorp-context call"] --> NS4
NS4["Step 4<br>org RAG w/ Context tags<br>+ PII/Context-violation lint<br>+ harness/org/"]
6-6. Caveats on this stack
Let’s lay out the pitfalls specific to the Next.js + Go combination.
- The boundary between Server Components and Server Actions: Mix Client/Server within a VSA slice, and the agent confuses the boundary. Make the position and intent of
use client/use serverexplicit inCLAUDE.md. Make it a convention to generateactions.tsas Server-Action-only andpage.tsxas Server-Component-by-default at scaffolding time. - The
(features)notation of Route Groups: App Router Route Groups do not appear in the URL, so the agent sometimes overlooks the structure. Mechanically enforce, viamycorp-feature new, the convention of always placing things under a Route Group. - Go gRPC vs. HTTP/JSON: Decide early whether the schema language for inter-Context communication is gRPC (proto) or OpenAPI. The internal implementation of
mycorp-context callchanges. If proto, makepackages/proto/the single source of contract schemas, and have the Next.js side reference the same schema with@bufbuild/connect-webor the like. - Next.js cache invalidation: Include in the skill the convention of calling
revalidatePath/revalidateTagwhen data changes in a Server Action. This is a spot the agent tends to forget; putting a “TODO comment for revalidation after data changes” into themycorp-feature newscaffold reduces accidents. - The temptation of type sharing across Bounded Contexts: As touched on in §6-3, do not create a cross-Context type package like
packages/types/. Instead, place only “DTOs sent and received between Contexts” inpackages/contracts/orpackages/proto/, and confine the domain types internal to a Context withinpackages/domain-<context>/. - Forgetting the auth check in Server Actions: Server Actions can be hit by anyone, so always pass them through the Auth Context’s ACL. Including a
requireAuth()call as mandatory in theactions.tsscaffold ofmycorp-feature newprevents the accident of the agent omitting it.
§7. Multi-Angle Evaluation and Limitations — Benefits and Risks Specific to the Integration
The benefits and drawbacks of adopting each article (VSA × AI / VSA × DDD / multi-tier harness) on its own are detailed in the originals. This section narrows to the benefits that stand up only when you adopt the three simultaneously, and the risks that occur precisely because you integrated. For the benefits and risks of VSA alone, DDD alone, or the multi-tier harness alone, see the “Limitations of VSA” section of VSA × AI, §7 of VSA × DDD, and §5-2 of the multi-tier harness.
Benefits specific to the integration
Here are the effects that, as a matter of logical coherence, can be expected if the integration proposal is adopted (emphasizing again that there is no empirical validation in a case study). These are effects that stand up only when integrated — they do not come out of the discussion of the individual articles.
- Consistency of design decisions: Because there is a single principle running through the three layers (stable / changing), new decisions (what goes in the shared tier, where to cut a Context, what to apply the CLI guardrail to) can be evaluated on the same axis. Run each article separately and you hesitate, for each new decision, over “which article’s norm do I apply.”
- Avoidance of premature abstraction extends to the operational-platform layer: VSA’s concern (premature generalization of business abstractions) is applied to the design of the harness’s shared tier as well. You can structurally prevent the accident of “business judgment” slipping into the shared tier. This is an integration effect not discussed in the individual articles.
- Mechanical enforcement of Bounded Context: A Bounded Context that had stayed at the level of conceptual framing gets hard-enforced via a CLI guardrail (the harness’s implementation mechanism). Boundary maintenance, which with DDD alone relied on “discipline” and “culture,” is supported at the operational-platform level. This is an effect that stands up only through the direct connection of DDD × harness.
- Consistency of agent judgment: Because slice boundaries, Context boundaries, and shared-tier boundaries are all aligned under the same principle, the agent does not hesitate over “which conventions to follow.” When each layer is designed in isolation, the agent wavers between conventions during AI coding.
Risks specific to the integration
The integration proposal has an aspect where the risks of related fields accumulate, plus risks that newly arise from combining the three layers. This section narrows to the latter (for the former, see the sections of the individual articles cited at the start).
Risk 1: The cognitive load of the integration
Implementing the integration proposal is far more cognitively demanding for a team than reading the three articles separately. It requires a foundational understanding of VSA, DDD, and the multi-tier harness each, and the integration’s benefits don’t stand up unless all three layers are in place. In teams of medium scale or below, “investing equally in every layer” may itself be impossible. The §5 design of building one step at a time, from the layer where the pain appears, exists for this reason.
Risk 2: Where the operational responsibility that runs through the three layers lives
Even if you place an owner for each layer, the integration collapses without someone responsible for watching “consistency across layers.” The shared harness tier owner tends to make “increasing the number of shared skills” their success metric, and the VSA / DDD owners tend to make “upholding the rules in my own area” theirs. A cross-cutting role that actually reviews the integration’s decision axis (is it fine to share / should it be separated) becomes necessary. This is an organizational problem that newly arises at integration adoption and is written in none of the individual articles.
Risk 3: The trade-off between local optimization and integration consistency
As discussed in §4 anti-pattern 4, treat integration consistency as absolute and you end up rejecting legitimate requests for local optimization. Conversely, allow too much local optimization and the integration’s benefits collapse. This trade-off does not appear in the individual articles — it is a problem specific to integration adoption. An operational rule that makes deviations explicit in ADRs becomes necessary.
Risk 4: The absence of a direct case study
This proposal is a connection design inferred from the related patterns of VSA × AI3, DDD × multi-agent51011, and harness design2, and as of May 2026, no direct case study of an organization running VSA × DDD × the multi-tier harness can be found. Implementation case studies exist for each individual article (in particular, multiple templates are listed for VSA × DDD in §1 of VSA × DDD), but there is no three-layer integration case study. You need to be prepared that early adopters will be the ones hitting the failure patterns.
Risk 5: The chained debt of maintaining prompt conventions
As arXiv 2604.0499012 shows, AI agents are implicitly making architectural decisions via prompts. Every design decision in this proposal (VSA slice boundaries, Bounded Context, CLI conventions, RAG context supply) does not function unless it is made explicit as prompts, skill definitions, and convention documents for the agent. Integrate the three layers, and the volume of prompt-convention maintenance accumulates too. Maintaining even one layer is hard work, and you end up needing to maintain conventions where three layers interlock. This is a clearly heavier burden than running the individual articles separately, and it is a cost specific to integration adoption.
And these integration-specific risks sit on top of the background of “the organization-level productivity paradox of AI development.” There is a survey showing that while 92.6% of developers use AI, the organization-level productivity gain stays around 10%13. This article’s conclusion argues that “organization-level productivity starts to move with a design decision that runs through the three layers,” but that is not automatically guaranteed. Before investing in the integration proposal, a step of measuring where your own organization’s productivity gap lies comes first — this is the same caveat each individual article points out, but in an integration proposal that invests in all three layers, the cost accumulates, so the importance of this premise check rises even further.
Adoption conditions and exit lines
Decide adoption by “which pain is appearing,” not by “organizational scale” (as discussed in §5 point 2, the scale axis produces misjudgment). Organizational scale is no more than a rough guide for where pain tends to appear.
| Signal appearing | Recommended stance | Scale guide (reference) |
|---|---|---|
| Neither knowledge silos, domain divergence, nor regulation has surfaced | This proposal is excessive. Run VSA alone; move to the next when the pain appears | up to 10 people |
| Copy-pasting of skills and conventions has started in another repository | Up to step 2 (VSA + tech-axis shared tier + CLI). Do not make DDD explicit | 10–30 people |
| Plus, “the same word is used with different meanings” happens frequently | Up to step 3 (+ Bounded Context + Context-axis shared tier). The organization harness is a minimal version | 30–100 people |
| Plus, regulatory response and company-wide compliance become a management issue | Up to step 4 (full integration). A dedicated platform team structure | 100+ people |
Scale roughly correlates left → right, but it is correlation, not causation. An organization of 30 people with three business areas is row 3; an organization of 100 people with a single domain is row 2 — such cases are not rare.
Signals that you should retreat:
- Business logic has started flowing into shared-tier skills → §4 anti-pattern 1. Refactor shared-tier skills to “narrow to How”
- CLI guardrails are noticeably slowing down development speed → §4 anti-pattern 3. Narrow the boundaries you hard-enforce
- Cases of rejecting the field’s legitimate local optimization for the sake of integration consistency are increasing → §4 anti-pattern 4. Shift to an operation that allows deviations via ADRs
- People frequently squabble over the boundary determination of Bounded Contexts → insufficient foundational understanding of DDD strategic design. Prioritize training and coaching
- AI agent judgment keeps splitting → prompt-convention maintenance has been deferred. Prioritize maintaining
CLAUDE.md/.cursorrules
Limitations
- This article is a proposal, not a case study: a connection design inferred from the related patterns of three articles
- The unified principle running through the three layers is just one framing: a different framing (for example, “locality of responsibility,” “frequency of change”) might reach the same conclusion. The “stable / changing” principle of this article is not the unique answer
- The evolution of the AI coding agent side is fast: there is a high chance that “Bounded-Context-tagged RAG” and “Context-aware skills” will be officially built in within 1–2 years. This proposal is a framing of “the areas you currently have to build yourself” as of May 2026, and assumes a review on a half-year cycle
- Political and cultural factors are not solved by this proposal: in a state where “the central team is not trusted” or “the discussion of Context boundaries is distorted by politics,” technical framing alone will not move things
Conclusion
VSA × DDD × the multi-tier harness are three design discussions handling separate layers. But on a single architect’s desk, they operate on the same decision axis. This article connected the three articles as one integration proposal.
The core message in one line:
The principle of “share what’s stable, separate what changes” is common to code structure (VSA), the operational platform (multi-tier harness), and domain design (DDD). Only when you turn the three layers into one consistent design decision does organization-level AI development productivity start to move.
Let’s lay out the three proposals.
| Proposal | Content | Risk specific to the integration |
|---|---|---|
| Principle | VSA’s “split things up” and the harness’s “generalize” are not a contradiction because they sit at different levels of abstraction. Both are two expressions of the “stable / changing” principle | The trade-off between local optimization and integration consistency. An ADR operation for deviations is needed |
| Connection points | A VSA slice = the unit of context supply / a Bounded Context = a shared-tier parallel axis / a CLI guardrail = hard enforcement of a Context boundary | The absence of a direct case study of the three-layer integration. Early adopters hit the failure patterns |
| Staged adoption | The order of VSA → tech-axis shared tier → Bounded Context → organization harness | The integration collapses without a cross-cutting role watching consistency across layers |
Decide adoption by which pain is appearing. When copy-pasting of skills and conventions appears, the shared tier; when the same word starts being used with different meanings, Bounded Context; when regulation becomes a management issue, the organization harness. Organizational scale is no more than a rough guide; the essence is the signal.
“Just build all three layers anyway” is the failure pattern this article warns against most.
This article is a new proposal. It will take time before direct case studies appear. If it is worth trying ahead of the curve in your organization, the prudent thing is to start by confirming the operational maturity of VSA alone. An organization where VSA is functioning has a high chance of seeing this proposal’s effects in the transition to §5 steps 2–4. An organization where VSA is not yet functioning gets a higher investment efficiency by reading VSA × AI before the integration discussion of this article.
One action you can try today: List the skills, templates, and conventions that exist in your organization’s shared tier (or shared-tier candidates), and put a “How (operational procedure)” or “What (business judgment)” label on each. Those labeled “What” are candidates to be pushed back to the Context layer. The more bloated an organization’s shared tier, the more likely a large amount of “What” has slipped in. In 30 minutes that structure comes into view.
Related Articles
Take a look at other articles related to this theme:
- Why Vertical Slice Architecture Is a Good Fit for AI Development — the VSA × AI discussion that is the foundation of this article
- How to Combine VSA and DDD in AI Development — a map of VSA × DDD and its several directions
- Multi-Tier Harness Engineering — The 3-Layer Model and a Data-Layer-Centered Investment Strategy — the other foundation of this article, the multi-tier harness model
- Context Engineering for the Organization — From Individual Craft to Organizational Capability — the positioning of the organizational RAG layer
- How to Build an AI-Native Engineering Team — organization and design when leveraging AI at team scale
References
References corresponding to the citation numbers in the text are listed in numerical order.
Other references (not cited by number in the text)
- Harness engineering: leveraging Codex in an agent-first world - OpenAI (2026). An internal case study achieving ~1 million lines and ~1,500 PRs over 5 months with zero lines of manual code. The origin of this article’s “multi-tier harness” discussion. 【Reliability: High】
- Harness engineering for coding agent users - Martin Fowler (April 2026). A conceptual framing of the outer harness. 【Reliability: High】
- Agent as Bounded Context (Part 1) - Philipp Kostyra, Medium (August 1, 2025). Proposes two models, Cognitive Agent / Workspace. Related to this article’s “Bounded Context = shared-tier parallel axis” discussion. 【Reliability: Medium】
- Designing Scalable Multi-Agent AI Systems: Leveraging Domain-Driven Design and Event Storming - DZone (June 12, 2025). Applies DDD + Event Storming to multi-agent, but points out the difficulty of defining boundaries for complexity management. A reference for this article’s “adoption conditions” discussion. 【Reliability: Medium】
Vertical Slice Architecture - Jimmy Bogard (April 19, 2018). The origin of VSA. Presents “minimize coupling between slices, maximize coupling within a slice” and “don’t share business logic between features.” 【Reliability: High】 ↩︎ ↩︎2
Multi-Tier Harness Engineering — The 3-Layer Model and a Data-Layer-Centered Investment Strategy - A previous article on this blog (May 14, 2026). Presents the multi-tier harness model, the boundary line of in-house investment, and the CLI guardrail pattern. 【Reliability: Own article】 ↩︎ ↩︎2 ↩︎3 ↩︎4 ↩︎5 ↩︎6 ↩︎7 ↩︎8 ↩︎9 ↩︎10
Why Vertical Slice Architecture Is a Good Fit for AI Development - A previous article on this blog (April 26, 2026). Discusses the design principle of 1 slice = 1 context and its affinity with AI coding. 【Reliability: Own article】 ↩︎ ↩︎2
Learning to Share: Selective Memory for Efficient Parallel Agentic Systems - arXiv:2602.05965 (February 2026). A selective memory-sharing mechanism between parallel agents. Demonstrates an efficient middle ground that is “neither share everything nor separate everything.” 【Reliability: Medium-High】 ↩︎
From Prompt Spaghetti to Bounded Contexts: DDD for Agentic Codebases - Nikita Golovko, Siemens AI Portfolio Architect, AI Coding Summit (February 26, 2026). Presents Bounded Context, contract schemas, ACL, and Context Map as four principles. 【Reliability: Medium】 ↩︎ ↩︎2
Backend Coding Rules for AI Coding Agents: DDD and Hexagonal Architecture - Bardia Khosravi, Medium (July 12, 2025). DDD/Hexagonal conventions for AI coding agents. Aims to present predictable patterns. 【Reliability: Medium】 ↩︎
9 Platform Engineering Anti-Patterns That Kill Adoption - Jellyfish (2025). Lays out nine anti-patterns (Rebranding the Operations Team / The Field of Dreams Fallacy / The Magpie Platform / Building the Front End First / The Platform for Everything / Neglecting the Day 2 Reality / The Skill Concentration Trap / Mandated Adoption / Tracking the Wrong Metrics). 【Reliability: Medium】 ↩︎
Vertical Slice Architecture: Where Does the Shared Logic Live? - Milan Jovanović. A discussion of placing shared logic in VSA. Lays out the Rule of Three (don’t abstract until something appears three times) and the principle that “duplication is cheaper than the wrong abstraction.” 【Reliability: Medium】 ↩︎ ↩︎2
How to Combine VSA and DDD in AI Development - A previous article on this blog (May 13, 2026). Lays out the directions of the VSA × DDD hybrid and several combination options. 【Reliability: Own article】 ↩︎ ↩︎2
Applying domain-driven design principles to multi-agent AI systems - James Croft, Microsoft Senior Software Engineer (April 8, 2026, updated May 4, 2026). An individual publication applying DDD’s Bounded Context and Ubiquitous Language to multi-agent AI. 【Reliability: Medium】 ↩︎
Transforming Travel: How Domain-Driven Design Unlocks the Power of Agentic Travel AI Systems - AWS Builder Center (September 4, 2025). A case study applying DDD’s Bounded Context to agentic AI and defining the natural boundaries of specialized agents (airline, hotel, etc.). 【Reliability: Medium-High】 ↩︎
Architecture Without Architects: How AI Coding Agents Shape Software Architecture - Phongsakon Mark Konrad et al., arXiv:2604.04990 (April 5, 2026). Demonstrates that AI coding agents implicitly make architectural decisions via prompts. Reports a code-size variation of 141–827 lines on the same task. 【Reliability: Medium-High】 ↩︎
93% of Developers Use AI. Why Is Productivity Only 10%? - ShiftMag (2026). Reports the “AI productivity paradox” in which 92.6% of developers use AI assistants while organization-level productivity gain stays around 10%. 【Reliability: Medium】 ↩︎