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.pyis the public use-case surface.model.pyis the authoritative home of rule lifecycle and evaluation ownership.policies.pyisolates replaceable evaluation behavior.runtime.pycoordinates sources, sinks, projections, and units of work.repository.pyexpresses persistence intent and rollback semantics.read_models.pyandprojections.pyremain 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 inspectwhen you want the derived state bundle before opening code. - Use
make tourwhen you want the public scenario route through the architecture. - Use
make verify-reportwhen you need executable evidence alongside that review. - Use
EXTENSION_GUIDE.mdwhen the architecture question is really a change-placement question. - Use
PROOF_GUIDE.mdwhen the main question is how aggregate decisions become reviewable evidence. - Use
PACKAGE_GUIDE.mdwhen 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.pywithout forcing a rewrite ofmodel.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