Rule-based architecture guardrails for Specx Python services.
Project description
Specx
Agent skills for building Python services with explicit architectural boundaries.
Specx is a skill catalog for generating and evolving backend services that keep application code readable under agent-driven development. It gives AI coding agents a shared vocabulary for packaged foundation bases, scoped core packages, delivery adapters, unit-of-work lifecycles, dependency injection, migrations, and architecture tests.
Install · Skills · Generated Architecture · Contribute
Key Features
- Skill-based service scaffolding. Specx replaces a one-off code template with composable skills for project structure, foundation usage, tooling, DI, use cases, services, delivery controllers, infrastructure adapters, settings, migrations, and tests.
- Explicit class boundaries. Generated services use class-based use cases, services, controllers, repositories, gateways, capabilities, DTOs, entities, units of work, and factories with packaged scoped foundation bases.
- Clear transaction ownership. Use cases open
UnitOfWorkManagerscopes and do not inject repositories, SQLAlchemy sessions, engines, session factories, or concrete infrastructure adapters directly. Read/effect services may use an active UoW passed by the use case, but they do not own transaction lifecycle. - Guardrails for agent work. The
specxPython package ships rule-based architecture tests that reject layer leaks, entity returns from use cases, schema bootstrap calls, bare classes, wrong suffixes, and hidden transaction ownership. - Standard runtime logging. Generated API services configure Python stdlib logging once through top-level infrastructure and keep logger creation local to classes that actually emit log records.
- Explicit FastAPI lifespans. Generated FastAPI apps inject a
FastAPILifecycleinto the app factory, pass it toFastAPI(lifespan=...), and close app-owned resources plus the DI container during shutdown. - Explicit foundation boundaries. Generated services import stateless base
classes from
specx.core.foundation,specx.delivery.foundation, andspecx.infrastructure.foundationinstead of vendoring a foundation tree. They add localfoundation/modules only for real project-local categories or stateful framework bases such as a SQLAlchemy declarative base. - Container-centric tests. Generated tests use native pytest
containerfixtures and directcontainer.resolve(Target)calls. Overrides are registered before resolution, one-off class-based doubles live in thetest_*.pymodule that uses them, reused unit-test doubles live in mirroredfake_<source_module>.pyfiles under unitcapabilities,gateways, orrepositoriestest packages, and generated tests mirror source modules with flat paths such astests/unit/core/tasks/services/test_title_service.py. - Alembic-first persistence. SQLAlchemy projects use real Alembic
migrations and drift checks instead of
metadata.create_all()bootstraps.
Install
Install every Specx skill for your target agent. For the codex target:
npx skills add maksimzayats/specx --skill '*' --agent codex -y
List skills from a local checkout:
npx skills add . --list --full-depth
Validate the catalog:
make check
Use the architecture package from generated projects:
from pathlib import Path
from specx.testing.architecture import SpecxArchitectureConfig, assert_specx_architecture
def test_specx_architecture() -> None:
assert_specx_architecture(
SpecxArchitectureConfig(
project_root=Path(__file__).resolve().parents[3],
package_name="order_service",
)
)
What You Get
- A reusable agent skill catalog under
skills/. - A typed Python guardrail package under
src/specx/. - A generated reference service under
samples/url-shortener-service/. - Rule-based architecture guardrails exposed through
specx.testing.architecture. - A compatibility renderer that writes the tiny generated-project pytest wrapper with the correct package name.
- Root
AGENTS.mdguidance for agents working on this catalog. - Generated-project
AGENTS.mdguidance that projects should carry with them.
Skills
specx-project-structurecreates the initialcore,delivery,infrastructure,ioc, optional localfoundation, optionalshared, migrations, tests, and generated-project agent instructions.specx-foundationteaches packaged stateless base usage and project-local extensions for real missing base categories or stateful framework bases.specx-project-toolingaddsuv, Ruff, mypy, pytest, Makefile targets, and local validation commands.specx-component-architecturedecides where code belongs across scopes, boundaries, capabilities, gateways, DTOs, schemas, adapters, and shared code.specx-diwire-compositionwiresdiwire.Container,Injected[...], private registrations, app factories, and test overrides.specx-add-core-use-caseadds command/query-driven use cases that return DTOs and own UoW scopes when persistence is needed.specx-add-core-serviceadds focused reusable core behavior without hiding transaction lifecycle.specx-add-infrastructure-adapteradds repositories, gateways, UoW implementations, SQLAlchemy, Redis, HTTP, SDK, logging configurators, and other technical adapters.specx-sqlalchemy-migrationsadds async Alembic configuration, revisions, migration commands, and drift tests.specx-add-delivery-controlleradds top-level FastAPI controllers, schemas, route registration, delivery lifecycles, and delivery-only helpers.specx-settingsaddspydantic-settingsconfiguration without direct environment reads in core code.specx-testsadds unit, integration, end-to-end, DI, migration, and architecture tests backed by thespecxpackage.
Generated Architecture
Specx projects import stateless foundation bases from scoped Specx packages and organize application code around scoped core packages:
src/<package>/
foundation/ # only when project-local/stateful bases are needed
core/
<scope>/
capabilities/
dtos/
entities/
exceptions/
gateways/
repositories/
services/
use_cases/
infrastructure/
delivery/
fastapi/
__main__.py
factory.py
lifecycle.py
controllers/
schemas/
services/
infrastructure/
logging/
ioc/
shared/
migrations/
core/<scope>/delivery/ is intentionally not part of the structure. Delivery
lives at the top level, while core packages stay framework-free.
Do not create an empty local foundation/ package. specx.core.foundation,
specx.delivery.foundation, and specx.infrastructure.foundation are the
default scoped foundation boundaries. Create
src/<package>/foundation/ only for project-local base categories or stateful
framework bases that must not be shared globally, such as the project
SQLAlchemy declarative base. Local foundation module filenames are not
base_-prefixed, but class names stay prefixed, for example clock.py defines
BaseClock.
Core Rules
- Every project class inherits an explicit packaged or project-local foundation base.
- Use cases accept exactly one same-file
CommandorQueryand return DTOs, not entities. - Commands represent state-changing operations. Queries are read-only, even when the input is empty.
- Commands, queries, DTOs, entities, and other core data classes should use
@dataclass(frozen=True, kw_only=True, slots=True)unless the user asks for another model type. Keep Pydantic for delivery schemas and settings. - Core services inherit
BasePureService,BaseReadService, orBaseEffectService; do not add a genericBaseService. - Small injectable collaborators inherit
BaseCapability, live undercore/<scope>/capabilities/, and do not pretend to be services, repositories, gateways, helpers, or managers. - Gateway ports inherit
BaseGateway, live undercore/<scope>/gateways/, declare external effects, use business language, and do not return entities. - Persistence use cases inject a
UnitOfWorkManagerand open an activeUnitOfWorkinsideexecute(...). They do not inject repositories, SQLAlchemy sessions/engines/session factories, or concrete infrastructure adapters directly. - Services may receive an active UoW as a method argument, but they do not open UoW scopes, commit, or roll back.
- SQLAlchemy schema is managed by Alembic migrations, not application schema bootstrap calls.
- Runtime logging is configured once in top-level infrastructure. Do not inject
logging.Loggeror register loggers indiwire.Container; classes that actually log create private stdlib class loggers. - FastAPI lifespan lives in
delivery/fastapi/lifecycle.py, inheritsBaseLifecycle[FastAPI], closes app-owned infrastructure resources, then callscontainer.aclose()on shutdown. It must not run migrations or schema creation. diwire.Containerbelongs inioc, top-level delivery factory/entrypoint/lifecycle code, and tests only.Injected[Container]is allowed only inFastAPILifecycle.
Reference Service
The sample service under samples/url-shortener-service/ is a working generated
project used to validate the skills. It includes:
- FastAPI delivery with
url_shortener_service.delivery.fastapi.__main__:app. - FastAPI lifespan cleanup for SQLAlchemy and DI container resources.
- URL and operational probe use cases with command/query inputs and DTO outputs.
- Split pure/read/effect services.
- SQLAlchemy repositories and UoW manager.
- Stdlib logging configurator and meaningful class-local log records.
- Alembic migrations and drift checks.
- Architecture tests that call the rule-based
specxguardrail package.
Run it from the sample directory:
cd samples/url-shortener-service
make check
Contributing
Developer setup, architecture notes, sample regeneration expectations, and validation workflow live in CONTRIBUTING.md.
License
Specx is released under the MIT License.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file specx-0.0.0a3.tar.gz.
File metadata
- Download URL: specx-0.0.0a3.tar.gz
- Upload date:
- Size: 37.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08377fe36c734196ee96cc54c8303a33e3c9d4ff1232e1258e1a7f5c32876da0
|
|
| MD5 |
28316a8ad979bfcafe89d9c825c91afd
|
|
| BLAKE2b-256 |
f9925daba0423a50c5d175303a522f48f509d39dce470dc32284749fee1e2ee6
|
File details
Details for the file specx-0.0.0a3-py3-none-any.whl.
File metadata
- Download URL: specx-0.0.0a3-py3-none-any.whl
- Upload date:
- Size: 51.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
951770c42dcf7f8a3849018accb8c61e39edc4d95c0739f6716c48d07ef1320a
|
|
| MD5 |
a76c08e60734af05e036af0c3c5c123d
|
|
| BLAKE2b-256 |
0b2fb7598e9e97671e09c32ddec3b7e0ca7720cb2147580a2267207e229ddd25
|