Skip to content

Architecture principles

Six load-bearing principles. Every framework decision is auditable against them.

1. Screaming architecture

The file tree says what the system does, not what it's built with.

✅ Right

modules/submissions/
modules/enrollments/
modules/billing/
apps/learnflow/

❌ Wrong

src/services/
src/controllers/
src/utils/
src/middleware/

A new contributor opens the repo and sees the business: submissions, enrollments, billing. Not: services, controllers, utils. The tech is the medium, not the message.

2. Self-identifying files

Every filename reveals role + context. No naked types.ts, index.ts, utils.ts.

✅ Right

  • submit-answer.action.ts
  • submission.actor.ts
  • submissions.events.ts
  • auto-grade.reaction.ts
  • submissions-by-student.projection.ts

❌ Wrong

  • actions.ts (which actions?)
  • service.ts (what does it do?)
  • types.ts (whose types?)
  • index.ts (everything goes here)

A file's role should be obvious from git diff filename alone.

3. Conservation of meaning

Names preserve the user's reality through every layer. Code is the last link in a chain that starts with the persona narrative and runs through the brief, the journey, the event, the action, the handler.

✅ Right

The product brief says "Avi submits his answer to a Hebrew Letters exercise." The event is submissions.answer-submitted. The action is submissions.submit-answer. The handler is submit-answer.handler.ts. Open any file — Avi's reality is intact.

❌ Wrong

  • submissionEntity.create() — what is an "entity"?
  • processFormSubmission() — the user didn't submit a form, they submitted an answer
  • recordTransaction() — Avi doesn't think in transactions

4. One-author coherence

Every file looks like the same person wrote it. Naming, structure, comment style, error message tone, file organization.

Drift is the enemy. Drift = different files in the same codebase reading differently for the same reason. Most often introduced when team grows or LLMs touch code without context.

Counter-drift practice:

  • Conventions live in AGENTS.md + code review
  • Scaffold tools (nwire scaffold module <x>) inherit the canonical shape from a reference module
  • One person owns "the way" — even temporarily

5. Artisan engineering

Engineers AND artists. Every decision traces to "why this serves the user."

If you can't say why a primitive exists in terms of someone's lived experience (Avi confused → Avi clear; Dina overloaded → Dina informed), the primitive is in the wrong place.

The framework's own design follows this: defineAction exists because the user types a command. defineActor exists because a single submission has a lifecycle. stuckThresholds exists because Dina needs to know something is stuck before she misses an SLA.

6. Modeling ⊥ deployment

Domain code never imports from wires.

  • modules/submissions/ knows nothing about HTTP, queues, CLI, cron
  • wires/ know how to expose modules to a transport
  • topologies/ describe which apps run where
  • Actions, events, actors look identical regardless of runtime mode

A submit-answer test runs in-process. The same submit-answer ships over HTTP, over a queue worker, over a webhook handler. Same code; the wire chooses.

This is what makes the topology composer work — you can swap monolith for split deployment without rewriting domain code.

How they compose

Principle 1 (screaming) + principle 2 (self-identifying) → a tree where every file is its own descriptor. You stop needing a README to find things.

Principle 3 (meaning) + principle 4 (coherence) → a codebase that reads like one well-written essay. Onboarding shrinks.

Principle 5 (artisan) is the why behind every other principle. If a decision doesn't trace to user value, the answer is "don't ship it."

Principle 6 (modeling ⊥ deployment) is what makes Nwire's primitives the right shape — they describe what the system IS, separately from how it runs.

Audit

amit-architecture-review is a project skill that audits any folder / file / PR against the six principles. Run it on a structural change:

bash
claude --skill=amit-architecture-review --target=modules/billing/

The skill walks the artifact and reports principle violations with concrete remediation suggestions.

See also

MIT licensed.