.specify/memory/constitution.md
Every feature area MUST be implemented as an independent module (separate .csproj) with clear boundaries.
src/modules/ and MUST be self-contained with their own
DI registration, contracts, and implementations.ShellFeatures/,
Contracts/, Services/, Extensions/, Models/, and optionally
Activities/, Middleware/, Handlers/.src/common/; application hosts belong in
src/apps/.Rationale: Modularity enables independent development, testing, and deployment of features. It keeps the 100+ project solution manageable and allows consumers to depend only on the modules they need via NuGet.
The system MUST favour composition over inheritance and provide explicit extensibility points for every major subsystem.
IShellFeature, IMiddlewareShellFeature)
with dependency declarations through the [ShellFeature(DependsOn = [...])]
attribute. The shell resolves and initialises features in correct order.Activity, Activity<T>, CodeActivity, or CodeActivity<T>
and declare metadata via [Activity], [Input], and [Output] attributes.IWorkflowDefinitionStore) define the contract; EF Core implementations
are one provider among potentially many.IExpressionEvaluator
implementations (JavaScript, C#, Python, Liquid).Microsoft.Extensions.DependencyInjection
with fluent IServiceCollection extension methods per module.Rationale: Elsa is a library embedded in arbitrary .NET hosts. Users MUST be able to swap persistence, expression engines, and feature sets without modifying core code.
The codebase MUST use consistent, discoverable conventions to reduce cognitive load and enable tooling automation.
[Activity], [Input],
[Output]) — not via external configuration.Input<T> and Output<T>
for expression-capable, type-safe data flow.ElsaEndpoint<TRequest, TResponse>) with collocated request/response models.{Area}Feature (e.g., HttpFeature, WorkflowsFeature)I{Entity}Store{Module}ServiceCollectionExtensions{Subject}TestsDirectory.Build.props.Rationale: Predictable patterns make the large codebase navigable and reduce onboarding friction. Attribute-driven metadata enables automatic UI generation in the visual designer.
All I/O-bound and workflow execution paths MUST use async/await. Cross-cutting concerns MUST be handled via middleware pipelines.
IActivityExecutionPipeline — a composable
middleware chain built with IActivityExecutionPipelineBuilder.IWorkflowRunner with scoped
ActivityExecutionContext for state isolation.IMediator (request/response and
notification patterns) — not external libraries.ValueTask SHOULD be preferred over Task for hot execution paths where
synchronous completion is common.Rationale: Workflows are inherently asynchronous and long-running. Pipeline architecture enables observability, resilience, and logging middleware without polluting activity code.
New code MUST include tests. Tests MUST be organised by scope and follow established patterns.
[Fact] and [Theory] attributes.test/unit/ for isolated tests, test/integration/
for end-to-end scenarios, test/component/ for feature testing.ActivityTestFixture for unit-testing activities
and WorkflowTestFixture for integration tests.DisplayName SHOULD be set for
readability.Rationale: The workflow engine is the critical path for all consuming applications. Regressions in core execution logic have outsized impact.
All changes MUST flow through Pull Requests targeting the main branch.
Rationale: Trunk-based development with focused PRs maintains velocity while keeping the codebase stable for the large contributor community.
Complexity MUST be justified. Start simple; avoid speculative generalisation.
Rationale: A 100+ project solution is only sustainable when each part earns its existence. Unnecessary abstraction increases maintenance burden and onboarding cost.
<TargetFrameworks> in src/Directory.Build.props.<LangVersion>latest</LangVersion>).build/Build.cs); CI runs
./build.cmd Compile Test Pack.Directory.Packages.props; NuGet source mapping in NuGet.Config.IWellKnownTypeRegistry.DbContext; generic
Store<TDbContext, TEntity> base class; supports SQL Server, PostgreSQL,
MySQL, SQLite, Oracle.ITenantAccessor with AsyncLocal<Tenant?> context;
query filters for tenant isolation.docker/.# Restore (always use --ignore-failed-sources for external feed resilience)
./build.sh Restore --ignore-failed-sources
# Compile (excludes studio apps)
./build.sh Compile
# Test
./build.sh Test
# Full CI pipeline
./build.sh Compile Test Pack
dotnet build src/modules/{Module}/.Follow conventional commits: feat:, fix:, refactor:, chore:, docs:,
test:, perf:.
This constitution is the authoritative reference for architectural decisions and development practices in the Elsa Workflows repository.
plan-template.md to verify alignment..github/copilot-instructions.md for build
commands, troubleshooting, and CI details.Version: 1.0.0 | Ratified: 2026-03-08 | Last Amended: 2026-03-08