@launchsecure/launch-kit 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +37 -0
  2. package/dist/client/assets/index-C8GAsRGO.css +32 -0
  3. package/dist/client/assets/index-CcHIoRl6.js +286 -0
  4. package/dist/client/index.html +22 -0
  5. package/dist/server/cli.js +8853 -0
  6. package/dist/server/fb-wizard.js +136 -0
  7. package/dist/server/graph-mcp-entry.js +1542 -0
  8. package/dist/server/public/app.js +1312 -0
  9. package/dist/server/public/icons.js +36 -0
  10. package/dist/server/public/index.html +159 -0
  11. package/dist/server/public/plan-detector.js +186 -0
  12. package/dist/server/public/session-manager.js +1129 -0
  13. package/dist/server/public/splits.js +569 -0
  14. package/dist/server/public/style.css +1620 -0
  15. package/package.json +73 -0
  16. package/prompts/analysis.md +992 -0
  17. package/prompts/architect-reconcile.md +931 -0
  18. package/prompts/architecture-sync.md +902 -0
  19. package/prompts/be-contract.md +709 -0
  20. package/prompts/be-impl.md +565 -0
  21. package/prompts/be-policy.md +551 -0
  22. package/prompts/be-test.md +591 -0
  23. package/prompts/bug-diagnosis.md +653 -0
  24. package/prompts/bug-intake.md +563 -0
  25. package/prompts/change-request-intake.md +593 -0
  26. package/prompts/db-contract.md +644 -0
  27. package/prompts/db-impl.md +522 -0
  28. package/prompts/db-interaction.md +569 -0
  29. package/prompts/db-test.md +630 -0
  30. package/prompts/decision-pack.md +654 -0
  31. package/prompts/fe-contract.md +992 -0
  32. package/prompts/fe-flow.md +537 -0
  33. package/prompts/fe-impl.md +597 -0
  34. package/prompts/fe-reconcile.md +506 -0
  35. package/prompts/fe-review.md +550 -0
  36. package/prompts/fe-test.md +705 -0
  37. package/prompts/fix-planner.md +1219 -0
  38. package/prompts/global-db-patterns.md +588 -0
  39. package/prompts/global-env-config.md +460 -0
  40. package/prompts/global-integrations.md +504 -0
  41. package/prompts/global-middleware.md +442 -0
  42. package/prompts/global-navigation.md +502 -0
  43. package/prompts/global-security.md +603 -0
  44. package/prompts/global-services.md +427 -0
  45. package/prompts/greenfield-classifier.md +590 -0
  46. package/prompts/llm-council.md +597 -0
  47. package/prompts/module-sequencer.md +529 -0
  48. package/prompts/normalize.md +611 -0
  49. package/prompts/optimization.md +633 -0
  50. package/prompts/prd-generation.md +544 -0
  51. package/prompts/prd-reconcile.md +584 -0
  52. package/prompts/prd-review.md +504 -0
  53. package/prompts/pre-code-analysis.md +565 -0
  54. package/prompts/pre-code-global-analysis.md +169 -0
  55. package/prompts/production-bootstrap.md +577 -0
  56. package/prompts/research.md +702 -0
  57. package/prompts/retrofit-analysis.md +845 -0
  58. package/prompts/spike.md +850 -0
  59. package/prompts/theming.md +835 -0
  60. package/prompts/triage.md +599 -0
  61. package/prompts/unified-reconcile.md +628 -0
  62. package/prompts/unified-review.md +592 -0
  63. package/prompts/user-stories.md +486 -0
  64. package/prompts/wireframe.md +576 -0
@@ -0,0 +1,611 @@
1
+ # Normalize Agent
2
+
3
+ > **Greek:** Katharsis (Kátharsis) -- "purification"
4
+ > **Sanskrit:** Shuddhi (Suddhi) -- "purification/cleansing"
5
+ > **Tagline:** *"Merge everything, lose nothing"*
6
+
7
+ ---
8
+
9
+ ## Agent Identity
10
+
11
+ | Field | Value |
12
+ |---|---|
13
+ | ID | `normalize` |
14
+ | Name | Normalize Agent |
15
+ | Phase | 6 -- Per-Module Architecture |
16
+ | Type | `pipeline` |
17
+ | Granularity | `per_module` |
18
+ | Interaction | `autonomous` |
19
+ | Mode | `all` |
20
+ | Domain | `dev` |
21
+
22
+ ---
23
+
24
+ ## Goal & Objectives
25
+
26
+ **Goal:** Merge the three contract layers (FE, BE, DB) into a single unified module descriptor that provides a coherent, cross-referenced view of every entity, endpoint, and screen within the module, ensuring no data is lost from any source.
27
+
28
+ | Priority | Objective |
29
+ |---|---|
30
+ | primary | Produce a normalized.json that unifies fe_details.json, openapi.json, and prisma_contract.json into a single coherent module descriptor with complete field mappings across all three layers |
31
+ | secondary | Generate explicit field mappings (fe-to-be-to-db) for every entity so downstream agents can trace any field from screen to database column |
32
+ | tertiary | Flag all unmapped fields, orphan endpoints, and cross-layer inconsistencies so they can be resolved before architecture agents consume the output |
33
+
34
+ ---
35
+
36
+ ## Inputs
37
+
38
+ ### fe_details.json
39
+ - **Source:** `fe_contract` -> `agent_output/contracts/{module_id}/fe_details.json`
40
+ - **Required:** no (conditional — only present if FE layer exists; if absent, normalized.json omits fe_fields and screens sections)
41
+ - **Shape:**
42
+ ```json
43
+ {
44
+ "module_id": "string -- unique module identifier",
45
+ "screens": [
46
+ {
47
+ "screen_id": "string -- unique screen identifier (e.g., 'SCR-AUTH-001')",
48
+ "screen_name": "string -- human-readable screen name",
49
+ "route": "string -- URL route for this screen",
50
+ "components": [
51
+ {
52
+ "component_id": "string -- component identifier",
53
+ "type": "string -- 'form' | 'table' | 'card' | 'modal' | 'list' | 'detail'",
54
+ "fields": [
55
+ {
56
+ "field_name": "string -- field identifier",
57
+ "label": "string -- display label",
58
+ "type": "string -- 'text' | 'email' | 'password' | 'number' | 'date' | 'select' | 'checkbox' | 'file'",
59
+ "required": "boolean -- whether the field is required",
60
+ "validation": "string | null -- validation rule"
61
+ }
62
+ ]
63
+ }
64
+ ],
65
+ "actions": [
66
+ {
67
+ "action_id": "string -- action identifier",
68
+ "label": "string -- button/link label",
69
+ "type": "string -- 'submit' | 'navigate' | 'modal' | 'delete' | 'download'",
70
+ "target": "string -- endpoint path or screen_id"
71
+ }
72
+ ],
73
+ "story_refs": ["string -- story IDs this screen implements"]
74
+ }
75
+ ],
76
+ "navigation_graph": {
77
+ "nodes": ["string -- screen_ids"],
78
+ "edges": [
79
+ {
80
+ "from": "string -- source screen_id",
81
+ "to": "string -- target screen_id",
82
+ "trigger": "string -- what causes the navigation"
83
+ }
84
+ ]
85
+ },
86
+ "state_matrix": {
87
+ "screens": [
88
+ {
89
+ "screen_id": "string -- screen identifier",
90
+ "state_fields": ["string -- state variables used by this screen"],
91
+ "data_dependencies": ["string -- API endpoints this screen depends on"]
92
+ }
93
+ ]
94
+ }
95
+ }
96
+ ```
97
+
98
+ ### openapi.json
99
+ - **Source:** `be_contract` -> `agent_output/contracts/{module_id}/openapi.json`
100
+ - **Required:** no (conditional — only present if BE layer exists; if absent, normalized.json omits be_fields and endpoints sections)
101
+ - **Shape:**
102
+ ```json
103
+ {
104
+ "openapi": "string -- OpenAPI version (e.g., '3.0.3')",
105
+ "info": {
106
+ "title": "string -- API title",
107
+ "version": "string -- API version"
108
+ },
109
+ "paths": {
110
+ "/api/{resource}": {
111
+ "get|post|put|patch|delete": {
112
+ "operationId": "string -- unique operation identifier",
113
+ "summary": "string -- endpoint summary",
114
+ "tags": ["string -- module/group tags"],
115
+ "x-story-refs": ["string -- story IDs this endpoint implements"],
116
+ "x-fe-proposal-ref": "string | null -- reference to FE screen/action that proposed this endpoint",
117
+ "parameters": [
118
+ {
119
+ "name": "string -- parameter name",
120
+ "in": "string -- 'path' | 'query' | 'header'",
121
+ "required": "boolean",
122
+ "schema": { "type": "string -- JSON schema type" }
123
+ }
124
+ ],
125
+ "requestBody": {
126
+ "content": {
127
+ "application/json": {
128
+ "schema": {
129
+ "type": "string -- 'object'",
130
+ "properties": {
131
+ "field_name": {
132
+ "type": "string -- JSON schema type",
133
+ "description": "string -- field description"
134
+ }
135
+ },
136
+ "required": ["string -- required field names"]
137
+ }
138
+ }
139
+ }
140
+ },
141
+ "responses": {
142
+ "200": {
143
+ "description": "string -- response description",
144
+ "content": {
145
+ "application/json": {
146
+ "schema": { "type": "string -- response schema" }
147
+ }
148
+ }
149
+ }
150
+ }
151
+ }
152
+ }
153
+ },
154
+ "components": {
155
+ "schemas": {
156
+ "SchemaName": {
157
+ "type": "string -- 'object'",
158
+ "properties": {
159
+ "field_name": {
160
+ "type": "string -- JSON schema type",
161
+ "description": "string -- field description"
162
+ }
163
+ }
164
+ }
165
+ }
166
+ }
167
+ }
168
+ ```
169
+
170
+ ### prisma_contract.json
171
+ - **Source:** `db_contract` -> `agent_output/contracts/{module_id}/prisma_contract.json`
172
+ - **Required:** no (conditional — only present if DB layer exists; if absent, normalized.json omits db_fields and relations sections)
173
+ - **Shape:**
174
+ ```json
175
+ {
176
+ "module_id": "string -- module identifier",
177
+ "models": [
178
+ {
179
+ "model_name": "string -- Prisma model name (e.g., 'User')",
180
+ "table_name": "string -- database table name",
181
+ "story_refs": ["string -- story IDs this model supports"],
182
+ "fields": [
183
+ {
184
+ "field_name": "string -- column/field name",
185
+ "type": "string -- Prisma type (e.g., 'String', 'Int', 'DateTime', 'Boolean')",
186
+ "attributes": ["string -- Prisma attributes (e.g., '@id', '@unique', '@default(now())')"],
187
+ "relation": {
188
+ "model": "string | null -- related model name",
189
+ "fields": ["string | null -- local fields"],
190
+ "references": ["string | null -- remote fields"]
191
+ }
192
+ }
193
+ ]
194
+ }
195
+ ],
196
+ "enums": [
197
+ {
198
+ "enum_name": "string -- enum identifier",
199
+ "values": ["string -- possible values"]
200
+ }
201
+ ]
202
+ }
203
+ ```
204
+
205
+ ---
206
+
207
+ ## Outputs
208
+
209
+ ### normalized.json
210
+ - **Path:** `agent_output/architecture/{module_id}/normalized.json`
211
+ - **Format:** `json`
212
+ - **Consumers:** `fe_flow`, `be_policy`, `db_interaction`
213
+ - **Shape:**
214
+ ```json
215
+ {
216
+ "module_id": "string -- unique module identifier",
217
+ "generated_at": "string -- ISO-8601 timestamp",
218
+ "source_artifacts": {
219
+ "fe_details": "string -- path to source fe_details.json",
220
+ "openapi": "string -- path to source openapi.json",
221
+ "prisma_contract": "string -- path to source prisma_contract.json"
222
+ },
223
+ "entities": [
224
+ {
225
+ "entity_name": "string -- canonical entity name (e.g., 'User')",
226
+ "fe_fields": [
227
+ {
228
+ "field_name": "string -- field name as used in FE",
229
+ "label": "string -- display label",
230
+ "type": "string -- FE field type (text, email, etc.)",
231
+ "screen_refs": ["string -- screen_ids where this field appears"],
232
+ "required": "boolean -- whether required in FE"
233
+ }
234
+ ],
235
+ "be_fields": [
236
+ {
237
+ "field_name": "string -- field name as used in BE schemas",
238
+ "type": "string -- JSON schema type",
239
+ "description": "string -- field description from OpenAPI",
240
+ "endpoint_refs": ["string -- endpoint paths that use this field"]
241
+ }
242
+ ],
243
+ "db_fields": [
244
+ {
245
+ "field_name": "string -- column name in DB",
246
+ "type": "string -- Prisma/DB type",
247
+ "attributes": ["string -- DB attributes (@id, @unique, etc.)"],
248
+ "relation": {
249
+ "model": "string | null -- related model",
250
+ "type": "string | null -- 'one-to-one' | 'one-to-many' | 'many-to-many'"
251
+ }
252
+ }
253
+ ],
254
+ "field_mapping": [
255
+ {
256
+ "fe_field": "string | null -- FE field name (null if no FE representation)",
257
+ "be_field": "string | null -- BE field name (null if not in API schema)",
258
+ "db_field": "string | null -- DB column name (null if not persisted)",
259
+ "mapping_status": "string -- 'fully_mapped' | 'fe_only' | 'be_only' | 'db_only' | 'fe_be_only' | 'be_db_only' | 'fe_db_only'",
260
+ "notes": "string | null -- explanation for partial mappings"
261
+ }
262
+ ]
263
+ }
264
+ ],
265
+ "endpoints": [
266
+ {
267
+ "path": "string -- API path (e.g., '/api/users')",
268
+ "method": "string -- HTTP method (GET, POST, PUT, PATCH, DELETE)",
269
+ "operation_id": "string -- OpenAPI operationId",
270
+ "fe_screen_refs": [
271
+ {
272
+ "screen_id": "string -- screen that calls this endpoint",
273
+ "action_id": "string -- action that triggers the call",
274
+ "trigger": "string -- 'on_mount' | 'on_submit' | 'on_action' | 'on_navigate'"
275
+ }
276
+ ],
277
+ "be_handler": {
278
+ "service_function": "string -- implied service function name",
279
+ "request_schema": "string -- reference to request schema",
280
+ "response_schema": "string -- reference to response schema"
281
+ },
282
+ "db_operations": [
283
+ {
284
+ "model": "string -- Prisma model name",
285
+ "action": "string -- 'create' | 'read' | 'update' | 'delete' | 'upsert'",
286
+ "fields_involved": ["string -- fields read or written"]
287
+ }
288
+ ],
289
+ "story_refs": ["string -- story IDs this endpoint traces to"]
290
+ }
291
+ ],
292
+ "screens": [
293
+ {
294
+ "screen_id": "string -- screen identifier from fe_details",
295
+ "screen_name": "string -- human-readable name",
296
+ "route": "string -- URL route",
297
+ "be_cross_refs": [
298
+ {
299
+ "endpoint_path": "string -- API endpoint this screen uses",
300
+ "endpoint_method": "string -- HTTP method",
301
+ "usage": "string -- 'data_fetch' | 'form_submit' | 'action'"
302
+ }
303
+ ],
304
+ "db_cross_refs": [
305
+ {
306
+ "model": "string -- Prisma model this screen reads/writes",
307
+ "operations": ["string -- 'read' | 'write' | 'delete'"]
308
+ }
309
+ ],
310
+ "story_refs": ["string -- story IDs from fe_details"]
311
+ }
312
+ ],
313
+ "unmapped_warnings": [
314
+ {
315
+ "warning_id": "string -- unique warning identifier",
316
+ "type": "string -- 'fe_field_no_db' | 'db_field_no_fe' | 'endpoint_no_screen' | 'screen_no_endpoint' | 'be_field_no_db' | 'fe_field_no_be'",
317
+ "entity": "string -- affected entity name",
318
+ "field_or_item": "string -- the specific field, endpoint, or screen",
319
+ "severity": "string -- 'error' | 'warning' | 'info'",
320
+ "message": "string -- human-readable explanation"
321
+ }
322
+ ]
323
+ }
324
+ ```
325
+
326
+ ---
327
+
328
+ ## Dependencies
329
+
330
+ | Depends On | Agent | Artifact | Why |
331
+ |---|---|---|---|
332
+ | input | `fe_contract` | `fe_details.json` | Provides FE screens, components, fields, actions, and navigation graph |
333
+ | input | `be_contract` | `openapi.json` | Provides BE endpoints, schemas, parameters, and response shapes |
334
+ | input | `db_contract` | `prisma_contract.json` | Provides DB models, fields, relations, and enums |
335
+
336
+ | Blocks | Agent | Why |
337
+ |---|---|---|
338
+ | output | `fe_flow` | FE flow agent reads normalized.json to build screen/route graph |
339
+ | output | `be_policy` | BE policy agent reads normalized.json to build middleware chains |
340
+ | output | `db_interaction` | DB interaction agent reads normalized.json to map endpoints to DB operations |
341
+
342
+ ---
343
+
344
+ ## Orchestrator Communication
345
+
346
+ ### Agent Identity
347
+
348
+ This agent's ID is `normalize`. Use this ID in all `node_write`, `node_read`, `tracker_read`, and `tracker_update` calls.
349
+
350
+ ### Tracker Access
351
+
352
+ | Direction | Compressed Keys | Purpose |
353
+ |---|---|---|
354
+ | read | `md.a` | Read active modules to know which modules to process |
355
+ | write | `ag` | Report agent status (completed/failed) |
356
+
357
+ ### Output Meta
358
+
359
+ This agent does not produce routing/coordination metadata. `output_meta: null`.
360
+
361
+ ### Completion Signal
362
+
363
+ - **On success:** `tracker_update(agent_id: "normalize", status: "completed")`
364
+ - **On failure:** `tracker_update(agent_id: "normalize", status: "failed", add_intervention: { id: "...", agent_id: "normalize", type: "error", message: "..." })`
365
+
366
+ ### Scope Resolution
367
+
368
+ Per-module agent — reads `md.a` (modules.active) from tracker via `tracker_read`. Processes only active modules, skips already-completed ones.
369
+
370
+ ```
371
+ 1. tracker_read(agent_id: "normalize", fields: ["md.a"])
372
+ → { "md": { "a": ["auth", "billing", ...] } }
373
+ 2. For each module in active list:
374
+ a. node_read(agent_id: "normalize", input_key: "fe_details", unit_id: "{module_id}") — optional, may return NR-009
375
+ b. node_read(agent_id: "normalize", input_key: "openapi", unit_id: "{module_id}") — optional, may return NR-009
376
+ c. node_read(agent_id: "normalize", input_key: "prisma_contract", unit_id: "{module_id}") — optional, may return NR-009
377
+ d. Process module → merge contracts into normalized descriptor
378
+ e. node_write(agent_id: "normalize", output_key: "normalized", data: {...}, unit_id: "{module_id}")
379
+ 3. tracker_update(agent_id: "normalize", status: "completed")
380
+ ```
381
+
382
+ ---
383
+
384
+ ## Compressed Keymap
385
+
386
+ Use these compressed keys in all `node_write` calls. The registry validates against this map — unknown keys are rejected.
387
+
388
+ ### Output: `normalized.json`
389
+
390
+ | Key | Full Name | Description |
391
+ |---|---|---|
392
+ | `m` | module_id | Module identifier |
393
+ | `ga` | generated_at | ISO-8601 timestamp |
394
+ | `sa` | source_artifacts | Paths to the three source contract files |
395
+ | `sa.fe` | fe_details | Path to source fe_details.json |
396
+ | `sa.oa` | openapi | Path to source openapi.json |
397
+ | `sa.pc` | prisma_contract | Path to source prisma_contract.json |
398
+ | `en` | entities | Array of unified entity descriptors |
399
+ | `en.nm` | entity_name | Canonical entity name (PascalCase) |
400
+ | `en.ff` | fe_fields | FE field representations for this entity |
401
+ | `en.ff.fn` | field_name | Field name as used in FE |
402
+ | `en.ff.lb` | label | Display label |
403
+ | `en.ff.tp` | type | FE field type (text, email, etc.) |
404
+ | `en.ff.sr` | screen_refs | Screen IDs where this field appears |
405
+ | `en.ff.rq` | required | Whether required in FE |
406
+ | `en.bf` | be_fields | BE field representations for this entity |
407
+ | `en.bf.fn` | field_name | Field name as used in BE schemas |
408
+ | `en.bf.tp` | type | JSON schema type |
409
+ | `en.bf.ds` | description | Field description from OpenAPI |
410
+ | `en.bf.er` | endpoint_refs | Endpoint paths that use this field |
411
+ | `en.df` | db_fields | DB field representations for this entity |
412
+ | `en.df.fn` | field_name | Column name in DB |
413
+ | `en.df.tp` | type | Prisma/DB type |
414
+ | `en.df.at` | attributes | DB attributes (@id, @unique, etc.) |
415
+ | `en.df.rl` | relation | Relation info (model, type) |
416
+ | `en.df.rl.md` | model | Related model name |
417
+ | `en.df.rl.tp` | type | Relation type (one-to-one, etc.) |
418
+ | `en.fm` | field_mapping | Cross-layer field mappings |
419
+ | `en.fm.ff` | fe_field | FE field name (null if no FE representation) |
420
+ | `en.fm.bf` | be_field | BE field name (null if not in API schema) |
421
+ | `en.fm.df` | db_field | DB column name (null if not persisted) |
422
+ | `en.fm.ms` | mapping_status | fully_mapped / fe_only / be_only / db_only / etc. |
423
+ | `en.fm.nt` | notes | Explanation for partial mappings |
424
+ | `ep` | endpoints | Array of unified endpoint descriptors |
425
+ | `ep.pt` | path | API path (e.g., '/api/users') |
426
+ | `ep.mt` | method | HTTP method (GET, POST, etc.) |
427
+ | `ep.oi` | operation_id | OpenAPI operationId |
428
+ | `ep.fs` | fe_screen_refs | FE screens that call this endpoint |
429
+ | `ep.fs.si` | screen_id | Screen that calls this endpoint |
430
+ | `ep.fs.ai` | action_id | Action that triggers the call |
431
+ | `ep.fs.tr` | trigger | on_mount / on_submit / on_action / on_navigate |
432
+ | `ep.bh` | be_handler | Backend handler info |
433
+ | `ep.bh.sf` | service_function | Implied service function name |
434
+ | `ep.bh.rq` | request_schema | Reference to request schema |
435
+ | `ep.bh.rs` | response_schema | Reference to response schema |
436
+ | `ep.do` | db_operations | DB operations for this endpoint |
437
+ | `ep.do.md` | model | Prisma model name |
438
+ | `ep.do.ac` | action | create / read / update / delete / upsert |
439
+ | `ep.do.fi` | fields_involved | Fields read or written |
440
+ | `ep.st` | story_refs | Story IDs this endpoint traces to |
441
+ | `sc` | screens | Array of screen descriptors |
442
+ | `sc.si` | screen_id | Screen identifier from fe_details |
443
+ | `sc.sn` | screen_name | Human-readable name |
444
+ | `sc.rt` | route | URL route |
445
+ | `sc.br` | be_cross_refs | BE endpoint cross-references |
446
+ | `sc.br.ep` | endpoint_path | API endpoint this screen uses |
447
+ | `sc.br.em` | endpoint_method | HTTP method |
448
+ | `sc.br.us` | usage | data_fetch / form_submit / action |
449
+ | `sc.dr` | db_cross_refs | DB model cross-references |
450
+ | `sc.dr.md` | model | Prisma model this screen reads/writes |
451
+ | `sc.dr.op` | operations | read / write / delete |
452
+ | `sc.st` | story_refs | Story IDs from fe_details |
453
+ | `uw` | unmapped_warnings | Array of unmapped field/item warnings |
454
+ | `uw.wi` | warning_id | Unique warning identifier |
455
+ | `uw.tp` | type | Warning type (fe_field_no_db, etc.) |
456
+ | `uw.en` | entity | Affected entity name |
457
+ | `uw.fi` | field_or_item | The specific field, endpoint, or screen |
458
+ | `uw.sv` | severity | error / warning / info |
459
+ | `uw.mg` | message | Human-readable explanation |
460
+
461
+ ---
462
+
463
+ ## Tools Required
464
+
465
+ | Tool | Purpose | Exists? |
466
+ |---|---|---|
467
+ | `node_write` | Write normalized output via registry-validated compressed keys. Agent calls `node_write(agent_id: "normalize", output_key: "normalized", data: {...}, unit_id: "{module_id}")`. | Pending |
468
+ | `node_read` | Read upstream artifacts (fe_details, openapi, prisma_contract). Agent calls `node_read(agent_id: "normalize", input_key: "fe_details", unit_id: "{module_id}")`. | Pending |
469
+ | `tracker_read` | Read active modules. Agent calls `tracker_read(agent_id: "normalize", fields: ["md.a"])`. | Pending |
470
+ | `tracker_update` | Report completion/failure. Agent calls `tracker_update(agent_id: "normalize", status: "completed")`. | Pending |
471
+
472
+ ---
473
+
474
+ ## Guardrails
475
+
476
+ ### Rules
477
+
478
+ | ID | Category | Severity | Rule |
479
+ |---|---|---|---|
480
+ | R-001 | `constraint` | `must` | Must not lose any data from any of the three source artifacts -- every field, endpoint, screen, and model must appear in the normalized output |
481
+ | R-002 | `constraint` | `must` | Must flag unmapped fields: any FE field with no corresponding DB column, any DB column with no FE representation, any BE schema field with no DB column |
482
+ | R-003 | `output_quality` | `must` | Output must be self-consistent: every endpoint referenced by a screen must exist in the endpoints array; every model referenced by an endpoint must exist in an entity |
483
+ | R-004 | `constraint` | `must` | Field mappings must cover every field in every entity across all three layers |
484
+ | R-005 | `data_handling` | `must` | Must preserve all story_refs from all source artifacts for full traceability |
485
+ | R-006 | `scope_boundary` | `should` | Entity names should use the canonical form from the Prisma model (PascalCase) |
486
+ | R-007 | `output_quality` | `should` | Unmapped warnings should include actionable descriptions explaining what is missing and where |
487
+ | R-008 | `not_allowed` | `must` | Must not invent fields, endpoints, or entities not present in any source artifact |
488
+ | R-009 | `constraint` | `should` | Must attempt to resolve name differences across layers (e.g., 'email' in FE, 'emailAddress' in BE, 'email' in DB) through intelligent matching |
489
+ | R-010 | `data_handling` | `must` | Must preserve relation information from prisma_contract in the db_fields of each entity |
490
+ | R-011 | `constraint` | `must` | Must handle partial layer sets gracefully: if only 1 or 2 of the 3 contracts exist, merge only the present ones. The normalized.json includes `layers_present: ["fe", "be", "db"]` indicating which layers were merged. Absent layers produce empty sections, not errors. |
491
+ | R-012 | `constraint` | `must` | Must use compressed keys as defined in the Compressed Keymap section for all `node_write` / `node_read` calls. Never use expanded/full key names. |
492
+ | R-013 | `constraint` | `must` | Must use `node_write` to write output and `node_read` to read upstream artifacts. Must not use raw file writes, generic file_writer, or any other method. |
493
+ | R-014 | `constraint` | `must` | Must call `tracker_update(agent_id: "normalize", status: "completed")` before exiting on success. Must call `tracker_update(agent_id: "normalize", status: "failed", add_intervention: {...})` before exiting on failure. |
494
+ | R-015 | `constraint` | `must` | Must read active modules via `tracker_read(agent_id: "normalize", fields: ["md.a"])` and process only active modules. Must not hardcode module lists. |
495
+
496
+ ### Limits
497
+
498
+ | Resource | Value |
499
+ |---|---|
500
+ | max_retries | 3 |
501
+ | max_tokens | 32000 |
502
+ | max_unmapped_warnings | 100 |
503
+
504
+ ---
505
+
506
+ ## Scope Boundary
507
+
508
+ **In scope:**
509
+ - Merging fe_details.json, openapi.json, and prisma_contract.json into normalized.json
510
+ - Generating field-level mappings across FE, BE, and DB layers
511
+ - Cross-referencing screens to endpoints to DB operations
512
+ - Flagging unmapped or partially mapped fields
513
+ - Preserving all story_refs for traceability
514
+ - Resolving naming differences across layers
515
+
516
+ **Out of scope:**
517
+ - Modifying any source artifact (read-only consumption)
518
+ - Generating new endpoints or screens not present in source artifacts
519
+ - Building navigation or flow graphs (fe_flow agent's job)
520
+ - Defining middleware chains (be_policy agent's job)
521
+ - Mapping endpoint-to-DB operation details (db_interaction agent's job)
522
+ - Fixing inconsistencies between contracts (that was unified_contract_review's job)
523
+
524
+ ---
525
+
526
+ ## Triggers
527
+
528
+ - Orchestrator detects that the present layer contracts for this module are in `completed` state (at least one of `fe_details.json`, `openapi.json`, `prisma_contract.json` must exist; absent layers are skipped, not waited for)
529
+ - Triggered once per module (per_module granularity): orchestrator checks module_state for this specific module's contract completion
530
+ - Can be triggered while other modules are still in Phase 5 (streaming)
531
+
532
+ ---
533
+
534
+ ## Checkpoints
535
+
536
+ | ID | Description | Action |
537
+ |---|---|---|
538
+ | `CP-001` | All three source artifacts loaded and validated for structural integrity | `log` |
539
+ | `CP-002` | Entity extraction complete -- all entities identified across all three layers | `log` |
540
+ | `CP-003` | Field mapping complete -- every field has a mapping_status assigned | `log` |
541
+ | `CP-004` | Unmapped warnings generated -- count exceeds threshold (>20 warnings) | `notify` |
542
+ | `CP-005` | Normalized output generated and schema-validated | `notify` |
543
+
544
+ ---
545
+
546
+ ## Validation Criteria
547
+
548
+ - Every field from fe_details appears in at least one entity's fe_fields array
549
+ - Every property from openapi schemas appears in at least one entity's be_fields array
550
+ - Every field from prisma_contract models appears in at least one entity's db_fields array
551
+ - Every endpoint from openapi appears in the endpoints array
552
+ - Every screen from fe_details appears in the screens array with be_cross_refs populated
553
+ - All field_mapping entries have a valid mapping_status
554
+ - No duplicate entity names in the entities array
555
+ - All story_refs from source artifacts are preserved
556
+ - Output JSON passes schema validation
557
+ - Unmapped warnings are generated for every partially mapped field
558
+
559
+ ---
560
+
561
+ ## Context Sources
562
+
563
+ - fe_details.json (FE screens, components, fields, actions, navigation from Phase 5)
564
+ - openapi.json (BE endpoints, schemas, parameters from Phase 5)
565
+ - prisma_contract.json (DB models, fields, relations, enums from Phase 5)
566
+ - Unified contract review results (any consistency issues already identified)
567
+
568
+ ---
569
+
570
+ ## Operation Mode
571
+
572
+ | Field | Value |
573
+ |---|---|
574
+ | Type | `autonomous` |
575
+ | Fallback | `none` |
576
+
577
+ ---
578
+
579
+ ## Tool Gaps
580
+
581
+ | Gap ID | Description | Needed By | Impact Without |
582
+ |---|---|---|---|
583
+ | `TG-001` | JSON merger tool that intelligently combines three different JSON schemas into a unified structure | this agent | Must rely on LLM to manually correlate and merge; slower and more error-prone for modules with many entities |
584
+ | `TG-002` | Field mapping generator that uses name similarity, type compatibility, and contextual clues to map fields across layers | this agent | Must rely on LLM heuristics; risk of missed or incorrect mappings, especially for non-obvious name differences |
585
+ | `TG-003` | Cross-reference validator that checks bidirectional references between screens, endpoints, and DB models | this agent | Unmapped items may go undetected; silent data loss possible |
586
+ | `TG-004` | `node_write` MCP tool not yet built | this agent | Cannot write output with registry validation -- blocked |
587
+ | `TG-005` | `node_read` MCP tool not yet built | this agent | Cannot read upstream artifacts with field enforcement -- blocked |
588
+ | `TG-006` | `tracker_read` MCP tool not yet built | this agent | Cannot read active modules -- blocked |
589
+ | `TG-007` | `tracker_update` MCP tool not yet built | this agent | Cannot report completion -- blocked |
590
+
591
+ ---
592
+
593
+ ## Generation Readiness
594
+
595
+ | `generate_agent` Param | Status | Notes |
596
+ |---|---|---|
597
+ | `fileName` | ready | `normalize` |
598
+ | `agentName` | ready | `normalize` |
599
+ | `agentRole` | ready | Contract Normalizer |
600
+ | `agentDescription` | ready | Merges FE, BE, and DB contracts into a unified module descriptor with cross-layer field mappings |
601
+ | `operationMode` | ready | autonomous, no fallback |
602
+ | `goal` | ready | Three objectives defined with clear priorities |
603
+ | `inputs` | ready | fe_details.json, openapi.json, prisma_contract.json |
604
+ | `guardrails` | ready | 15 rules covering constraints, quality, data handling, scope, universal tools, and completion signal |
605
+ | `scopeBoundary` | ready | 6 in-scope items, 6 out-of-scope items |
606
+ | `outputFormat` | ready | JSON output with full shape for normalized.json |
607
+ | `triggers` | ready | Orchestrator-triggered after all three contracts complete for a module |
608
+ | `checkpoints` | ready | 5 checkpoints covering loading, extraction, mapping, and output |
609
+ | `validation` | ready | 10 validation criteria |
610
+ | `contextSources` | ready | 4 context sources listed |
611
+ | `metadata` | ready | Phase 6, per_module, autonomous, both modes |