Skip to content

Architecture Guide

Guide Maps

graph LR
  family["Python Programming"]
  program["Python Object-Oriented Programming"]
  guide["Capstone docs"]
  section["Docs"]
  page["Architecture Guide"]
  proof["Proof route"]

  family --> program --> guide --> section --> page
  page -.checks against.-> proof
flowchart LR
  orient["Read the guide boundary"] --> inspect["Inspect the named files, targets, or artifacts"]
  inspect --> run["Run the confirm, demo, selftest, or proof command"]
  run --> compare["Compare output with the stated contract"]
  compare --> review["Return to the course claim with evidence"]

This capstone is intentionally small, but its shape is strict. The domain is not buried inside infrastructure, and the runtime does not quietly absorb domain rules. The goal is to show an object-oriented design where ownership stays legible under change.

Ownership boundaries

  • application.py is the public use-case surface.
  • model.py is the authoritative home of rule lifecycle and evaluation ownership.
  • policies.py isolates replaceable evaluation behavior.
  • runtime.py coordinates sources, sinks, projections, and units of work.
  • repository.py expresses persistence intent and rollback semantics.
  • read_models.py and projections.py remain downstream of events.

Why this shape matters

The aggregate should stay authoritative for domain change. The runtime should stay thin enough that replacing a source or sink does not change the rules of the domain. The projections should stay derived so read concerns do not mutate authoritative state.

Dependency direction

Surface May depend on Should not depend on
application.py use-case inputs, runtime coordination, aggregate-facing operations projection internals as a source of truth
model.py domain values, events, policy abstractions runtime adapters, sinks, or public command flow
policies.py rule-evaluation inputs and domain values repository or projection mechanics
runtime.py aggregate operations, repositories, projections, sinks, and sources projection state as an authority for domain decisions
read_models.py and projections.py emitted events and display needs aggregate mutation paths
repository.py storage semantics and rollback coordination hidden lifecycle or evaluation rules

Review routes for architecture questions

  • Use make inspect when you want the derived state bundle before opening code.
  • Use make tour when you want the public scenario route through the architecture.
  • Use make verify-report when you need executable evidence alongside that review.
  • Use EXTENSION_GUIDE.md when the architecture question is really a change-placement question.
  • Use PROOF_GUIDE.md when the main question is how aggregate decisions become reviewable evidence.
  • Use PACKAGE_GUIDE.md when the architecture question has already become a file route.

Architecture questions for review

  • What would break if rule activation lived in the runtime instead of the aggregate?
  • What would become harder to trust if the read models were updated directly?
  • Which extension should modify policies.py without forcing a rewrite of model.py?

Change placement

If the change is... Start in Why
a new rule lifecycle constraint model.py lifecycle authority belongs to the aggregate
a new evaluation mode policies.py variation should stay replaceable instead of widening the aggregate
a new sink or source integration runtime.py orchestration and adapters stay outside domain ownership
a new read model projections.py or read_models.py derived views should stay downstream of events
a persistence or rollback detail repository.py storage mechanics should adapt to the domain, not redefine it

Boundary ownership by responsibility

Boundary Owns Must not own
aggregate rule lifecycle, authority, and alert creation orchestration, projections, or persistence workflow
policy replaceable evaluation behavior aggregate authority or event publication
projection downstream read models and derived history authoritative lifecycle state
runtime coordination with sources, sinks, and units of work domain truth
persistence repository and unit-of-work boundaries domain decision-making
public surface CLI and bundle routes hidden authority not reachable from review routes

Anti-patterns this architecture rejects

  • runtime code deciding domain lifecycle transitions
  • projections mutating authoritative state
  • persistence concerns leaking into the aggregate's core rules
  • evaluation variability implemented as condition ladders spread across multiple files

Boundary drift review

Ask these during review before changing the code:

  • does this proposal make the runtime smarter than the aggregate about rule truth
  • does this proposal force a read model to become authoritative
  • does this proposal hide a domain rule inside persistence or adapter code
  • does this proposal widen several files because ownership was not settled first