Complete the SEA-Forge™ code generation pipeline so that running python tools/codegen/gen.py <context>.manifest.json produces fully working code with no TODOs for all 17 bounded contexts.
semantic-core context has complete manifest with field definitions → generates working codecommand.py.jinja2, query.py.jinja2, event.py.jinja2) are ready to generate complete implementationsfields: {} in their aggregatesir_to_manifest.py creates empty fields dictionaries instead of reading from SDS YAML1
docs/specs/<context>/<context>.sds.yaml
See: docs/specs/developer-tooling/reference/002-sds-yaml-format.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
sds:
id: SDS-<NNN>
title: <Context Name> Context SDS
bounded_context: <context-name>
version: 1.0.0
status: draft
# CRITICAL: Define fields for ALL aggregates in the manifest
domain:
aggregates:
- name: <AggregateName>
root: true
identity: <IdentityField>
fields:
id: string
# Add all fields with types: string, number, boolean, datetime, object, object[], uuid
field_name: type
invariants: []
# Define commands with input/output schemas
cqrs:
commands:
- id: CMD-<NNN>
name: <CommandName>
input:
field_name: type
output: <AggregateName>
transactional: true
emits: [<EventName>]
touches:
aggregates: [<AggregateName>]
queries:
- id: QRY-<NNN>
name: <QueryName>
input:
id: string
output: <AggregateName>
consistency: eventual
read_model:
source: primary_db
# Define events with payload schemas
events:
- id: EVT-<NNN>
name: <EventName>
payload:
id: string
timestamp: datetime
publish:
topic: <context>.<event_name>.v1
delivery: at_least_once
Priority 1 - Have commands/queries but no field definitions:
| Context | Aggregates | Commands | Queries | Status |
|———|————|———-|———|——–|
| llm-provider | 9 | 2 | 2 | Needs SDS YAML |
| context | 21 | 3 | 4 | Needs SDS YAML |
| sea-api | 9 | 2 | 1 | Needs SDS YAML |
Priority 2 - Have aggregates but no commands/queries:
| Context | Aggregates | Commands | Queries | Status |
|———|————|———-|———|——–|
| governance-runtime | 5 | 0 | 0 | Needs CQRS + fields |
| governance | 3 | 0 | 0 | Needs CQRS + fields |
| documentation | 17 | 0 | 0 | Needs CQRS + fields |
| ingest | 2 | 0 | 0 | Needs CQRS + fields |
| query | 3 | 0 | 0 | Needs CQRS + fields |
| federal | 4 | 0 | 0 | Needs CQRS + fields |
| developer-tooling | 6 | 0 | 0 | Needs CQRS + fields |
Priority 3 - Already have field definitions (verify only):
| Context | Aggregates | Commands | Queries | Status |
|———|————|———-|———|——–|
| semantic-core | 4 | 4 | 5 | ✅ Complete |
| cognitive-extension | 5 | 0 | 0 | Has fields, needs CQRS |
| memory | 3 | 2 | 2 | Has fields, verify |
| healthcare | 4 | 4 | 4 | Has fields, verify |
| finance | 4 | 0 | 0 | Has fields, needs CQRS |
| architectural-governance | 4 | 0 | 0 | Has fields, needs CQRS |
For each aggregate, examine:
docs/specs/<context>/<context>.sea) - entity names and relationshipsdocs/specs/<context>/<context>.manifest.json) - aggregate names, command/query definitionssemantic-core as the reference patternExample: For LlmProvider aggregate in llm-provider context:
1
2
3
4
5
6
7
8
9
10
11
12
- name: LlmProvider
root: true
identity: id
fields:
id: string
name: string
endpoint: string
api_key_ref: string # Reference to secret, not actual key
model_specs: object[]
is_active: boolean
created_at: datetime
updated_at: datetime
1
tools/ir_to_manifest.py
Line 56-57:
1
aggregates = {sym["name"]: {"fields": {}} for sym in entities.values()}
This always creates empty fields: {}.
1
2
3
4
5
6
7
8
9
10
11
12
def load_sds_yaml(context_name: str) -> dict:
"""Load SDS YAML for a bounded context."""
sds_paths = [
Path(f"docs/specs/{context_name}/{context_name}.sds.yaml"),
Path(f"specs/{context_name}/{context_name}.sds.yaml"),
]
for path in sds_paths:
if path.exists():
import yaml
with open(path) as f:
return yaml.safe_load(f)
return {}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
def merge_sds_fields(aggregates: dict, sds: dict) -> dict:
"""Merge field definitions from SDS YAML into aggregates."""
sds_aggregates = {}
for agg in sds.get("domain", {}).get("aggregates", []):
name = agg.get("name")
if name:
sds_aggregates[name] = {
"fields": {
field_name: {"type": field_type, "required": True}
for field_name, field_type in agg.get("fields", {}).items()
}
}
# Merge into existing aggregates
for name, agg in aggregates.items():
if name in sds_aggregates:
agg["fields"] = sds_aggregates[name]["fields"]
return aggregates
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
def merge_sds_cqrs(cqrs: dict, sds: dict, context_name: str) -> dict:
"""Merge CQRS definitions from SDS YAML."""
sds_cqrs = sds.get("cqrs", {})
# Merge commands
for cmd in sds_cqrs.get("commands", []):
cmd_name = cmd.get("name")
if cmd_name and cmd_name not in cqrs.get("commands", {}):
cqrs["commands"][cmd_name] = {
"id": f"command:{context_name}:{cmd_name}",
"aggregate": cmd.get("touches", {}).get("aggregates", [None])[0],
"description": cmd.get("description", f"{cmd_name} command"),
"input": {
k: {"type": v, "required": True}
for k, v in cmd.get("input", {}).items()
},
"output": cmd.get("output", "void"),
"emits": cmd.get("emits", []),
"preconditions": cmd.get("preconditions", []),
"state_changes": cmd.get("state_changes", ""),
}
# Merge queries (similar pattern)
for qry in sds_cqrs.get("queries", []):
qry_name = qry.get("name")
if qry_name and qry_name not in cqrs.get("queries", {}):
cqrs["queries"][qry_name] = {
"id": f"query:{context_name}:{qry_name}",
"aggregate": qry.get("touches", {}).get("aggregates", [None])[0] if qry.get("touches") else None,
"description": qry.get("description", f"{qry_name} query"),
"input": {
k: {"type": v, "required": True}
for k, v in qry.get("input", {}).items()
},
"output": qry.get("output", "unknown"),
"read_model": qry.get("read_model", {}).get("source", "primary_db"),
"consistency": qry.get("consistency", "eventual"),
}
return cqrs
1
2
3
4
5
# After creating initial aggregates dict
sds = load_sds_yaml(context_name)
aggregates = merge_sds_fields(aggregates, sds)
cqrs = merge_sds_cqrs(cqrs, sds, context_name)
events = merge_sds_events(events, sds, context_name) # Similar pattern
1
2
# At top of file
import yaml # pip install pyyaml
After implementation, run these checks:
1
2
ls docs/specs/*/$(basename $PWD).sds.yaml 2>/dev/null | wc -l
# Should output: 17 (one per context)
1
2
3
4
5
for ctx in llm-provider context sea-api governance-runtime governance \
documentation ingest query federal developer-tooling \
cognitive-extension memory healthcare finance architectural-governance; do
python tools/ir_to_manifest.py docs/specs/$ctx/$ctx.ir.json > docs/specs/$ctx/$ctx.manifest.json
done
1
2
3
4
5
6
7
8
9
10
11
12
python3 -c "
import json
from pathlib import Path
for mf in Path('docs/specs').rglob('*.manifest.json'):
data = json.load(open(mf))
aggs = data.get('model', {}).get('aggregates', {})
aggs_with_fields = sum(1 for a in aggs.values() if a.get('fields'))
if len(aggs) != aggs_with_fields:
print(f'❌ {mf.stem}: {aggs_with_fields}/{len(aggs)} aggregates have fields')
else:
print(f'✅ {mf.stem}: All {len(aggs)} aggregates have fields')
"
1
2
3
for ctx in semantic-core llm-provider context sea-api governance-runtime; do
python tools/codegen/gen.py docs/specs/$ctx/$ctx.manifest.json
done
1
2
grep -rn "TODO\|Implement" libs/*/application/src/gen/ libs/*/domain/src/gen/ 2>/dev/null
# Should output: nothing (no matches)
1
python -m pytest libs/*/adapters/tests/ -v
Create docs/specs/llm-provider/llm-provider.sds.yaml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
sds:
id: SDS-049
title: LLM Provider Context SDS
bounded_context: llm-provider
version: 1.0.0
status: draft
domain:
aggregates:
- name: LlmProvider
root: true
identity: id
fields:
id: string
name: string
provider_type: string # openai, anthropic, ollama, openrouter
endpoint: string
api_key_ref: string
is_active: boolean
created_at: datetime
updated_at: datetime
- name: ModelSpec
identity: id
fields:
id: string
provider_id: string
model_name: string
context_window: number
max_tokens: number
supports_streaming: boolean
supports_functions: boolean
cost_per_1k_input: number
cost_per_1k_output: number
- name: ChatMessage
identity: id
fields:
id: string
role: string # system, user, assistant, function
content: string
name: string
function_call: object
created_at: datetime
- name: ChatCompletion
identity: id
fields:
id: string
provider_id: string
model: string
messages: object[]
response: string
usage: object
finish_reason: string
created_at: datetime
latency_ms: number
- name: Embedding
identity: id
fields:
id: string
provider_id: string
model: string
input_text: string
vector: object # float array
dimensions: number
created_at: datetime
- name: FallbackChain
identity: id
fields:
id: string
name: string
provider_ids: object[] # ordered list
fallback_on_error: boolean
fallback_on_rate_limit: boolean
created_at: datetime
- name: ProviderConfig
identity: id
fields:
id: string
provider_id: string
timeout_ms: number
max_retries: number
rate_limit_rpm: number
rate_limit_tpm: number
- name: ProviderHealth
identity: id
fields:
id: string
provider_id: string
is_healthy: boolean
last_check_at: datetime
error_count: number
avg_latency_ms: number
- name: TokenUsage
identity: id
fields:
id: string
provider_id: string
model: string
prompt_tokens: number
completion_tokens: number
total_tokens: number
cost: number
timestamp: datetime
cqrs:
commands:
- id: CMD-001
name: CompleteChat
description: Send chat messages and receive completion
input:
provider_id: string
model: string
messages: object[]
temperature: number
max_tokens: number
output: ChatCompletion
transactional: false
emits: [ChatCompleted]
touches:
aggregates: [ChatCompletion, TokenUsage]
preconditions:
- provider must be active
- model must be supported
- id: CMD-002
name: GenerateEmbedding
description: Generate vector embedding for text
input:
provider_id: string
model: string
input_text: string
output: Embedding
transactional: false
emits: [EmbeddingGenerated]
touches:
aggregates: [Embedding, TokenUsage]
queries:
- id: QRY-001
name: GetProvider
description: Retrieve provider by ID
input:
id: string
output: LlmProvider
consistency: strong
read_model:
source: primary_db
- id: QRY-002
name: ListProviders
description: List all active providers
input: {}
output: LlmProvider[]
consistency: eventual
read_model:
source: primary_db
events:
- id: EVT-001
name: ChatCompleted
payload:
completion_id: string
provider_id: string
model: string
tokens_used: number
latency_ms: number
timestamp: datetime
publish:
topic: llm-provider.chat_completed.v1
delivery: at_least_once
- id: EVT-002
name: EmbeddingGenerated
payload:
embedding_id: string
provider_id: string
dimensions: number
timestamp: datetime
publish:
topic: llm-provider.embedding_generated.v1
delivery: at_least_once
When complete:
<context>.sds.yaml filesir_to_manifest.py reads SDS YAML and populates fieldspython tools/codegen/gen.py <manifest> generates code with NO TODOsgrep -r "TODO" libs/*/src/gen/ returns nothingsemantic-core as the reference implementationstring or object as safe defaultstransactional: trueconsistency: eventual or strong*_at (created_at, updated_at, etc.)string type with required: true