specx Project Structure
Use this skill to create the repo shell and first runnable vertical slice. For
details, read references/blueprint.md.
Workflow
- For a fresh framework-neutral repo, start with
specx init <path>. It creates packaging, strict tooling, rootAGENTS.md, a smallcore/healthuse case and pure service,ioc/container.py, and mirrored unit tests. It intentionally omits delivery and infrastructure; add those packages only with real technology-specific behavior. - Preserve an existing import package declared by the repo. For a new repo,
derive a lowercase underscore name, normalize every non-identifier
character, and verify
name.isidentifier()andnot keyword.iskeyword(name); distribution names and import packages need not be identical. If normalization still yields a keyword or leading digit, choose an explicit valid package name rather than emitting it unchanged. - Create
src/<package>/andtests/packages with empty__init__.pyfiles only. - Add
specxas a runtime dependency and import base classes fromspecx.core.foundation,specx.delivery.foundation, orspecx.infrastructure.foundation. - Use
core/<scope>/as the main boundary. Put application packages at the scope root:capabilities/,dtos/,entities/,exceptions/,gateways/,repositories/,services/, anduse_cases/. Put scope-owned technical adapters underinfrastructure/only when real IO exists. - Add top-level
delivery/for runnable framework apps, lifecycles, controllers, request/response schemas, and delivery-only services. - Add top-level
infrastructure/for shared technical resources such as SQLAlchemy session factories, logging, telemetry, and external client factories. App-owned pooled clients live here even when only one scope currently consumes them; bounded short-lived clients may stay with the scope adapter. - Add
infrastructure/logging/with a stdlibLoggingConfiguratorandLoggingSettingsfor every new API repo. - Add
ioc/fordiwire.Containercreation and explicit bindings. - Add
shared/only for stable cross-scope application primitives such as unit-of-work contracts, clocks, ids, or errors. - Add
migrations/with Alembic when SQLAlchemy models exist. - Build the first user-requested business vertical slice. The initializer's
process-health slice is a framework-neutral composition example, not a
readiness check. With a delivery framework, map or replace it deliberately:
keep simple liveness at delivery, and use
core/healthfor/readyzwhen readiness checks a required dependency or policy is shared across deliveries. - Create root
AGENTS.mdfor every new repo. Include runnable project commands from$specx-project-toolingand specx boundaries from$specx-component-architecture. - Do not create an empty local
foundation/package. Createsrc/<package>/foundation/only for a real project-local base category or a stateful framework base that must not be shared globally, such as a SQLAlchemy declarative base. - Add tests only where there is real code to test. Do not create empty folders just to satisfy the diagram.
Non-Negotiable Boundaries
- Keep all source and test
__init__.pyfiles empty. Do not add empty local foundation, source, test, or helper packages. - Every non-foundation source class inherits an explicit packaged or local
scoped base and uses the suffix implied by that ancestry. Every source class,
including local bases, has a scoped docstring with a real
Example:. - Keep core inner packages free of delivery, IOC, SQLAlchemy, Redis, HTTP
clients, and framework imports. Put concrete IO adapters under
core/<scope>/infrastructure/<technology>/. - Capabilities are narrow
BaseCapabilitycollaborators; gateways are business-languageBaseGatewayports; core services chooseBasePureService,BaseReadService, orBaseEffectService. - Same-file
BaseCommandorBaseQueryinputs enter use cases, and result DTOs leave them. Persistence use cases inject aUnitOfWorkManager; services do not open or finish transactions. - Prefer frozen, keyword-only, slotted dataclasses for core data and
BaseStrEnumfor reusable closed value sets. Keep Pydantic at delivery and settings edges. - Keep infrastructure technical and schema evolution in Alembic. Never call
metadata.create_allordrop_allin application or test code. - Configure stdlib logging once before composing the FastAPI app. Use FastAPI lifespan for resource cleanup, then close the container; do not run schema changes or business workflows in lifespan.
- Business routes use full
/api/v1/...paths. Keep/healthzindependent of external systems; use/readyzandcore/healthfor any required external dependency, with bounded checks and minimal responses. - Mirror real source behavior with flat tests. Unit tests resolve targets from
a native pytest
containerfixture; integration tests use the real internal graph and replace only external boundaries. Read the blueprint before adding shared doubles or support helpers. - Keep root
AGENTS.mdcommands aligned with the Makefile and include only guidance that matches files and features present in the project. - This skill targets FastAPI and must enable the opt-in
fastapirule family in[tool.specx]. Framework-neutral specx rules remain the default for workers, CLIs, and other delivery technologies.
References
references/blueprint.md- target tree, starter files, and creation checklist.


