This document defines the CQRS and transactional semantics for kernel execution flows. These semantics ensure deterministic, reliable execution with proper transactional boundaries and event delivery guarantees.
Related Specifications:
All kernel flows MUST include @cqrs annotation specifying their kind (command, query, or event). Additional annotations are required based on the CQRS kind as defined in the P04 pattern.
Flow annotations are validated by tools/flow_lint.py against the AST schema (tools/schemas/ast-v3.schema.json).
1
python tools/flow_lint.py docs/specs/shared/kernel.ast.json --strict
CQRS Kind: Command
Semantics:
true - All command executions occur within a transaction boundarycorrelationId keyAnnotations:
1
2
3
4
5
{
"cqrs": { "kind": "command" },
"tx": { "transactional": true },
"idempotency": { "enabled": true, "key": "correlationId" }
}
Port Interface: CommandBus
execute<TCommand, TResult>(command: TCommand, context: CommandContext): Promise<TResult>isIdempotent(correlationId: string): Promise<boolean>Invariants:
CQRS Kind: Query
Semantics:
ReadProjection for consistent readsAnnotations:
1
2
3
4
{
"cqrs": { "kind": "query" },
"read_model": { "source": "ReadProjection" }
}
Port Interface: QueryBus
execute<TQuery, TResult>(query: TQuery, context: QueryContext): Promise<TResult>getConsistencyLevel(): ConsistencyLevelInvariants:
CQRS Kind: Event
Semantics:
required - All events MUST use transactional outboxAnnotations:
1
2
3
4
{
"cqrs": { "kind": "event" },
"outbox": { "mode": "required" }
}
Port Interface: EventBus
publish(event: EventEnvelope): Promise<boolean>publishBatch(events: ReadonlyArray<EventEnvelope>): Promise<boolean>Invariants:
Outbox Pattern Flow:
CQRS Kind: Command
Semantics:
true - Transaction lifecycle managementtransactionId keyAnnotations:
1
2
3
4
5
{
"cqrs": { "kind": "command" },
"tx": { "transactional": true },
"idempotency": { "enabled": true, "key": "transactionId" }
}
Port Interface: UnitOfWork
begin(): Promise<TransactionBoundary>commit(boundary: TransactionBoundary): Promise<void>rollback(boundary: TransactionBoundary): Promise<void>getCurrent(): TransactionBoundary | nullInvariants:
1
2
3
4
5
6
7
1. Begin transaction (UnitOfWork.begin)
2. Load aggregates (Repository.findById)
3. Execute command logic
4. Save modified aggregates (Repository.save with optimistic locking)
5. Record events to outbox (OutboxPort.record)
6. Commit transaction (UnitOfWork.commit)
7. [Async] Publish events from outbox
Ensures at-least-once delivery by persisting events transactionally:
All events wrapped in EventEnvelope containing:
eventType: Event type identifieraggregateId & aggregateType: Source aggregateversion: Aggregate version when event occurredcausationId: Command that caused this eventcorrelationId: Original request correlation IDtimestamp: Event occurrence timemetadata: Additional contextual informationRun flow lint to validate all flows have required annotations:
1
python tools/flow_lint.py docs/specs/shared/kernel.ast.json --strict
Checks:
@cqrs annotation@tx (transactional semantics)@idempotency (deduplication strategy)@outbox (delivery guarantees)@read_model (projection source)AST JSON must conform to tools/schemas/ast-v3.schema.json:
| Enum values valid (e.g., outbox mode: “required” | “optional”) |
All kernel ports defined as TypeScript interfaces in libs/sea/ports/src/gen/kernel/ports.ts. Adapters implement these interfaces without kernel coupling.
Domain types (CommandContext, QueryContext, EventEnvelope, TransactionBoundary) defined in libs/sea/domain/src/gen/kernel/types.ts.
Kernel ports tested independently without shell dependencies (see libs/sea/ports/src/gen/kernel/ports.spec.ts).
tools/flow_lint.py - Flow annotation validatortools/schemas/ast-v3.schema.json - AST v3 schemadocs/reference/sea_dsl_language_idioms.yml - P04 Flow Annotation Contractdocs/specs/shared/sds/055-kernel-execution-ports.sds.yaml