$npx -y skills add maksimzayats/specx --skill specx-component-architectureDesign or review specx core scope boundaries in Python services. Use when deciding where code belongs across packaged scoped foundation bases, optional local foundation extensions, core/, capabilities, delivery, infrastructure, shared/, and ioc; when adding guardrails or sp
| 1 | # specx Scope Architecture |
| 2 | |
| 3 | Use this skill before broad structural changes or when a feature crosses more |
| 4 | than one layer. Read `references/boundaries.md` for the full rules. |
| 5 | |
| 6 | ## Boundary Model |
| 7 | |
| 8 | - `core/<scope>/`: application behavior and contracts. Inner packages are |
| 9 | `capabilities/`, `dtos/`, `entities`, `exceptions/`, `gateways/`, |
| 10 | `repositories/`, `services/`, and `use_cases/`. |
| 11 | - `core/<scope>/infrastructure/`: scope-owned external IO adapters such as |
| 12 | SQLAlchemy repositories, Redis stores, HTTP clients, file storage, and queues. |
| 13 | Inner core packages must not import it. |
| 14 | - Scoped specx foundation packages: packaged base classes under |
| 15 | `specx.core.foundation`, `specx.delivery.foundation`, and |
| 16 | `specx.infrastructure.foundation`. Every non-foundation source class must |
| 17 | inherit an explicit packaged base directly or through a project-local base; |
| 18 | local bases explicitly inherit the packaged or framework base they extend. |
| 19 | - `foundation/`: optional project-local extension point for base definitions |
| 20 | only: real project-local base categories or stateful framework bases that |
| 21 | must not be shared globally, such as a SQLAlchemy declarative base. |
| 22 | - `delivery/`: runnable framework apps, controllers, schemas, auth |
| 23 | dependencies, request parsing, response serialization, HTTP error translation, |
| 24 | app lifecycle managers, and delivery-only services. |
| 25 | - `infrastructure/`: app-wide technical resources such as SQLAlchemy session |
| 26 | factories, logging, telemetry, and external client factories. |
| 27 | - Runtime logging lives in top-level `infrastructure/logging`. Configure it |
| 28 | once with a `BaseConfigurator`; do not inject `logging.Logger`. |
| 29 | - `shared/`: tiny stable cross-scope primitives. It is not a dumping ground. |
| 30 | - `ioc/`: `diwire` container creation and explicit bindings. |
| 31 | |
| 32 | ## Decision Rules |
| 33 | |
| 34 | - Use a use case for an externally meaningful action. |
| 35 | - Use a service for focused reusable business/application behavior. |
| 36 | - Use a capability for one small replaceable injectable ability that is |
| 37 | narrower than a service. |
| 38 | - Name every service class with a `Service` suffix. |
| 39 | - Name direct concrete `BaseCapability` subclasses with a `Capability` suffix. |
| 40 | - Do not call small collaborators services by default. |
| 41 | - Core services inherit `BasePureService`, `BaseReadService`, or |
| 42 | `BaseEffectService`; do not add or use a generic `BaseService`. |
| 43 | - Do not add `base_` prefixes to project-local foundation module filenames. |
| 44 | Class names stay prefixed, for example `clock.py` defines `BaseClock`. |
| 45 | - Use gateway ports under `core/<scope>/gateways/` for outbound business |
| 46 | capabilities such as OpenAI summaries, payments, email, queues, and external |
| 47 | APIs. Gateway ports inherit `BaseGateway`, declare external effects, and do |
| 48 | not return entities. |
| 49 | - Put concrete gateway implementations under |
| 50 | `core/<scope>/infrastructure/<technology>/`. |
| 51 | - Use packaged scoped specx foundation bases before adding project-local bases. |
| 52 | - Do not create an empty local `foundation/` package. |
| 53 | - Add a project-local foundation base only when a real project-local base |
| 54 | category exists or a stateful framework base must own project-local state, |
| 55 | such as SQLAlchemy `MetaData`. |
| 56 | - Use a port or ABC only for a real external boundary or multiple |
| 57 | implementations. |
| 58 | - Use one delivery controller per scoped set of use cases. |
| 59 | - Use `core/health` when readiness checks any required external dependency or |
| 60 | probe policy is reusable across delivery layers. Keep a simple |
| 61 | framework-specific liveness probe in delivery, and do not invent core probe |
| 62 | services and use cases solely to satisfy the layer diagram. |
| 63 | - When `core/health` is justified, keep framework route/status/header mapping |
| 64 | in delivery and technical checks behind gateway adapters. |
| 65 | - Keep request/response schemas in top-level `delivery/`. Keep use-case DTOs in |
| 66 | `core/<scope>/dtos/`. |
| 67 | - Prefer `@dataclass(frozen=True, kw_only=True, slots=True)` for commands, |
| 68 | queries, DTOs, entities, and other core data classes unless the user asks for |
| 69 | another model type. Keep Pydantic at delivery schemas and settings edges. |
| 70 | - Use `BaseStrEnum` for limited known application value sets instead of plain |
| 71 | `str` or `Literal[...]`. |
| 72 | - When creating or reshaping a repo, keep root `AGENTS.md` architecture |
| 73 | guidance aligned with these boundaries. |
| 74 | - Define each use-case input as a same-file `Command` or `Query`: commands are |
| 75 | state-changing, queries are read-only, and even empty inputs are explicit. |
| 76 | - Keep commands and queries independent from DTOs. They inherit `BaseCommand` |
| 77 | or `BaseQuery`, not `BaseDTO`, and live beside the use case that consumes |
| 78 | them. |
| 79 | - Use |