PSE is a Domain-Driven Design (DDD) architecture scaffolding engine built on top of textX.
Instead of generating folders and files directly, PSE allows developers to describe software architecture using a domain-specific language (DSL). The engine applies architectural heuristics, technology presets, and generation plugins to produce production-ready project structures.
The goal is to provide a consistent, maintainable starting point for modern software projects while remaining technology-agnostic and future-proof.
PSE aims to become:
Terraform for software architecture.
Developers describe:
- Business domains
- Bounded contexts
- Entities
- APIs
- Infrastructure
- Deployment requirements
PSE generates:
- Solution structure
- Source projects
- Docker configurations
- CI/CD pipelines
- Infrastructure manifests
- Tests
PSE follows a layered architecture.
DSL Source
↓
AST (textX)
↓
Architecture Model (semantic IR)
↓
Capability Graph (intent)
↓
Dependency Graph (ordering)
↓
Generators (backend emission)
DSL (Grammar Layer)
- Clean, constrained DSL in
pse.tx. - Constructs: Project, Archetype, Capabilities, Contexts, Entities, ValueObjects, Aggregates, Infrastructure, Deployment.
- No packages/frameworks/CI/CD in DSL; intent only.
Architecture Model (Core IR)
- Normalized
ArchitectureModelwith project metadata, contexts, entities, value objects, aggregates, infrastructure, and deployment. - Decouples DSL from generators and enables multi-language targets.
Heuristics System (Externalized Intelligence)
- YAML registries:
archetypes.yaml,presets.yaml,packages.yaml,versions.yaml,capabilities.yaml. - Maps archetypes to capabilities, capabilities to implementations, implementations to packages and versions.
Bootstrap System (Execution Orchestrator)
- Validates environment, loads grammar, parses DSL, builds
ArchitectureModel, loads heuristics. - Builds
GenerationContextand dispatches generators. - Fail-fast, deterministic execution flow.
- Writes a run manifest (
pse.manifest.json) with DSL input, resolved capabilities, timestamps, and status.
GenerationContext (Unified Generator Contract)
- Shared contract for all generators: architecture model, heuristics, output path, options, logging.
- Removes direct dependency on textX models in generators.
Dotnet Generator (Pipeline-Based)
generate_dotnet(ctx)
├── create_solution()
├── create_projects()
├── create_structure()
├── create_integration()
├── restore_packages()
└── create_docker()
Docker Generation (Basic Infrastructure Output)
- Dockerfile generation and runtime image wiring.
- Tied to deployment target in the architecture model.
- Uses templates in pse/templates/dotnet.
Integration Scaffolding
- Generates
appsettings.jsonandappsettings.Development.jsonfor entrypoint projects. - Emits Options classes in
Application/Optionsfor Database, Redis, and RabbitMq. - Adds
AppDbContextin Infrastructure when a database is declared. - Wires EF Core, Redis cache, and MassTransit in Program.cs using templates.
Capability System + Resolver
- Capabilities represent abstract needs (cqrs, logging, validation, database, cache, messaging).
- Resolver applies archetype defaults, infers from infrastructure, and falls back to defaults.
- Produces a
CapabilityGraphused by generators.
Dependency Graph System (Ordering Engine)
- Directed dependency graph with topological sorting.
- Enables deterministic capability sequencing and future orchestration correctness.
Integration Path
ArchitectureModel
↓
CapabilityGraph
↓
DependencyGraph
↓
GenerationContext
Generators are now dumb executors; intelligence is centralized in the resolver layer.
PSE is an architecture compilation engine and a declarative, heuristic-driven scaffolding system.
- Capability swapping (MediatR → Wolverine, Serilog → built-in logging).
- Multi-language targets via the same semantic model.
- Infrastructure scaling (Docker now, Kubernetes next).
- Archetype evolution (Clean Architecture, Modular Monolith, Microservices).
The missing brain layer is package resolution and conflict solving:
- Capability-to-package mapping.
- Version conflict resolution.
- Dependency collision handling.
- Transitive dependency reasoning.
The DSL describes architecture and business requirements.
Example:
Project StoreApi target=dotnet {
Archetype WebApi
Capabilities {
Capability Logging
Capability Validation
Capability Mapping
}
Context Orders {
Entity Order {
Guid Id
DateTime CreatedAt
}
Entity OrderItem {
Guid ProductId
int Quantity
}
Aggregate OrderAggregate {
root Order
children OrderItem
}
}
Infrastructure {
Database PostgreSQL
Cache Redis
}
Deployment Docker
}
Samples:
- Basic DSL (no explicit capabilities): pse/sample_basic.pse
- DSL with explicit capabilities: pse/sample_with_capabilities.pse
All emitted content is rendered from templates in pse/templates/dotnet. Edit those files to customize Program.cs, controllers, repositories, Docker artifacts, and class skeletons.
Run the generator from pse/run.py. It accepts a DSL file and output directory:
python run.py sample_with_capabilities.pse -o ./sample_outputThe DSL describes architecture rather than implementation details.
Avoid:
package MediatR
package AutoMapper
Prefer:
Capability CQRS
Capability Validation
Capability Mapping
The heuristics engine resolves capabilities to technologies.
Technologies are selected through presets and registries.
Today:
cqrs: mediatrTomorrow:
cqrs: wolverineNo DSL changes required.
Reasonable defaults should generate a working project with minimal configuration.
Example:
Project StoreApi {
Archetype WebApi
}
May automatically generate:
- ASP.NET Core Web API
- PostgreSQL
- Docker
- GitHub Actions
- Logging
- Validation
- Testing
- Health Checks
Based on configured heuristics.
Archetypes define high-level project structures.
Presentation
Application
Domain
Infrastructure
Tests
Presentation
Application
Domain
Infrastructure
Modules
├── Identity
├── Orders
└── Billing
Services
Gateway
Shared
Infrastructure
PSE supports modeling of:
- Entities
- Value Objects
- Aggregates
- Domain Events
- Repositories
- Bounded Contexts
Example:
Context Identity {
Entity User {
Guid Id
Email Email
}
ValueObject Email
Aggregate UserAggregate {
Root User
}
}
Generated artifacts may include:
- Domain entities
- Repository interfaces
- DTOs
- CQRS handlers
- Validation rules
Infrastructure is described declaratively.
Example:
Infrastructure {
Database PostgreSQL
Cache Redis
MessageBroker RabbitMQ
ObjectStorage MinIO
}
PSE generates deployment artifacts automatically.
docker-compose.ymldeployments/
services/
configmaps/- Docker Compose
- Kubernetes
- Docker Swarm
- Nomad
Deployment Docker
Deployment Kubernetes
Deployment DockerSwarm
The same architecture model can produce different deployment artifacts.
The heuristics engine applies organizational standards and best practices.
Example:
Project StoreApi {
Archetype WebApi
}
May resolve to:
logging: serilog
validation: fluentvalidation
database: postgres
testing: xunit
deployment: dockerAll decisions are configurable.
versions:
dotnet: 9.0
postgres: 17
redis: 8mediatr:
package: MediatR
version: 13.0.0webapi:
logging: serilog
validation: fluentvalidation
cqrs: mediatrPSE is built around generator plugins.
plugins/
├── dotnet
├── java
├── docker
├── kubernetes
├── github_actions
├── terraform
A plugin may provide:
- Grammar extensions
- Validators
- Templates
- Generators
pse/
├── grammar/
│ └── pse.tx
│
├── model/
│ └── architecture.py
│
├── heuristics/
│ ├── archetypes.yaml
│ ├── presets.yaml
│ ├── packages.yaml
│ └── versions.yaml
│
├── validators/
│
├── generators/
│ ├── dotnet/
│ ├── java/
│ ├── docker/
│ ├── kubernetes/
│ └── github_actions/
│
├── templates/
│
└── tests/
- DSL foundation
- Architecture model
- .NET generator
- Docker generator
- Git integration
- Domain modeling
- API generation
- Validation engine
- GitHub Actions
- Kubernetes support
- DockerSwarm support
- Java generator
- Multi-service architectures
MIT