Python Object-Oriented Programming Capstone¶
Guide Maps¶
graph LR
family["Python Programming"]
program["Python Object-Oriented Programming"]
guide["Capstone docs"]
section["README"]
page["Python Object-Oriented Programming Capstone"]
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 a compact monitoring-system reference implementation. It exists to make the course concrete: value objects, entities, rule lifecycles, aggregate roots, evaluation policies, read models, runtime adapters, and unit-of-work boundaries are all exercised in runnable code instead of only in chapter prose.
Use this capstone for¶
- learning how the course’s ownership rules look in one executable system
- reviewing where domain logic ends and orchestration begins
- proving one design claim with the smallest honest command or saved bundle
Do not use this capstone for¶
- memorizing file names before you know which boundary you are reviewing
- jumping straight to the strongest proof route when the question is still vague
- treating the runtime or CLI as if they were the source of domain authority
The scenario is deliberately human and operational:
- a team defines monitoring rules for a service
- rules move from draft to active to retired
- incoming metric samples are evaluated against those rules
- incidents are published without letting downstream views control domain state
- orchestration stays outside the aggregate so the domain model remains readable
What it models¶
- threshold-based monitoring rules with explicit lifecycle states
- a
MonitoringPolicyaggregate root that owns rule transitions and evaluation - multiple evaluation policies: threshold, consecutive breach, and rate of change
- domain events for registration, activation, retirement, and alert triggering
- read models for active-rule indexing and incident history
- a
MonitoringRuntimefacade with source and sink adapters - an in-memory unit of work with rollback semantics
Run it¶
From this directory:
Or from the repository root:
make PROGRAM=python-programming/python-object-oriented-programming capstone-walkthrough
make PROGRAM=python-programming/python-object-oriented-programming proof
Documentation set¶
All supporting capstone guides live under docs/. The root stays focused on the
entry route while still linking the complete local documentation set:
- GUIDE_INDEX.md
- FIRST_SESSION_GUIDE.md
- COMMAND_GUIDE.md
- OWNERSHIP_BOUNDARIES.md
- SCENARIO_BOUNDARY_MAP.md
- PROOF_GUIDE.md
- ARCHITECTURE.md
- DOMAIN_GUIDE.md
- SCENARIO_GUIDE.md
- RETIREMENT_SCENARIO_GUIDE.md
- RATE_OF_CHANGE_SCENARIO_GUIDE.md
- RULE_LIFECYCLE_GUIDE.md
- EVENT_FLOW_GUIDE.md
- BUNDLE_GUIDE.md
- MANIFEST_GUIDE.md
- CHANGE_RECIPES.md
- RUNTIME_GUIDE.md
- PROJECTION_GUIDE.md
- PUBLIC_API_GUIDE.md
- SCENARIO_SELECTION_GUIDE.md
- SOURCE_GUIDE.md
- COURSE_STAGE_MAP.md
- TOUR.md
- PACKAGE_GUIDE.md
- TEST_GUIDE.md
- TARGET_GUIDE.md
- INSPECTION_GUIDE.md
- EXTENSION_GUIDE.md
First session route¶
If this is your first honest pass through the capstone, use this order:
Read FIRST_SESSION_GUIDE.md for the stable local route, then come back to this README for the broader guide list and review routes.
Review routes¶
COMMAND_GUIDE.mdexplains which command or saved bundle best matches the current question.make inspectwrites a learner-facing inspection bundle with summary, lifecycle, and history outputs.make inspect-timelineprints the ordered scenario flow when you need sequence before proofs.make inspect-retirementprints the before-and-after retirement scenario when you need full lifecycle cleanup in one route.make inspect-rate-of-changeprints the alternate evaluation-mode scenario when you need a policy-seam example.make inspect-jsonprints the default scenario as stable structured JSON when you need a machine-readable review surface.make tourwrites the walkthrough bundle with the scenario story and matching local guides.make PROGRAM=python-programming/python-object-oriented-programming capstone-walkthroughis the published repository-root walkthrough route that builds the same saved learner-facing bundle.make verify-reportwrites the executable verification report bundle with test results and captured state.make confirmruns the strongest local confirmation route.make proofbuilds the published learner-facing review route.
Use BUNDLE_GUIDE.md when you want the relationship between those saved directories kept explicit.
Route by reader goal¶
| If you want to... | Start with | Then |
|---|---|---|
| understand the domain before reading code | GUIDE_INDEX.md, this README, DOMAIN_GUIDE.md, and RULE_LIFECYCLE_GUIDE.md |
make PROGRAM=python-programming/python-object-oriented-programming capstone-walkthrough and TOUR.md |
| inspect ownership boundaries file by file | OWNERSHIP_BOUNDARIES.md and PACKAGE_GUIDE.md |
SOURCE_GUIDE.md and ARCHITECTURE.md |
| pick the smallest scenario for the current pressure | SCENARIO_BOUNDARY_MAP.md |
the matching scenario guide and inspect route |
| confirm one design claim with evidence | PROOF_GUIDE.md |
make inspect or make verify-report |
| review the full capstone as a learner-facing artifact | make tour |
make proof |
| run the strongest local confirmation route | make confirm |
make proof if you need the published bundle |
What a good first read should settle¶
- what the system is modeling in plain operational language
- what the main domain terms mean before the file tree gets involved
- where the learner-facing application surface ends
- which object is authoritative for lifecycle and rule state
- which routes are for inspection, walkthrough, verification, and full proof
Guided review route¶
| Review question | Inspect first | What to conclude | Strongest proof route |
|---|---|---|---|
| Do the core value and entity boundaries make sense? | src/service_monitoring/model.py, tests/test_policy_lifecycle.py |
Identity, equality, and lifecycle semantics are explicit rather than accidental | make inspect |
| Is evaluation behavior owned by replaceable policy objects instead of condition ladders? | src/service_monitoring/policies.py, tests/test_policy_evaluation.py |
Variation lives in named policy surfaces, not inside the aggregate | make verify-report |
| Does orchestration stay outside the aggregate? | src/service_monitoring/runtime.py, src/service_monitoring/application.py, ARCHITECTURE.md |
Runtime coordination does not become the source of truth | make PROGRAM=python-programming/python-object-oriented-programming capstone-walkthrough |
| Can the current design be reviewed as a learner-facing artifact instead of just a code dump? | TOUR.md, INSPECTION_GUIDE.md, PROOF_GUIDE.md |
The capstone remains legible as a guided reference path | make proof |
Use this order repeatedly: inspect the named files, state the ownership claim, then run the smallest route that produces matching evidence.
Common first-read mistakes¶
- starting in
runtime.pybefore the scenario and aggregate are clear - treating the tests as the only explanation of the design
- using
make proofbefore the lighter routes have made the boundaries legible - reading the read models as if they defined the authoritative state
Inspect, explain, prove¶
Use this loop throughout the capstone:
- Inspect one file, guide, or saved bundle.
- Explain which object or boundary owns the behavior.
- Prove that claim with one named command or one named test.
Use COURSE_STAGE_MAP.md when you want that loop tied directly to the current stage of the course instead of the full capstone at once.
Currency audit¶
- Supported runtime: Python
>=3.10as declared inpyproject.toml. - Time semantics: domain timestamps use timezone-aware UTC (
datetime.now(timezone.utc)), not naiveutcnow(). - Persistence scope: the shipped capstone keeps an in-memory repository and unit of work so storage concerns stay reviewable before database tooling enters the story.
- Concurrency scope: the capstone is intentionally synchronous today; concurrency and scheduling pressure are reviewed as design boundaries, not shipped runtime machinery.
- Serialization scope: learner-facing review artifacts are text and JSON bundles produced by the Make targets, not a stable network API contract.
Definition of done¶
make testpasses withPYTHONPATH=src.make inspectproduces readable summary, rules, and history bundles that match the documented scenario.make tourproduces the walkthrough bundle without requiring learners to read internals first.make verify-reportcaptures executable proof and learner-facing state in one saved review bundle.make confirmcompletes the strongest local confirmation route.make proofcompletes the full published learner route end to end.
Read it by course stage¶
- Semantic floor: inspect the model and lifecycle tests first.
- Collaboration and evolution: inspect policies, read models, repository boundaries, and runtime coordination.
- Trust and governance: inspect bundles, proof routes, and public review outputs before reading internals.
How to read this code¶
Start in this order:
src/service_monitoring/application.pysrc/service_monitoring/model.pysrc/service_monitoring/policies.pysrc/service_monitoring/runtime.pysrc/service_monitoring/repository.pysrc/service_monitoring/read_models.pytests/
That order mirrors the course: semantics first, then replaceable behavior, then orchestration.
Use PACKAGE_GUIDE.md, TEST_GUIDE.md, and EXTENSION_GUIDE.md when you need a narrower
reading route than the full overview.
Design intent¶
The implementation deliberately stays small. The goal is not framework breadth. The goal is to demonstrate a Python object model that remains readable under change:
- value types stay immutable and validated
- aggregates own invariants instead of scattering them
- strategy objects keep rule evaluation extensible without condition ladders
- events describe what happened without mutating projections directly
- a runtime facade keeps orchestration outside the aggregate
- repositories and unit-of-work boundaries make persistence intent explicit
Study questions¶
- Which objects are authoritative, and which only derive views from events?
- Where would a new rule mode belong?
- Which behavior would be dangerous to move into the runtime?
- Which pieces can change without forcing a rewrite of the aggregate?
Scenario walkthrough¶
Run the learner-facing scenario:
That path exercises the application surface in application.py, which is the best
place to start if you want to understand how a team would drive the capstone without
reaching into its internals first. Use make tour when you want that scenario captured
as a durable bundle instead of transient terminal output.
For the full narrative route, continue to TOUR.md.
Architecture¶
graph TD
runtime["MonitoringRuntime"]
source["MetricSource adapter"]
sink["IncidentSink adapter"]
repo["InMemoryPolicyRepository"]
uow["InMemoryUnitOfWork"]
aggregate["MonitoringPolicy aggregate"]
evaluator["RuleEvaluator"]
policies["Evaluation policies"]
events["Domain events"]
active["ActiveRuleIndex"]
ledger["IncidentLedger"]
source --> runtime
runtime --> uow
runtime --> sink
uow --> repo
uow --> aggregate
runtime --> evaluator --> policies
aggregate --> events
events --> active
events --> ledger
For a fuller boundary review, continue to ARCHITECTURE.md.
Layout¶
src/service_monitoring/model.pycontains the aggregate, rules, and alert model.src/service_monitoring/policies.pycontains rule-evaluation strategy objects.src/service_monitoring/read_models.pycontains downstream incident projections.src/service_monitoring/runtime.pycontains the runtime facade and adapters.tests/contains executable behavioral checks across the full stack.