aboutsummaryrefslogtreecommitdiff
path: root/docs/architecture
diff options
context:
space:
mode:
Diffstat (limited to 'docs/architecture')
-rw-r--r--docs/architecture/README.md359
-rw-r--r--docs/architecture/v2-todo.org254
2 files changed, 613 insertions, 0 deletions
diff --git a/docs/architecture/README.md b/docs/architecture/README.md
new file mode 100644
index 0000000..e09efb0
--- /dev/null
+++ b/docs/architecture/README.md
@@ -0,0 +1,359 @@
+# Architecture Suite
+
+Four chained Claude Code skills for the full architecture lifecycle: **design**, **decide**, **document**, **evaluate**. Paradigm-agnostic (supports layered, hexagonal, microservices, event-driven, CQRS, DDD, and others). Language-aware (framework-agnostic checks work everywhere; language-specific linters augment when configured).
+
+## The Chain
+
+```
+ ┌─────────────────┐
+ New project → │ arch-design │ → .architecture/brief.md
+ └────────┬────────┘
+ │
+ (for each open decision)
+ │
+ ▼
+ ┌─────────────────┐
+ │ arch-decide │ → docs/adr/NNNN-*.md
+ └────────┬────────┘
+ │
+ (when ready to formalize)
+ │
+ ▼
+ ┌─────────────────┐
+ │ arch-document │ → docs/architecture/*.md
+ └────────┬────────┘ (dispatches to c4-analyze, c4-diagram)
+ │
+ (once code exists, periodically)
+ │
+ ▼
+ ┌─────────────────┐
+ │ arch-evaluate │ → .architecture/evaluation-YYYY-MM-DD.md
+ └─────────────────┘
+```
+
+Skills are standalone — invoke any one directly. The flow above is the canonical path; you can enter at any point if the prerequisite artifacts already exist.
+
+## What Each Skill Does
+
+### [arch-design](../../arch-design/SKILL.md)
+
+Elicits the architecture: intake (stakeholders, scale, team, timeline), quality-attribute prioritization, constraints, then proposes 2-4 candidate paradigms with honest trade-off analysis. Picks one with rationale. Lists open decisions that become ADRs.
+
+**Output:** `.architecture/brief.md`
+
+### [arch-decide](../../arch-decide/SKILL.md)
+
+Records significant technical decisions as ADRs. Five template variants (MADR, Nygard, Y-statement, lightweight, RFC). Covers ADR lifecycle (proposed / accepted / deprecated / superseded), review checklist, and `adr-tools` automation.
+
+**Output:** `docs/adr/NNNN-<title>.md`, plus an index at `docs/adr/README.md`.
+
+**Forked from [wshobson/agents](https://github.com/wshobson/agents) — MIT.**
+
+### [arch-document](../../arch-document/SKILL.md)
+
+Produces full arc42-structured documentation from the brief + ADRs + codebase. All twelve arc42 sections. Dispatches to `c4-analyze` (for code-present systems) and `c4-diagram` (for textual descriptions) for the diagrams in sections 3, 5, 6, and 7.
+
+**Output:** `docs/architecture/01-introduction.md` through `12-glossary.md`, plus diagrams under `docs/architecture/diagrams/`.
+
+### [arch-evaluate](../../arch-evaluate/SKILL.md)
+
+Audits the codebase against the brief + ADRs. Four framework-agnostic checks (cyclic deps, stated-layer violations, public API drift, forbidden deps). Opportunistically invokes language-specific linters if they're already configured in the repo.
+
+**Output:** `.architecture/evaluation-YYYY-MM-DD.md`
+
+## Installation
+
+These skills live in this rulesets repo alongside the other skills (`debug`, `add-tests`, `c4-analyze`, etc.). Install globally once:
+
+```bash
+make -C ~/code/rulesets install
+```
+
+This symlinks every skill (including the four `arch-*`) into `~/.claude/skills/`. Any Claude Code session on this machine will see them.
+
+To uninstall:
+
+```bash
+make -C ~/code/rulesets uninstall
+```
+
+To check install state:
+
+```bash
+make -C ~/code/rulesets list
+```
+
+## Optional: Language-Specific Linters
+
+`arch-evaluate` works without any external tooling — its framework-agnostic checks cover cycles, layer violations, API drift, and forbidden deps on any language Claude can read. **Installing the linters below is optional** and augments those checks with dedicated tooling: faster on large codebases, CI-friendly, and precise.
+
+Install only the ones you need for your active languages.
+
+### Python — import-linter
+
+Declarative import contracts. Config in `.importlinter` or `[tool.importlinter]` in `pyproject.toml`.
+
+```bash
+pipx install import-linter
+# or: pip install --user import-linter
+# or (in a uv-managed project): uv add --dev import-linter
+```
+
+Verify:
+
+```bash
+lint-imports --help
+```
+
+Example config (`.importlinter`):
+
+```ini
+[importlinter]
+root_package = myapp
+
+[importlinter:contract:layers]
+name = Core layers
+type = layers
+layers =
+ myapp.presentation
+ myapp.application
+ myapp.domain
+ myapp.infrastructure
+
+[importlinter:contract:framework_isolation]
+name = Domain isolation
+type = forbidden
+source_modules =
+ myapp.domain
+forbidden_modules =
+ django
+ fastapi
+```
+
+### TypeScript / JavaScript — dependency-cruiser
+
+Rich import analysis with a JS config file. The de-facto standard for TS architectural linting.
+
+```bash
+npm install --save-dev dependency-cruiser
+# or globally: npm install -g dependency-cruiser
+```
+
+Verify:
+
+```bash
+npx dependency-cruiser --version
+```
+
+Generate an initial config:
+
+```bash
+npx dependency-cruiser --init
+```
+
+Then edit `.dependency-cruiser.cjs` to encode your architecture. Example rule:
+
+```javascript
+module.exports = {
+ forbidden: [
+ {
+ name: 'domain-no-infrastructure',
+ severity: 'error',
+ from: { path: '^src/domain' },
+ to: { path: '^src/infrastructure' },
+ },
+ ],
+ options: { tsPreCompilationDeps: true, tsConfig: { fileName: 'tsconfig.json' } },
+};
+```
+
+### Go — golangci-lint (with depguard)
+
+`go vet` (part of the stdlib) covers built-in checks. `depguard` (via golangci-lint) enforces import rules.
+
+```bash
+# macOS
+brew install golangci-lint
+
+# Linux / anywhere with Go
+go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
+```
+
+Verify:
+
+```bash
+golangci-lint --version
+go vet ./...
+```
+
+Example `.golangci.yml`:
+
+```yaml
+linters:
+ disable-all: true
+ enable:
+ - depguard
+
+linters-settings:
+ depguard:
+ rules:
+ domain:
+ list-mode: lax
+ files:
+ - "$all"
+ - "!**/infrastructure/**"
+ deny:
+ - pkg: "github.com/yourorg/yourapp/infrastructure"
+ desc: "domain must not depend on infrastructure"
+```
+
+### Java — ArchUnit (v2+)
+
+Test-driven: architectural rules live in JUnit tests. Not invoked by `arch-evaluate` in v1.
+
+**Maven:**
+
+```xml
+<dependency>
+ <groupId>com.tngtech.archunit</groupId>
+ <artifactId>archunit-junit5</artifactId>
+ <version>1.3.0</version>
+ <scope>test</scope>
+</dependency>
+```
+
+**Gradle:**
+
+```groovy
+testImplementation 'com.tngtech.archunit:archunit-junit5:1.3.0'
+```
+
+Example rule (`src/test/java/archtest/LayerRules.java`):
+
+```java
+@AnalyzeClasses(packages = "com.yourorg.yourapp")
+class LayerRules {
+ @ArchTest
+ static final ArchRule layered =
+ layeredArchitecture().consideringAllDependencies()
+ .layer("Presentation").definedBy("..presentation..")
+ .layer("Application").definedBy("..application..")
+ .layer("Domain").definedBy("..domain..")
+ .whereLayer("Presentation").mayNotBeAccessedByAnyLayer()
+ .whereLayer("Application").mayOnlyBeAccessedByLayers("Presentation")
+ .whereLayer("Domain").mayOnlyBeAccessedByLayers("Application", "Presentation");
+}
+```
+
+Then run `mvn test` or `gradle test`.
+
+### C / C++ — include-what-you-use (v2+)
+
+Checks each source file's `#include` discipline. Not invoked by `arch-evaluate` in v1; listed for completeness.
+
+```bash
+# macOS
+brew install include-what-you-use
+
+# Arch Linux
+sudo pacman -S include-what-you-use
+
+# Ubuntu/Debian
+sudo apt install iwyu
+```
+
+Integrate via CMake:
+
+```cmake
+set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE include-what-you-use)
+```
+
+Verify:
+
+```bash
+include-what-you-use --version
+```
+
+## Typical Flow
+
+### New project
+
+```bash
+# 1. Shape the architecture
+# In Claude Code:
+/arch-design
+# Answer intake questions, rank quality attributes, review candidates.
+# Output: .architecture/brief.md
+
+# 2. Record each open decision
+/arch-decide
+# Once per significant decision. Output: docs/adr/0001-*.md, 0002-*.md, etc.
+
+# 3. Formalize (when ready)
+/arch-document
+# Generates all twelve arc42 sections + diagrams.
+# Output: docs/architecture/*.md
+
+# 4. Audit (once code exists)
+/arch-evaluate
+# Report at .architecture/evaluation-YYYY-MM-DD.md
+```
+
+### Existing project with no architecture docs
+
+```bash
+# 1. Retroactively capture
+/arch-design # reconstruct the brief from what exists
+/arch-decide # write ADRs for past decisions (date them honestly)
+/arch-document # produce current-state arc42 docs
+
+# 2. Audit against the reconstructed intent
+/arch-evaluate
+```
+
+### Continuous
+
+- Re-run `/arch-evaluate` periodically (on PR, before release, monthly)
+- Every significant new decision → `/arch-decide`
+- Brief or ADR changes → `/arch-document` to refresh
+
+## Where Things Land
+
+```
+<project-root>/
+├── .architecture/
+│ ├── brief.md ← arch-design
+│ └── evaluation-YYYY-MM-DD.md ← arch-evaluate
+├── docs/
+│ ├── adr/
+│ │ ├── README.md ← arch-decide (index)
+│ │ └── NNNN-<title>.md ← arch-decide
+│ └── architecture/
+│ ├── README.md ← arch-document (index)
+│ ├── 01-introduction.md … ← arch-document
+│ ├── 12-glossary.md
+│ └── diagrams/ ← arch-document (via c4-*)
+│ ├── context.svg
+│ ├── container.svg
+│ └── runtime-<scenario>.svg
+```
+
+## Dependencies Between Skills
+
+- `arch-decide` is standalone; nothing required from the others
+- `arch-document` reads the brief and ADRs; without them, it stubs sections as TODO
+- `arch-evaluate` requires the brief; without it, the skill stops and tells the user to run `arch-design`
+- `arch-document` dispatches to `c4-analyze` (if code exists) and `c4-diagram` (otherwise) — both live in this same rulesets repo
+
+## Versioning and Deferred Work
+
+v1 covers the four core skills with the chain above. The deferred feature list — CI integration, auto-generated linter configs, ArchUnit integration, DDD aggregate boundaries, etc. — is tracked at [`v2-todo.org`](v2-todo.org).
+
+## Licensing
+
+- `arch-design`, `arch-document`, `arch-evaluate` — part of this rulesets repo
+- `arch-decide` — forked from [wshobson/agents](https://github.com/wshobson/agents), **MIT**. See `arch-decide/LICENSE`.
+
+## Contributing / Modifying
+
+These are personal skills; fork as needed. If you change a skill and want to re-sync the global install symlink, re-run `make -C ~/code/rulesets install`. Symlinks point back at this repo, so edits propagate without re-install.
diff --git a/docs/architecture/v2-todo.org b/docs/architecture/v2-todo.org
new file mode 100644
index 0000000..4d40ad3
--- /dev/null
+++ b/docs/architecture/v2-todo.org
@@ -0,0 +1,254 @@
+#+TITLE: Architecture Suite — v2+ TODO
+#+AUTHOR: Craig Jennings
+#+DATE: 2026-04-19
+
+Deferred work for the arch-* skill chain. v1 ships with the four core skills
+and opportunistic linter integration. Items here extend capability,
+precision, or scope and were intentionally deferred.
+
+* About
+
+Each item lists motivation, scope, and the skill(s) it touches. Priority hints
+(=[#A/B/C]=) reflect rough judgement, not firm commitment. Rearrange freely.
+
+Related: [[file:README.md][README.md]] for the v1 architecture suite overview.
+
+* v2 Candidates
+
+** TODO [#A] Auto-generate linter configs from the brief :arch-evaluate:
+SCHEDULED: <2026-05-15 Fri>
+
+Today the user hand-writes =.importlinter= / =.dependency-cruiser.cjs= / =.golangci.yml=
+from the brief's declared layers. The skill should be able to emit a starter
+config for the detected language.
+
+*** Scope
+- Parse layers section of =.architecture/brief.md=
+- Emit minimal config matching declared structure
+- Place in repo with =--dry-run= mode to preview
+- Never overwrite an existing config without =--force=
+
+*** Complication
+- Each tool has different semantics (forbidden vs layer-based vs import rules)
+- Mapping from "paradigm + layers" to tool-specific rules has edge cases
+- Want to avoid generating wrong/incomplete rules that mislead users
+
+*** Touches
+- =arch-evaluate= (config generation)
+- =arch-design= (formalize the layers syntax in the brief)
+
+** TODO [#A] CI mode: exit codes and --fail-on :arch-evaluate:
+
+Today the skill produces a markdown report. For CI, need machine-readable
+output and non-zero exit on violations.
+
+*** Scope
+- =--output json=: structured findings for parsing
+- Exit code: 0 (no errors), 1 (errors present), 2 (tool failures)
+- =--fail-on=warning= flag for strict mode
+- =--delta-since=<git-ref>=: only report findings introduced since that ref
+
+*** Touches
+- =arch-evaluate= only
+
+** TODO [#A] ArchUnit integration (Java) :arch-evaluate:
+
+Java architectural linting happens via ArchUnit, which runs as JUnit tests.
+The skill needs to know how to invoke it and parse its output.
+
+*** Scope
+- Detect =archunit-junit5= dependency in =pom.xml= / =build.gradle=
+- Invoke via =mvn test -Dtest=*ArchTest*= or =gradle test --tests *ArchTest=
+- Parse JUnit XML or surefire reports for failures
+- Map to unified finding format
+
+*** Complication
+- ArchUnit requires someone to have written the rule classes
+- Skill could also suggest generating rule tests from the brief (overlap with auto-gen task above)
+
+*** Touches
+- =arch-evaluate= (invocation + parsing)
+
+** TODO [#B] include-what-you-use / cpp-linter integration (C/C++) :arch-evaluate:
+
+C and C++ have weaker architectural linting options than the dynamic
+languages. =include-what-you-use= is the main tool; needs CMake integration
+to run usefully.
+
+*** Scope
+- Detect =.iwyu.imp= or CMake option =CMAKE_CXX_INCLUDE_WHAT_YOU_USE=
+- Run a build with IWYU enabled, collect output
+- Parse and report
+
+*** Complication
+- Requires a full build (slow)
+- Output is verbose; much is noise (re-sorting includes vs. real violations)
+- May need a user-provided mapping file for vendored deps
+
+*** Touches
+- =arch-evaluate= (invocation + parsing)
+
+** TODO [#B] DDD aggregate boundary checks :arch-evaluate:
+
+When the brief declares DDD tactical patterns (aggregates, repositories,
+domain events), check that code respects the boundaries: aggregates only
+referenced via their root, repositories only for aggregate roots, events not
+crossing bounded contexts directly.
+
+*** Scope
+- Extend brief syntax to declare aggregates + bounded contexts
+- Framework-agnostic check: aggregate internals only accessed via root path
+- Framework-agnostic check: repositories match declared aggregate roots 1:1
+- Flag direct cross-aggregate references
+
+*** Complication
+- DDD is heterogeneous in practice — no single canonical structure
+- Risk of being too prescriptive
+
+*** Touches
+- =arch-design= (formalize DDD declaration in brief)
+- =arch-evaluate= (checks)
+
+** TODO [#B] Auto-detect declared architecture from existing code :arch-design:
+
+For retroactive briefs: instead of asking the user to describe their
+existing architecture, infer a likely layering from import patterns, propose
+it, and let the user confirm/edit.
+
+*** Scope
+- Dispatch to =c4-analyze= for module graph
+- Cluster modules into implied layers using dep direction + naming
+- Propose: "Looks like these layers: presentation → application → domain → infrastructure. Confirm or edit."
+- Save confirmed layering to brief §7
+
+*** Complication
+- Inference can mislead — mixed codebases produce bad clusters
+- Requires code organization that isn't already chaotic to work well
+
+*** Touches
+- =arch-design= only
+
+** TODO [#B] ADR ⇄ brief cross-referencing :arch-decide:
+
+Currently the brief links to "ADRs TBD" and ADRs don't link back. Bidirectional
+linking improves navigation and ensures the brief stays current.
+
+*** Scope
+- =arch-decide= adds a "Brief section" field to new ADRs
+- When an ADR is accepted, update brief §8 (Open Decisions) to check the box and link
+- =arch-document= §9 generates a cross-reference table
+
+*** Touches
+- =arch-decide= (write-back to brief)
+- =arch-document= (index table)
+
+** TODO [#B] Visual dependency graph output :arch-evaluate:
+
+Beyond text report, emit a visual graph of cycles and layer violations.
+
+*** Scope
+- Graphviz / mermaid output with violating edges highlighted in red
+- Optional per-layer coloring
+- Link to SVG/PNG from the markdown report
+
+*** Touches
+- =arch-evaluate= (output rendering)
+
+** TODO [#C] Expanded paradigm library :arch-design:
+
+Add more paradigm entries to the candidate-considered table in arch-design:
+CQRS+Event-Sourcing combined, saga orchestration, choreography, CRDTs,
+space-based, reactive, etc.
+
+*** Complication
+- More options isn't always better — risk of analysis paralysis
+- Must keep trade-off analysis honest per paradigm
+
+*** Touches
+- =arch-design= only
+
+** TODO [#C] Quality attribute scenario generator :arch-design:
+
+Given a top-ranked quality attribute ("performance"), generate concrete
+testable scenarios in the format: "Under X, the system should Y within Z."
+
+*** Scope
+- Scenario template per attribute class
+- Measurable by default; flag vague ones for the user
+
+*** Touches
+- =arch-design= (optional phase 2.5)
+
+** TODO [#C] Support for non-arc42 documentation formats :arch-document:
+
+Some teams prefer C4-only, ISO/IEC 42010 terminology, or a lighter 4+1 views
+format. Add alternate templates.
+
+*** Scope
+- Selectable =--format= in =arch-document=: arc42 (default), c4-only, 4+1, minimal
+- Each format maps a subset of content
+
+*** Complication
+- Duplicates effort; arc42 is already comprehensive
+- May mean maintaining parallel templates
+
+*** Touches
+- =arch-document= only
+
+** TODO [#C] PlantUML / Structurizr output :arch-document:
+
+Generate text-based architecture DSLs (PlantUML C4, Structurizr DSL) from the
+decomposition, for teams that prefer those toolchains.
+
+*** Scope
+- Output option in =arch-document=: emit structurizr or plantuml alongside markdown
+
+*** Touches
+- =arch-document= (via c4-* dispatch)
+
+** TODO [#C] ATAM-style trade-off analysis :arch-design:
+
+For complex decisions, enable a deeper Architecture Trade-off Analysis
+Method pass: identify sensitivity points, trade-off points, risks per
+paradigm option.
+
+*** Complication
+- ATAM is heavy; not appropriate for most projects
+- Optional mode; don't make it default
+
+*** Touches
+- =arch-design= (optional deep-dive)
+
+** TODO [#C] Interactive mode :arch-design:
+
+Instead of one-shot Q&A, walk the user through each phase as a guided
+conversation with branching based on answers.
+
+*** Complication
+- Hard to make conversational in a skill context
+- Probably belongs as a slash command workflow, not a skill
+
+*** Touches
+- =arch-design= (or a new =/arch-wizard= command)
+
+* Won't-Do
+
+** DONE Auto-implementation of architecture
+
+Generating code from a brief would sound appealing but crosses into tooling
+that's inherently scoped to a language/framework. Out of scope for an
+architectural skill suite. Leave to project-specific generators.
+
+** DONE Real-time collaboration
+
+These skills operate on filesystem artifacts (brief, ADRs, arc42 docs).
+Concurrent editing is git's problem, not the skills'.
+
+* Notes
+
+- Tag entries with the skill(s) they affect (=:arch-design:=, =:arch-decide:=,
+ =:arch-document:=, =:arch-evaluate:=) so you can filter.
+- Priority A items are what would most improve v1 for Craig's current stack
+ (Python / TS / Go).
+- Java and C/C++ integration (ArchUnit, IWYU) is A-priority when Craig starts
+ using those languages, B otherwise.