The complete workflow for implementing features in SEA™ using the spec-first pipeline.
This SOP covers Phases 7–9 of the ENGINEERING.SOP:
- Phase 7: Generate Scaffolding
- Phase 8: Build Testing Harness
- Phase 9: Implement Vertical Slices
Before starting, ensure:
1
2
3
just doctor # Environment OK
just setup # Dependencies installed
nx show projects # Workspace visible
See: Skills — Skill 0
Every feature begins with a TDD cycle. Use the unified branching workflow.
1
2
# Start a new cycle: phase, cycle-number, agent-id, slug
just cycle-start 1 1 A happy-path-order
This command:
cycle/p1-c1A-happy-path-order from devtdd, phase, cycle, agentCI Trigger: branch-rules.yml validates branch naming on PR open.
See: Branching Reference
Specs live in docs/specs/<bounded-context>/.
1
2
# Create or edit
vim docs/specs/orders/orders.adr.md
| Section | What to Write |
|---|---|
| Context | Problem domain, why a decision is needed |
| Decision | DDD + CQRS + hexagonal (or chosen approach) |
| Constraints | MUST/MUST NOT rules for generators |
| Consequences | Trade-offs, complexity added |
1
vim docs/specs/orders/orders.prd.md
REQ-### IDs1
vim docs/specs/orders/orders.sds.yaml
Machine-readable YAML with:
Validate:
1
python tools/validate_sds.py docs/specs/orders/orders.sds.yaml
CI Gate: ci.yml runs SDS validation on specs changes.
See: Spec Pipeline — Sections 1-3
Create the SEA™ model that expresses the SDS:
1
vim docs/specs/orders/orders.sea
| SDS Concept | SEA-DSL Construct |
|---|---|
| Entity | Entity "Order" |
| Value Object | Resource "Money" |
| Command | Flow + @cqrs { "kind": "command" } |
| Query | Flow + @cqrs { "kind": "query" } |
| Event | Flow + @cqrs { "kind": "event" } |
| Invariant | Policy "name" as: expression |
Every Flow must have @cqrs:
Flow "PlaceOrder"
@cqrs { "kind": "command" }
@tx { "transactional": true }
@idempotency { "enabled": true, "key": "header:X-Idempotency-Key" }
from "Customer" to "Order"
Validate:
1
2
sea validate docs/specs/orders/orders.sea
just flow-lint
See: Flow Annotations, Skills 2-4
Generate code from specs through the deterministic pipeline:
1
2
# Full pipeline via Nx
nx run specs-orders:all
Or run steps individually:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1. Parse SEA™ to AST
sea parse --format json docs/specs/orders/orders.sea > orders.ast.json
# 2. AST → IR
python tools/ast_to_ir.py orders.ast.json orders.ir.json
# 3. IR → Manifest
python tools/ir_to_manifest.py orders.ir.json orders.manifest.json
# 4. Manifest → Code
python tools/codegen/gen.py orders.manifest.json
# 5. Determinism gate
python tools/regen_check.py orders.manifest.json
CI Gate: ci.yml runs regen-check on every PR.
See: Spec Pipeline — Section 5, Nx Targets
With the manifest, scaffold the bounded context structure.
| Layer | Path |
|---|---|
| Domain | libs/orders/domain/src/gen/ |
| Application | libs/orders/application/src/gen/ |
| Ports | libs/orders/ports/src/gen/ |
| Adapters | libs/orders/adapters/src/gen/ |
| API | apps/api/src/gen/ |
1
python tools/sea_new_context.py orders
This creates:
Rule: Never manually create scaffolding. Use generators.
See: Skills — Skill 1
Tests are generated alongside code. Verify at each layer.
| Layer | Test Type | Command |
|---|---|---|
| Domain | Unit tests | nx test orders-domain |
| Application | Use-case tests | nx test orders-application |
| Adapters | Integration tests | nx test orders-adapters |
| E2E | Minimal smoke tests | nx e2e api-e2e |
1
2
just test # Baseline suite
nx run-many -t test # All libs/apps
CI Gate: ci.yml runs tests on every push.
| Symptom | Fix |
|---|---|
| Flow lint fails | Add missing @cqrs annotation |
| AST schema fails | DSL syntax error |
| IR schema fails | Check ast_to_ir.py mapping |
| Manifest schema fails | Check ir_to_manifest.py |
| Regen fails | Generator has nondeterminism |
Each slice follows the Required Order (do not skip):
Edit SEA™ to define:
Entity "Order"
Policy "TotalMustBePositive" as: Order.total.amount > 0
Define commands and queries with handlers:
Flow "PlaceOrder"
@cqrs { "kind": "command" }
@tx { "transactional": true }
from "Customer" to "Order"
Generated from flows:
OrderRepositoryUnitOfWorkMessageBusGenerated based on runtime choices in SDS:
Generated in apps/api/src/gen/app.py:
Defined in ADR constraints, generated as:
If rollout risk exists, add feature flags via manifest config.
After passing all local checks:
1
2
3
4
5
6
7
8
# Stage changes
git add docs/specs/ libs/ apps/
# Commit with conventional message
git commit -m "feat(orders): implement PlaceOrder command"
# Push
git push
CI Pipeline:
ci.yml — tests, lint, regen-checkpr-cycle-assist.yml — adds labels, wave warningsbranch-rules.yml — validates PR target1
2
# Open PR to dev
gh pr create --base dev --title "feat(orders): PlaceOrder"
python tools/validate_sds.py ...sea validate ...python tools/regen_check.py ...nx run-many -t testsrc/gen/After approval, merge to dev.
1
2
3
4
5
6
7
8
# Promote dev to stage
just promote-stage
# Promote stage to main (release)
just promote-main
# Create release tag
just release v1.2.0
See: Branching SOP
| Task | Command |
|---|---|
| Start cycle | just cycle-start <phase> <cycle> <agent> <slug> |
| Validate SDS | python tools/validate_sds.py <sds.yaml> |
| Validate SEA™ | sea validate <file.sea> |
| Full codegen | nx run specs-<ctx>:all |
| Regen check | python tools/regen_check.py <manifest.json> |
| Run tests | nx run-many -t test |
| Promote | just promote-stage / just promote-main |