Clean Architecture and Cosmic Python guidance for well-tested, layered Python systems...
Cosmic Python is NOT about system architecture (service boundaries, deployment topology, C4 modelsβthat's the separate architecture skill).
Cosmic Python IS about code structure within a Python module or service: how to organize classes, functions, tests, and dependencies so that code is clean, testable, and maintainable.
When to use Cosmic Python:
This skill pairs with:
The principles, best-practices, and anti-patterns are owned in ONE place:
references/principles-and-anti-patterns.md.
Every other skill, agent, and the global prompt cites an entry by id (e.g.
cosmic-python:AP-DICT-AS-MODEL) and never restates it. The tables in this SKILL.md are reference
("what good looks like"); the catalogue is authority. When a code-review finding recurs, add it there.
Survey & reuse before you write (PR-SURVEY-FIRST). Before adding a new file/class/function, read
the sibling files in the target package and grep for existing constants, enums, models, and helpers;
decide reuse / extend / refactor-to-fit first. This is the implement-phase entry step β the
implementer agent enforces it; the red-green-refactor ritual is owned by superpowers:test-driven-development.
Our goal is clean code that passes code review quickly while keeping developers productive and safe.
This is achieved through three non-negotiable commitments:
Within each Python module or service, separate code into four tightly-bounded layers:
models/ β Domain logic (business rules, entities, value objects)
adapters/ β Infrastructure and integration (databases, APIs, file systems)
models only; never on services or entrypointsservices/ β Use-case orchestration (application logic, workflows)
models and adaptersmodels and adapters, never on entrypointsentrypoints/ β Request/response boundaries (API, CLI, schedulers, workers)
servicesThe Law:
entrypoints β services β models
β
adapters β models
Never the reverse. High-level policy (models + services) must never depend on low-level details (adapters). Low-level details depend on abstractions (interfaces/protocols), not the other way around.
When you violate this:
How to enforce:
importlinter in CI/CD to block forbidden imports (see references)"If you can't test it, you can't understand it. If you can't understand it, you can't maintain it."
calculate_customer_tier() not calc_tier()services and entrypoints, not deep in modelsPR-COMPONENT-FIRST)A small service stays one level β just the four layers. A larger project is component-first:
<root>/
core/ # or commons β shared models/adapters/services; imported by all, imports none
models/ adapters/ services/
<component-a>/ # e.g. loader/
models/ adapters/ services/ entrypoints/
<component-b>/
models/ adapters/ services/ entrypoints/
services/<component>/ (layer-first with a
component nested in it) β that is AP-PARALLEL-LAYOUTS. Pick ONE layout per package and finish the migration.core/commons is the inward-looking shared component (AP-CROSS-VARIANT-IMPORT): others import it; it
imports none of them; it has no entrypoints/.commons isolation β owned by
project-setup, which also sets the grooming
cadence (revise the contracts on every refactor / new component; the agent asks the developer
periodically whether they still fit).For each function/class, ask:
If you can't answer these clearly, the architecture is drifting. See the references for detailed refactoring paths.
When you have clear specs from Stream Coding Phase 2 (doc is 9+/10 Clarity Gate):
models/ β Pure domain logic, no I/O, no frameworksadapters/ β Repositories, gateways, clients; mock external services in testsservices/ β Orchestrate models and adapters; test with mocked adaptersentrypoints/ β CLI, API, schedulers; minimal logic, mostly delegationmake check-architecture to validate import contractsBefore approving a pull request, ask:
Layering:
models/ import from services, adapters, or entrypoints? β Should notadapters/ import from services or entrypoints? β Should notservices/ import from entrypoints? β Should notservices/ or models/, not scattered in entrypoints/? β
Should beClean Code:
Testing:
coverage reportObservability:
services/ and entrypoints/, not deep in models/? β
Correct placementFor each layer, write tests that match its responsibility:
| Layer | What to Test | How | Example |
|---|---|---|---|
models/ |
Domain rules, invariants, transformations | Unit tests, no I/O, fast | test_user_cannot_have_negative_balance() |
adapters/ |
Integration with external systems (mocked) | Unit tests with mocks, or integration with real test DBs | test_postgres_repository_insert_user() |
services/ |
Use-case orchestration and business workflows | Unit tests with mocked adapters | test_user_signup_flow_sends_verification_email() |
entrypoints/ |
Request parsing, response formatting, status codes | Unit tests, check contracts | test_api_endpoint_returns_201_on_create() |
Target: 80%+ coverage overall, with focus on each layer's responsibility (not mixing concerns).
Common anti-patterns and how to fix them:
| Anti-Pattern | How It Looks | Why It's Wrong | Fix |
|---|---|---|---|
| I/O in models | import requests in models/user.py |
Models can't be tested in isolation | Move HTTP call to adapters/, inject via DIP |
| Business rules in entrypoints | API handler validates and transforms data | Logic is scattered, untestable | Extract to services/, call from handler |
| Circular imports | services/ β adapters/ β services/ |
Can't import cleanly, hard to test | Restructure: adapters/ β models/; services/ β adapters/ + models/ |
| Magic strings everywhere | if user.role == "admin" in 5 files |
Refactoring is fragile; intent hidden | Define ROLE_ADMIN = "admin" constant once, import everywhere |
| No tests for branching | services/ has 5 branches but only happy path tested |
Edge cases crash production | Add parametrized tests for each branch |
| Clever one-liners | [x for x in y if x.z and (a or b)] |
Unreadable; maintenance nightmare | Expand to 3-4 readable lines with intermediate variables |
make install # Set up environment (poetry install)
make test # Run unit tests with coverage
make test-bdd # Run BDD feature tests
make check-architecture # Validate import contracts (importlinter)
make lint # Run style checks (pylint, flake8)
make ci # Full pipeline (all above)
Before merging to main:
importlinter to block dependency violationsbilling/models/, billing/services/, not models/billing/import concrete implementations directly in servicesservices/ and entrypoints/, not deep in models/This approach requires team discipline. One developer ignoring layers breaks the architecture for everyone. All developers must respect boundaries and code review rigorously.
Stream Coding (documentation-first planning) and Cosmic Python (clean code structure) work together:
| Phase | Methodology | Focus | Output |
|---|---|---|---|
| 1 | Stream Coding | Strategic: WHAT to build, WHY | Strategic Blueprint + ADRs |
| 2 | Stream Coding | Specifications: HOW to build (AI-ready) | Implementation Specs (9+/10 Clarity Gate) |
| 3 | Cosmic Python | Code: Implement following layers/SOLID | Production code (80%+ tested) |
| 4 | Cosmic Python | Quality: Prevent drift, maintain specs | CI/CD gates, spec-first fixes |
docs/environment/setup.md) owns the documentation-first method: 40/40/20 split, mandatory spec sections, Rule of Divergence.docs/engineering-standards/references/ (stream-coding-notes.md, strategic-blueprint-checklist.md).docs/engineering-standards/coding-prompt.md β the full Meaningfy engineering culture (project structure, layering, SOLID, CI/CD, security). This SKILL.md is the operational version of that canon.Owns: the code-principles catalogue (references/principles-and-anti-patterns.md)
β the single source for code principles/best-practices/anti-patterns β plus code structure inside a
service: the four layers, SOLID, what to test per layer, and CI guardrails.
Delegates: TDD ritual β superpowers:test-driven-development; system design/topology/contracts β
architecture; domain model β conceptual-modelling; LinkML authoring + make generate-models β
linkml-engineering; commit/PR mechanics β meaningfy-git-workflow; sensitive-data interaction safety
β guardrails.
Related: architecture, meaningfy-code-review, bdd-gherkin, guardrails,
conceptual-modelling, linkml-engineering, ci-cd-delivery, meaningfy-git-workflow.
This skill owns code structure inside a service: the four layers, SOLID, what to test per layer, and CI guardrails. It does NOT own:
superpowers:test-driven-development; this
skill says what belongs in a models test vs. a services test, not how to do TDD.architecture skill (cosmic-python consumes
the contracts it authors; make generate-models is the seam).meaningfy-git-workflow skill.Canonical folder vocabulary: models/, adapters/, services/, entrypoints/ within
root modules (not a single /src). The Cosmic Python book's /domain and /service_layer
are documented synonyms for models/ and services/ β when reading the book, map them onto
our canonical names. No semantic label should exist only as a free string.