---
schema_id: architecture
schema_version: 1
applies_to: aiwiki/architecture/**/*.md
filename_pattern: "{topic}.md"
hard_cap_lines: 400
soft_target_lines: [100, 250]
required_frontmatter:
  schema_id: { type: string, equals: architecture }
  schema_version: { type: integer }
  scope: { type: string, pattern: "^(project|subsystem:.+)$" }
  date: { type: date }
  status: { type: enum, values: [active, proposed, superseded] }
required_sections:
  - "## The shape"
  - "## Components"
  - "## Boundaries"
  - "## Tradeoffs"
section_order: strict
citation_rule: required-in-components
---

# Schema: architecture (system-shape doc)

## Purpose

An architecture file describes the shape of a subsystem — what its parts are, what's in and out of scope, what tradeoffs were taken. The page answers "what is this system? what does each piece do? where does it stop?" so future contributors don't have to reverse-engineer.

**One file per topic.** Multiple focused files (`data-layer.md`, `auth-flow.md`, `event-bus.md`) — NOT one giant `architecture.md`. A 400-line file forced into existence by combining unrelated subsystems is unreadable.

## When to write one

- During Phase 5 codification (`harden`) — extract architecture from the locked prototype
- When a subsystem grows past ~3 files and a "what does this do" overview becomes valuable
- After a refactor that meaningfully reshapes a subsystem (write the new shape; mark the old one `superseded`)

Do NOT write an architecture file for: a single function or class (write a comment in the code), a feature you haven't built yet (write a plan in `.forge/work/`), an entire codebase summary (split by subsystem).

## File location and naming

- Path: `aiwiki/architecture/{topic}.md`
- Topic: kebab-case, names the subsystem or concern (not the document type)

Examples: `data-layer.md`, `auth-flow.md`, `event-bus.md`, `frontend-state-model.md`.

## Required frontmatter

| Field | Type | Notes |
|---|---|---|
| `schema_id` | string | Must equal `architecture` |
| `schema_version` | integer | — |
| `scope` | string | `project` / `subsystem:<name>` |
| `date` | ISO date | When this shape was codified or last refreshed |
| `status` | enum | `active` (current) / `proposed` (not yet implemented) / `superseded` (old shape; link successor) |

## Required sections

| Section | Purpose | Format |
|---|---|---|
| `## The shape` | What it looks like at a glance | Mermaid diagram OR ≤5-sentence prose summary |
| `## Components` | What each part does | Bulleted list with citations to the actual code |
| `## Boundaries` | What's in scope, what's out, and where the seams are | Bullets — explicit "in" and "out" |
| `## Tradeoffs` | What was rejected and why | Link to ADRs in `aiwiki/decisions/` |

## Line caps

- Hard cap: 400 lines (LINT fails above)
- Soft target: 100-250 lines

If a subsystem genuinely needs >400 lines to describe, split it: `auth-flow.md` + `auth-token-storage.md` + `auth-session-lifecycle.md` rather than one mega-file.

## Citation rules

- `## Components` MUST cite the responsible files/symbols with `file:line@<sha7>` or `symbol` form
- `## The shape` may use Mermaid (no citations needed) or prose (cite if making code claims)
- `## Tradeoffs` should link to ADRs that capture the decisions
- LINT auto-fills missing `@<sha7>` on first save

## Skeleton

```markdown
---
schema_id: architecture
schema_version: 1
scope: subsystem:auth
date: 2026-05-10
status: active
---

## The shape

```mermaid
flowchart LR
  Client -->|credentials| AuthHandler
  AuthHandler -->|verified| TokenIssuer
  TokenIssuer -->|signed token| Client
  Client -->|token| ProtectedRoute
  ProtectedRoute -->|verify| TokenValidator
```

## Components

- `AuthHandler` ([src/auth/handler.ts#authHandler](src/auth/handler.ts)) — accepts credentials, dispatches to credential validator
- `TokenIssuer` ([src/auth/token.ts#issueToken](src/auth/token.ts)) — signs JWT with HS256; lifetime 24h
- `TokenValidator` ([src/auth/middleware.ts#validateToken](src/auth/middleware.ts)) — verifies signature + expiry on every protected request

## Boundaries

**In scope**: credential validation, token issuance, token verification middleware.

**Out of scope**: user CRUD (lives in [aiwiki/architecture/users.md](aiwiki/architecture/users.md)), password reset flow (lives in [aiwiki/architecture/password-reset.md](aiwiki/architecture/password-reset.md)), MFA (deferred — see [aiwiki/decisions/0023-mfa-deferral.md](aiwiki/decisions/0023-mfa-deferral.md)).

## Tradeoffs

- HS256 over RS256: chosen for single-service deployment ([aiwiki/decisions/0008-jwt-algorithm.md](aiwiki/decisions/0008-jwt-algorithm.md))
- 24h token lifetime over refresh-token pair: chosen for simplicity at MVP scale ([aiwiki/decisions/0009-token-lifetime.md](aiwiki/decisions/0009-token-lifetime.md))
- Stateless JWT over session-store pattern: chosen for horizontal scalability ([aiwiki/decisions/0007-stateless-auth.md](aiwiki/decisions/0007-stateless-auth.md))
```
