@tdk-landscape/tdk-cli-core 1.3.15 → 1.3.22

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 (274) hide show
  1. package/Tiltfile +144 -0
  2. package/discovery/AGENTS.md +362 -0
  3. package/discovery/TILT_DISCOVERY.star +424 -0
  4. package/discovery/Tiltfile +58 -0
  5. package/discovery/config.star +258 -0
  6. package/discovery/constants.star +127 -0
  7. package/discovery/deterministic.star +211 -0
  8. package/discovery/discovery_daemon.star +191 -0
  9. package/discovery/discovery_orchestrator.star +460 -0
  10. package/discovery/filtering.star +5 -0
  11. package/discovery/identity-management-backend/service.yaml +26 -0
  12. package/discovery/identity-management-frontend/service.yaml +29 -0
  13. package/discovery/identity-sdk/service.yaml +9 -0
  14. package/discovery/incremental_discovery.star +213 -0
  15. package/discovery/indexing.star +7 -0
  16. package/discovery/json_manifest_scanner.star +51 -0
  17. package/discovery/libraries.star +46 -0
  18. package/discovery/loading.star +23 -0
  19. package/discovery/manifest/constants.star +104 -0
  20. package/discovery/manifest/loading.star +386 -0
  21. package/discovery/manifest/normalize.star +281 -0
  22. package/discovery/manifest/validation.star +108 -0
  23. package/discovery/normalization.star +11 -0
  24. package/discovery/registry.star +544 -0
  25. package/discovery/resource_snapshot.py +382 -0
  26. package/discovery/resource_snapshot.star +143 -0
  27. package/discovery/schemas.star +1 -0
  28. package/discovery/services/platform/cdc/debezium/nats-connector/service.yaml +9 -0
  29. package/discovery/services/platform/cdc/nats-http-bridge/service.yaml +9 -0
  30. package/discovery/services/platform/orchestrator/orchestrator-glue-backend/service.yaml +26 -0
  31. package/discovery/services/platform/synthetic-monitor/service.yaml +9 -0
  32. package/discovery/test_resource_snapshot.py +251 -0
  33. package/discovery/validation.star +78 -0
  34. package/discovery/versioning.star +1 -0
  35. package/dist/commands/config.d.ts.map +1 -1
  36. package/dist/commands/config.js +11 -0
  37. package/dist/commands/config.js.map +1 -1
  38. package/dist/commands/doctor.d.ts.map +1 -1
  39. package/dist/commands/doctor.js +1 -2
  40. package/dist/commands/doctor.js.map +1 -1
  41. package/dist/commands/project.d.ts.map +1 -1
  42. package/dist/commands/project.js +36 -41
  43. package/dist/commands/project.js.map +1 -1
  44. package/dist/commands/resource.d.ts.map +1 -1
  45. package/dist/commands/resource.js +51 -55
  46. package/dist/commands/resource.js.map +1 -1
  47. package/dist/commands/stack.d.ts.map +1 -1
  48. package/dist/commands/stack.js +22 -24
  49. package/dist/commands/stack.js.map +1 -1
  50. package/dist/commands/ui.d.ts.map +1 -1
  51. package/dist/commands/ui.js +1 -2
  52. package/dist/commands/ui.js.map +1 -1
  53. package/dist/commands/up.d.ts.map +1 -1
  54. package/dist/commands/up.js +1 -2
  55. package/dist/commands/up.js.map +1 -1
  56. package/dist/commands/upgrade.d.ts +8 -0
  57. package/dist/commands/upgrade.d.ts.map +1 -1
  58. package/dist/commands/upgrade.js +59 -18
  59. package/dist/commands/upgrade.js.map +1 -1
  60. package/dist/generator/extension-fetch.d.ts +19 -0
  61. package/dist/generator/extension-fetch.d.ts.map +1 -1
  62. package/dist/generator/extension-fetch.js +71 -5
  63. package/dist/generator/extension-fetch.js.map +1 -1
  64. package/dist/generator/template-engine.d.ts +1 -0
  65. package/dist/generator/template-engine.d.ts.map +1 -1
  66. package/dist/generator/template-engine.js +50 -6
  67. package/dist/generator/template-engine.js.map +1 -1
  68. package/dist/utils/command-helpers.d.ts.map +1 -1
  69. package/dist/utils/command-helpers.js +7 -9
  70. package/dist/utils/command-helpers.js.map +1 -1
  71. package/dist/utils/constants.d.ts +1 -0
  72. package/dist/utils/constants.d.ts.map +1 -1
  73. package/dist/utils/constants.js +1 -0
  74. package/dist/utils/constants.js.map +1 -1
  75. package/dist/utils/errors.d.ts +2 -0
  76. package/dist/utils/errors.d.ts.map +1 -1
  77. package/dist/utils/errors.js +6 -1
  78. package/dist/utils/errors.js.map +1 -1
  79. package/dist/utils/project-features.d.ts.map +1 -1
  80. package/dist/utils/project-features.js +1 -1
  81. package/dist/utils/project-features.js.map +1 -1
  82. package/dist/utils/resource-features.d.ts.map +1 -1
  83. package/dist/utils/resource-features.js +2 -2
  84. package/dist/utils/resource-features.js.map +1 -1
  85. package/dist/utils/tar.js +4 -4
  86. package/dist/utils/tar.js.map +1 -1
  87. package/dist/utils/validation.d.ts +7 -0
  88. package/dist/utils/validation.d.ts.map +1 -1
  89. package/dist/utils/validation.js +9 -0
  90. package/dist/utils/validation.js.map +1 -1
  91. package/engine/AGENTS.md +705 -0
  92. package/engine/README.md +29 -0
  93. package/engine/REFACTORING_MANIFEST_SYSTEM.md +974 -0
  94. package/engine/Tiltfile +80 -0
  95. package/engine/assets/docker/golden-layers.Dockerfile +221 -0
  96. package/engine/assets/scripts/cleanup-completed-migrator-images.sh +37 -0
  97. package/engine/assets/scripts/cleanup-tilt-images.sh +120 -0
  98. package/engine/assets/scripts/mac-m1-resource-monitor.sh +121 -0
  99. package/engine/config.star +3 -0
  100. package/engine/docs/AUTODISCOVERY_TEST.md +182 -0
  101. package/engine/docs/C4-ARCHITECTURE-operations.md +396 -0
  102. package/engine/docs/C4-ARCHITECTURE-overview.md +284 -0
  103. package/engine/docs/C4-ARCHITECTURE.md +17 -0
  104. package/engine/docs/GOLDEN_IMAGE_INTEGRATION.md +349 -0
  105. package/engine/docs/MANIFEST_DRIVEN_ARCHITECTURE.md +357 -0
  106. package/engine/docs/README.md +284 -0
  107. package/engine/entrypoint.star +97 -0
  108. package/engine/lifecycle/orchestrator.star +260 -0
  109. package/engine/paths.star +717 -0
  110. package/engine/schemas/manifest-schema.json +301 -0
  111. package/engine/schemas/service-schema.json +301 -0
  112. package/engine/scripts/README.md +89 -0
  113. package/engine/scripts/build-and-publish-lib.sh +205 -0
  114. package/engine/scripts/check-lib-publish.sh +85 -0
  115. package/engine/scripts/debug-container.sh +258 -0
  116. package/engine/scripts/generate-manifest.sh +197 -0
  117. package/engine/spec.master +702 -0
  118. package/engine/spec.master.example +341 -0
  119. package/engine/topologies/README.md +34 -0
  120. package/engine/topologies/platform/docker/AGENTS.md +59 -0
  121. package/engine/topologies/platform/docker/auth/auth.star +167 -0
  122. package/engine/topologies/platform/docker/build/golden_image.star +37 -0
  123. package/engine/topologies/platform/docker/build/golden_image_build.star +82 -0
  124. package/engine/topologies/platform/docker/build/golden_image_constants.star +93 -0
  125. package/engine/topologies/platform/docker/build/golden_image_dockerfile.star +291 -0
  126. package/engine/topologies/platform/docker/compose/compose.star +636 -0
  127. package/engine/topologies/platform/docker/compose/compose_helpers.star +52 -0
  128. package/engine/topologies/platform/docker/compose/traefik_standalone.star +53 -0
  129. package/engine/topologies/platform/docker/config/bunignore.star +142 -0
  130. package/engine/topologies/platform/docker/config/dockerignore.star +150 -0
  131. package/engine/topologies/platform/docker/constants.star +170 -0
  132. package/engine/topologies/platform/docker/dockerfile/dockerfile.star +54 -0
  133. package/engine/topologies/platform/docker/generators/golden_docker_generator_v2.star +73 -0
  134. package/engine/topologies/platform/docker/index.star +27 -0
  135. package/engine/topologies/platform/docker/layers/bun_helpers.star +23 -0
  136. package/engine/topologies/platform/docker/layers/infisical/index.star +40 -0
  137. package/engine/topologies/platform/docker/layers/infisical/infisical_docker.star +262 -0
  138. package/engine/topologies/platform/docker/layers/l1_base_layers.star +87 -0
  139. package/engine/topologies/platform/docker/layers/l2_dependency_layers.star +125 -0
  140. package/engine/topologies/platform/docker/layers/l3_builder_layers.star +209 -0
  141. package/engine/topologies/platform/docker/layers/l4_runtime_layers.star +214 -0
  142. package/engine/topologies/platform/docker/layers/prisma/constants.star +135 -0
  143. package/engine/topologies/platform/docker/layers/prisma/db_readiness.star +96 -0
  144. package/engine/topologies/platform/docker/layers/prisma/filesystem_setup.star +109 -0
  145. package/engine/topologies/platform/docker/layers/prisma/migrate_script.star +98 -0
  146. package/engine/topologies/platform/docker/layers/prisma/prisma_build.star +126 -0
  147. package/engine/topologies/platform/docker/layers/prisma/prisma_runtime.star +161 -0
  148. package/engine/topologies/platform/docker/layers/prisma/secret_resolution.star +119 -0
  149. package/engine/topologies/platform/docker/networking/api_path_constants.star +230 -0
  150. package/engine/topologies/platform/docker/networking/sablier_container_cycle.star +27 -0
  151. package/engine/topologies/platform/docker/networking/traefik.star +232 -0
  152. package/engine/topologies/platform/docker/networking/traefik_constants.star +146 -0
  153. package/engine/topologies/platform/docker/networking/traefik_helpers.star +160 -0
  154. package/engine/topologies/platform/docker/secrets/infisical.star +135 -0
  155. package/engine/topologies/platform/net/proxy.star +4 -0
  156. package/engine/topologies/platform/registries/local.star +4 -0
  157. package/engine/topologies/platform/security/secrets.star +239 -0
  158. package/engine/topologies/platform/state/relational.star +4 -0
  159. package/engine/topologies/tilt/common/AGENTS.md +59 -0
  160. package/engine/topologies/tilt/common/utils.star +364 -0
  161. package/engine/topologies/tilt/common/utils_debug.star +69 -0
  162. package/engine/topologies/tilt/common/utils_deterministic.star +168 -0
  163. package/engine/topologies/tilt/common/utils_docker_networks.star +46 -0
  164. package/engine/topologies/tilt/common/utils_env.star +43 -0
  165. package/engine/topologies/tilt/common/utils_output.star +97 -0
  166. package/engine/topologies/tilt/config/AGENTS.md +68 -0
  167. package/engine/topologies/tilt/config/defaults.star +3 -0
  168. package/engine/topologies/tilt/config/feature_flags.star +10 -0
  169. package/engine/topologies/tilt/config/global.star +55 -0
  170. package/engine/topologies/tilt/config/profiles.star +382 -0
  171. package/engine/topologies/tilt/generators/agents_md.star +62 -0
  172. package/engine/topologies/tilt/generators/api_gateway.star +145 -0
  173. package/engine/topologies/tilt/generators/index.star +124 -0
  174. package/engine/topologies/tilt/generators/infisical/README.md +424 -0
  175. package/engine/topologies/tilt/generators/infisical/examples.star +312 -0
  176. package/engine/topologies/tilt/generators/infisical/index.star +57 -0
  177. package/engine/topologies/tilt/generators/infisical/machine_identity.star +420 -0
  178. package/engine/topologies/tilt/generators/infisical/organization.star +534 -0
  179. package/engine/topologies/tilt/generators/infisical/path_manager.star +476 -0
  180. package/engine/topologies/tilt/generators/infisical/secrets_generator.star +420 -0
  181. package/engine/topologies/tilt/generators/nginx_conf.star +143 -0
  182. package/engine/topologies/tilt/generators/npmrc.star +111 -0
  183. package/engine/topologies/tilt/generators/tsconfig.star +23 -0
  184. package/engine/topologies/tilt/generators/typescript/backend_library_tsconfig.star +71 -0
  185. package/engine/topologies/tilt/generators/typescript/backend_tsconfig.star +124 -0
  186. package/engine/topologies/tilt/generators/typescript/common.star +7 -0
  187. package/engine/topologies/tilt/generators/typescript/frontend_library_tsconfig.star +76 -0
  188. package/engine/topologies/tilt/generators/typescript/frontend_tsconfig.star +110 -0
  189. package/engine/topologies/tilt/generators/typescript/include.star +23 -0
  190. package/engine/topologies/tilt/generators/typescript/playwright_config.star +40 -0
  191. package/engine/topologies/tilt/generators/typescript/prisma_config.star +49 -0
  192. package/engine/topologies/tilt/generators/validators.star +853 -0
  193. package/engine/topologies/tilt/generators/vite/backend.star +78 -0
  194. package/engine/topologies/tilt/generators/vite/frontend.star +98 -0
  195. package/engine/topologies/tilt/generators/vite/generators.star +43 -0
  196. package/engine/topologies/tilt/generators/vite/helpers.star +244 -0
  197. package/engine/topologies/tilt/generators/vite/library.star +65 -0
  198. package/engine/topologies/tilt/generators/vite/sdk.star +73 -0
  199. package/engine/topologies/tilt/generators/vite/templates.star +737 -0
  200. package/engine/topologies/tilt/generators/vite_config.star +22 -0
  201. package/engine/topologies/tilt/manifest/AGENTS.md +61 -0
  202. package/engine/topologies/tilt/manifest/README.md +693 -0
  203. package/engine/topologies/tilt/manifest/__init__.star +218 -0
  204. package/engine/topologies/tilt/manifest/constants.star +252 -0
  205. package/engine/topologies/tilt/manifest/errors.star +266 -0
  206. package/engine/topologies/tilt/manifest/integration.star +339 -0
  207. package/engine/topologies/tilt/manifest/json_to_yaml.py +54 -0
  208. package/engine/topologies/tilt/manifest/loader.star +214 -0
  209. package/engine/topologies/tilt/manifest/mapper.star +227 -0
  210. package/engine/topologies/tilt/manifest/parser.star +400 -0
  211. package/engine/topologies/tilt/manifest/schema.star +462 -0
  212. package/engine/topologies/tilt/manifest/tests/test_integration.star +276 -0
  213. package/engine/topologies/tilt/manifest/tests/test_loader_parser.star +397 -0
  214. package/engine/topologies/tilt/manifest/tests/test_manifest.star +316 -0
  215. package/engine/topologies/tilt/manifest/tests/test_validator.star +470 -0
  216. package/engine/topologies/tilt/manifest/validator.star +717 -0
  217. package/engine/topologies/tilt/manifest/yaml_to_json.py +18 -0
  218. package/engine/topologies/tilt/resources/AGENTS.md +71 -0
  219. package/engine/topologies/tilt/resources/conditions.star +3 -0
  220. package/engine/topologies/tilt/resources/databases.star +244 -0
  221. package/engine/topologies/tilt/resources/declaration.star +3 -0
  222. package/engine/topologies/tilt/resources/deps.star +3 -0
  223. package/engine/topologies/tilt/resources/infra-loader.star +437 -0
  224. package/engine/topologies/tilt/resources/libs.star +30 -0
  225. package/engine/topologies/tilt/resources/libs_discovery.star +102 -0
  226. package/engine/topologies/tilt/resources/libs_paths.star +79 -0
  227. package/engine/topologies/tilt/resources/libs_resource_definition.star +151 -0
  228. package/engine/topologies/tilt/resources/libs_setup.star +164 -0
  229. package/engine/topologies/tilt/resources/libs_tsconfig.star +37 -0
  230. package/engine/topologies/tilt/resources/orchestrator/apply.star +77 -0
  231. package/engine/topologies/tilt/resources/orchestrator/apply_compose_resource_registration.star +431 -0
  232. package/engine/topologies/tilt/resources/orchestrator/apply_manifest_orchestration.star +81 -0
  233. package/engine/topologies/tilt/resources/orchestrator/apply_migrator_orchestration.star +148 -0
  234. package/engine/topologies/tilt/resources/orchestrator/apply_resource_validation.star +36 -0
  235. package/engine/topologies/tilt/resources/orchestrator/apply_runtime_flags.star +44 -0
  236. package/engine/topologies/tilt/resources/orchestrator/builders/typescript.star +164 -0
  237. package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/AGENTS.md +75 -0
  238. package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/index.star +21 -0
  239. package/engine/topologies/tilt/resources/orchestrator/generators/dependencies/resolver.star +134 -0
  240. package/engine/topologies/tilt/resources/orchestrator/generators/env.star +258 -0
  241. package/engine/topologies/tilt/resources/orchestrator/generators/frontend.star +169 -0
  242. package/engine/topologies/tilt/resources/orchestrator/generators/manifest_resource.star +524 -0
  243. package/engine/topologies/tilt/resources/orchestrator/helpers.star +33 -0
  244. package/engine/topologies/tilt/resources/orchestrator.star +54 -0
  245. package/engine/topologies/tilt/resources/ordering.star +3 -0
  246. package/engine/topologies/tilt/resources/triggers.star +3 -0
  247. package/engine/topologies/tilt/resources/watchers.star +299 -0
  248. package/engine/where-things-live.star +717 -0
  249. package/ext/Tiltfile +66 -0
  250. package/ext/ide-components/README.md +219 -0
  251. package/ext/ide-components/code_executor/server.py +268 -0
  252. package/ext/ide-components/code_viewer/server.py +206 -0
  253. package/ext/ide-components/config_inspector/server.py +1050 -0
  254. package/ext/ide-components/file_browser/server.py +285 -0
  255. package/ext/ide-components/shared/config_service.py +469 -0
  256. package/ext/ide-components/shared/file_utils.py +298 -0
  257. package/ext/ide-components/shared/http_utils.py +232 -0
  258. package/ext/ide-components/shared/static/styles.css +1334 -0
  259. package/ext/ide-components/shared/syntax_highlighter.py +140 -0
  260. package/ext/ide-components/shared/template_engine.py +123 -0
  261. package/ext/ide-components/shared/templates/base.html +121 -0
  262. package/ext/ide-components/shared/test_config_service.py +326 -0
  263. package/ext/ide-components/shared/tilt_integration.py +158 -0
  264. package/ext/ui-enhancements/cron-status-server.sh +49 -0
  265. package/ext/ui-enhancements/cron-status-tracker.sh +146 -0
  266. package/ext/ui-enhancements/extension.yaml +36 -0
  267. package/ext/ui-enhancements/tiltfile.py +99 -0
  268. package/ext/ui-enhancements/ui/cron-jobs-tab.css +396 -0
  269. package/ext/ui-enhancements/ui/help-panel.css +279 -0
  270. package/ext/ui-enhancements/ui/icons.css +125 -0
  271. package/ext/ui-enhancements/ui/tooltips.css +114 -0
  272. package/package.json +13 -9
  273. package/specs/specs/TILT_SERVICE_DEFAULTS.star +205 -0
  274. package/specs/specs/TILT_TECH_STACK.star +159 -0
@@ -0,0 +1,974 @@
1
+ # 📋 Manifest System Refactoring Plan
2
+
3
+ ## Executive Summary
4
+
5
+ This document outlines a comprehensive refactoring of the manifest parsing and validation system in the TDK Landscape Tilt infrastructure. The goal is to move from scattered inline logic to a clean, modular, well-tested architecture.
6
+
7
+ **Current State:**
8
+ - Manifest parsing scattered across `discovery.star`, `registry.star`, and multiple generator files
9
+ - Validation logic inline and duplicated
10
+ - No clear separation between loading, parsing, and validation
11
+ - Schema definitions mixed with business logic
12
+
13
+ **Target State:**
14
+ - Dedicated `manifest/` module with clear separation of concerns
15
+ - Parser, validator, loader, schema, and fetch as separate modules
16
+ - Comprehensive attribute and value verification
17
+ - Backward compatibility maintained during migration
18
+
19
+ ---
20
+
21
+ ## New Architecture
22
+
23
+ ### Folder Structure
24
+
25
+ ```
26
+ .tilt/topologies/tilt/
27
+ ├── manifest/ # NEW: Manifest system module
28
+ │ ├── __init__.star # Module exports and facade
29
+ │ ├── loader.star # File loading and I/O
30
+ │ ├── parser.star # JSON parsing and normalization
31
+ │ ├── validator.star # Schema and value validation
32
+ │ ├── schema.star # Schema definitions and constraints
33
+ │ ├── fetch.star # Remote manifest fetching (future)
34
+ │ ├── constants.star # Manifest-specific constants
35
+ │ ├── errors.star # Error types and handling
36
+ │ └── tests/ # Unit tests for manifest system
37
+ │ ├── test_loader.star
38
+ │ ├── test_parser.star
39
+ │ ├── test_validator.star
40
+ │ └── test_schema.star
41
+
42
+ ├── discovery/ # EXISTING: Service discovery
43
+ │ ├── manifest/ # DEPRECATED: Will be moved to ../manifest/
44
+ │ │ └── constants.star # Will migrate to ../manifest/constants.star
45
+ │ ├── discovery.star # Will use new manifest module
46
+ │ └── registry.star # Will use new manifest module
47
+
48
+ └── generators/ # EXISTING: Config generators
49
+ └── validators.star # Will use new manifest/validator.star
50
+ ```
51
+
52
+ ---
53
+
54
+ ## Module Specifications
55
+
56
+ ### 1. `manifest/__init__.star` - Module Facade
57
+
58
+ **Purpose:** Provide a clean API surface for other modules
59
+
60
+ **Exports:**
61
+ ```starlark
62
+ # Main API
63
+ Manifest = struct(
64
+ # Loader functions
65
+ load_from_file = loader.load_from_file,
66
+ load_from_path = loader.load_from_path,
67
+ load_all = loader.load_all,
68
+
69
+ # Parser functions
70
+ parse = parser.parse,
71
+ normalize = parser.normalize,
72
+ extract_resource_path = parser.extract_resource_path,
73
+
74
+ # Validator functions
75
+ validate = validator.validate,
76
+ validate_schema = validator.validate_schema,
77
+ validate_values = validator.validate_values,
78
+ validate_dependencies = validator.validate_dependencies,
79
+
80
+ # Schema access
81
+ schema = schema.MANIFEST_SCHEMA,
82
+ defaults = constants.MANIFEST_DEFAULTS,
83
+ constraints = schema.CONSTRAINTS,
84
+
85
+ # Error handling
86
+ errors = errors.MANIFEST_ERRORS,
87
+ is_valid = validator.is_valid,
88
+ get_validation_report = validator.get_validation_report,
89
+ )
90
+ ```
91
+
92
+ **Usage Example:**
93
+ ```starlark
94
+ load("../manifest/__init__.star", "Manifest")
95
+
96
+ # Load and validate in one call
97
+ result = Manifest.load_from_file("services/product/user/user-management-backend/service.json")
98
+ if result.error:
99
+ print("Failed to load manifest:", result.error)
100
+ else:
101
+ manifest = result.manifest
102
+ # Use validated manifest
103
+ ```
104
+
105
+ ---
106
+
107
+ ### 2. `manifest/loader.star` - File Loading and I/O
108
+
109
+ **Purpose:** Handle all file system operations for manifest loading
110
+
111
+ **Functions:**
112
+
113
+ ```starlark
114
+ def load_from_file(path):
115
+ """
116
+ Load a single manifest from file path.
117
+
118
+ Args:
119
+ path: Absolute or relative path to manifest JSON file
120
+
121
+ Returns:
122
+ struct(manifest=None, error=None, metadata={})
123
+ - manifest: Parsed manifest dict or None if error
124
+ - error: Error message string or None
125
+ - metadata: Dict with load info (timestamp, file_size, path)
126
+ """
127
+
128
+ def load_from_path(resource_path):
129
+ """
130
+ Load manifest from resource directory (auto-detects manifest file).
131
+
132
+ Args:
133
+ resource_path: Path to resource directory
134
+
135
+ Returns:
136
+ Same as load_from_file
137
+ """
138
+
139
+ def load_all(resources_root, filters=None):
140
+ """
141
+ Load all manifests from resources directory with optional filtering.
142
+
143
+ Args:
144
+ resources_root: Root directory to search (e.g., "services/product")
145
+ filters: Optional dict of filters:
146
+ - appType: ['frontend', 'backend', 'library', ...]
147
+ - stack: ['user', 'order', ...]
148
+ - features: ['nats', 'prisma', ...]
149
+
150
+ Returns:
151
+ struct(
152
+ manifests=[], # List of loaded manifests
153
+ errors=[], # List of (path, error) tuples
154
+ stats={ # Loading statistics
155
+ 'total_found': N,
156
+ 'successful': N,
157
+ 'failed': N,
158
+ 'filtered_out': N,
159
+ }
160
+ )
161
+ """
162
+
163
+ def watch_manifest(path):
164
+ """
165
+ Set up file watch for manifest changes (Tilt integration).
166
+
167
+ Args:
168
+ path: Path to manifest file
169
+
170
+ Returns:
171
+ watch_spec for Tilt
172
+ """
173
+
174
+ def get_manifest_path(resource_path):
175
+ """
176
+ Get the expected manifest file path for a resource directory.
177
+
178
+ Args:
179
+ resource_path: Resource directory path
180
+
181
+ Returns:
182
+ Expected manifest file path or None
183
+ """
184
+ ```
185
+
186
+ **Implementation Notes:**
187
+ - Uses `read_file()` with proper error handling
188
+ - Caches loaded manifests to avoid redundant I/O
189
+ - Provides detailed error messages with context
190
+ - Integrates with Tilt's file watching system
191
+
192
+ ---
193
+
194
+ ### 3. `manifest/parser.star` - JSON Parsing and Normalization
195
+
196
+ **Purpose:** Transform raw JSON into normalized, validated manifest structures
197
+
198
+ **Functions:**
199
+
200
+ ```starlark
201
+ def parse(content, path=""):
202
+ """
203
+ Parse JSON content into manifest dict.
204
+
205
+ Args:
206
+ content: Raw JSON string
207
+ path: Optional path for error context
208
+
209
+ Returns:
210
+ struct(manifest=None, error=None, warnings=[])
211
+ """
212
+
213
+ def normalize(manifest, resource_path=""):
214
+ """
215
+ Normalize manifest with default values and computed fields.
216
+
217
+ Args:
218
+ manifest: Raw parsed manifest dict
219
+ resource_path: Resource directory path for context
220
+
221
+ Returns:
222
+ Normalized manifest dict with all fields populated
223
+
224
+ Normalization Steps:
225
+ 1. Apply defaults for missing fields
226
+ 2. Compute derived fields (appType from path if missing)
227
+ 3. Validate field types and formats
228
+ 4. Set up internal dependencies
229
+ 5. Compute sync paths based on features
230
+ 6. Normalize environment variables
231
+ 7. Set up Traefik configuration defaults
232
+ """
233
+
234
+ def extract_resource_path(manifest_path):
235
+ """
236
+ Extract resource directory path from manifest file path.
237
+
238
+ Args:
239
+ manifest_path: Path to manifest JSON file
240
+
241
+ Returns:
242
+ Resource directory path
243
+ """
244
+
245
+ def extract_stack(resource_path):
246
+ """
247
+ Extract stack from resource path.
248
+
249
+ Args:
250
+ resource_path: Resource directory path
251
+
252
+ Returns:
253
+ Stack string (e.g., 'user', 'order')
254
+ """
255
+
256
+ def determine_app_type(manifest, resource_path):
257
+ """
258
+ Determine app type from manifest or resource path.
259
+
260
+ Args:
261
+ manifest: Manifest dict
262
+ resource_path: Resource directory path
263
+
264
+ Returns:
265
+ App type string ('frontend', 'backend', 'library', etc.)
266
+ """
267
+
268
+ def compute_syncs(app_type, features):
269
+ """
270
+ Compute default sync paths based on app type and features.
271
+
272
+ Args:
273
+ app_type: App type string
274
+ features: List of feature strings
275
+
276
+ Returns:
277
+ List of sync paths
278
+ """
279
+
280
+ def parse_traefik_config(manifest):
281
+ """
282
+ Parse and normalize Traefik configuration.
283
+
284
+ Args:
285
+ manifest: Manifest dict
286
+
287
+ Returns:
288
+ Normalized Traefik config dict
289
+ """
290
+
291
+ def merge_manifests(base, overlay):
292
+ """
293
+ Merge two manifest dicts (for inheritance patterns).
294
+
295
+ Args:
296
+ base: Base manifest dict
297
+ overlay: Overlay manifest dict
298
+
299
+ Returns:
300
+ Merged manifest dict
301
+ """
302
+ ```
303
+
304
+ **Implementation Notes:**
305
+ - Pure functions with no side effects
306
+ - Comprehensive warning system for deprecated fields
307
+ - Supports manifest inheritance/overlays
308
+ - Detailed error context with path information
309
+
310
+ ---
311
+
312
+ ### 4. `manifest/schema.star` - Schema Definitions and Constraints
313
+
314
+ **Purpose:** Define the complete manifest schema with types, constraints, and documentation
315
+
316
+ **Schema Definition:**
317
+
318
+ ```starlark
319
+ # Complete manifest field schema
320
+ MANIFEST_SCHEMA = {
321
+ 'appName': {
322
+ 'type': 'string',
323
+ 'required': True,
324
+ 'pattern': r'^[a-z][a-z0-9-]*$',
325
+ 'min_length': 3,
326
+ 'max_length': 50,
327
+ 'description': 'Unique resource name (kebab-case)',
328
+ 'example': 'user-management-backend',
329
+ },
330
+ 'appType': {
331
+ 'type': 'string',
332
+ 'required': True,
333
+ 'enum': ['frontend', 'backend', 'library', 'migrator', 'sdk', 'worker'],
334
+ 'description': 'Type of application',
335
+ 'default': 'backend',
336
+ },
337
+ 'stack': {
338
+ 'type': 'string',
339
+ 'required': True,
340
+ 'enum': ['user', 'staff', 'identity', 'order', 'treatment',
341
+ 'platform', 'inventory', 'billing', 'notification', 'analytics'],
342
+ 'description': 'Technology stack this resource belongs to',
343
+ },
344
+ 'port': {
345
+ 'type': 'integer',
346
+ 'required': True,
347
+ 'min': 1024,
348
+ 'max': 65535,
349
+ 'description': 'External resource port',
350
+ 'constraints': 'Must be unique per resource',
351
+ },
352
+ 'internalPort': {
353
+ 'type': 'integer',
354
+ 'required': False,
355
+ 'default': 3000,
356
+ 'description': 'Internal container port (usually 3000)',
357
+ 'constant': True, # Should rarely change
358
+ },
359
+ 'replicas': {
360
+ 'type': 'integer',
361
+ 'required': False,
362
+ 'default': 1,
363
+ 'min': 1,
364
+ 'max': 5, # Reasonable limit
365
+ 'description': 'Number of container replicas',
366
+ },
367
+ 'runtime': {
368
+ 'type': 'string',
369
+ 'required': False,
370
+ 'default': 'bun',
371
+ 'enum': ['bun', 'node', 'python', 'go'],
372
+ 'description': 'Runtime environment',
373
+ },
374
+ 'features': {
375
+ 'type': 'list',
376
+ 'required': False,
377
+ 'default': [],
378
+ 'items': {
379
+ 'type': 'string',
380
+ 'enum': ['nats', 'prisma', 'redis', 'infisical', 'vitest',
381
+ 'traefik', 'websocket', 'graphql', 'grpc', 'vite-node'],
382
+ },
383
+ 'description': 'Feature flags for this resource',
384
+ },
385
+ 'databaseName': {
386
+ 'type': 'string',
387
+ 'required': False,
388
+ 'pattern': r'^[a-z][a-z0-9_]*$',
389
+ 'description': 'PostgreSQL database name',
390
+ },
391
+ 'dependsOn': {
392
+ 'type': 'list',
393
+ 'required': False,
394
+ 'default': [],
395
+ 'items': {'type': 'string'},
396
+ 'description': 'Other resources this depends on',
397
+ },
398
+ 'envVars': {
399
+ 'type': 'dict',
400
+ 'required': False,
401
+ 'default': {},
402
+ 'description': 'Environment variables',
403
+ },
404
+ 'traefik': {
405
+ 'type': 'dict',
406
+ 'required': False,
407
+ 'schema': {
408
+ 'pathPrefix': {'type': 'string', 'required': True},
409
+ 'host': {'type': 'string', 'required': False},
410
+ 'priority': {'type': 'integer', 'required': False, 'min': 1, 'max': 1000},
411
+ },
412
+ },
413
+ # Frontend-specific fields
414
+ 'backendName': {
415
+ 'type': 'string',
416
+ 'required': False,
417
+ 'condition': "appType == 'frontend'", # Required for frontends
418
+ 'description': 'Associated backend resource name',
419
+ },
420
+ 'basePath': {
421
+ 'type': 'string',
422
+ 'required': False,
423
+ 'condition': "appType == 'frontend'",
424
+ 'pattern': r'^/[a-z][a-z0-9-]*$',
425
+ 'description': 'URL base path for frontend',
426
+ },
427
+ # Advanced fields
428
+ 'syncs': {
429
+ 'type': 'list',
430
+ 'required': False,
431
+ 'description': 'Custom sync paths (auto-computed if not provided)',
432
+ },
433
+ 'startCommand': {
434
+ 'type': 'string',
435
+ 'required': False,
436
+ 'description': 'Custom container start command',
437
+ },
438
+ 'targetPath': {
439
+ 'type': 'string',
440
+ 'required': False,
441
+ 'description': 'Frontend build target path',
442
+ },
443
+ }
444
+
445
+ # Cross-field constraints
446
+ CONSTRAINTS = {
447
+ # Port uniqueness will be validated across all manifests
448
+ 'port_unique': True,
449
+
450
+ # App type specific rules
451
+ 'frontend_requires_backend': {
452
+ 'condition': "appType == 'frontend'",
453
+ 'requires': ['backendName', 'basePath'],
454
+ },
455
+
456
+ # Feature dependencies
457
+ 'prisma_requires_database': {
458
+ 'condition': "'prisma' in features",
459
+ 'requires': ['databaseName'],
460
+ },
461
+
462
+ # Port ranges by app type
463
+ 'port_ranges': {
464
+ 'frontend': {'min': 3000, 'max': 3999},
465
+ 'backend': {'min': 4000, 'max': 5999},
466
+ 'worker': {'min': 6000, 'max': 6999},
467
+ },
468
+ }
469
+ ```
470
+
471
+ **Functions:**
472
+
473
+ ```starlark
474
+ def get_field_schema(field_name):
475
+ """Get schema definition for a specific field."""
476
+
477
+ def validate_field_type(field_name, value):
478
+ """Validate a single field's type against schema."""
479
+
480
+ def get_default_value(field_name):
481
+ """Get default value for a field."""
482
+
483
+ def get_required_fields(manifest):
484
+ """Get list of required fields based on manifest context."""
485
+
486
+ def get_field_constraints(field_name):
487
+ """Get constraints for a specific field."""
488
+ ```
489
+
490
+ ---
491
+
492
+ ### 5. `manifest/validator.star` - Comprehensive Validation
493
+
494
+ **Purpose:** Validate manifest structure, values, and cross-resource dependencies
495
+
496
+ **Validation Levels:**
497
+
498
+ ```starlark
499
+ def validate(manifest, context=None, level='all'):
500
+ """
501
+ Comprehensive manifest validation.
502
+
503
+ Args:
504
+ manifest: Manifest dict to validate
505
+ context: Optional context dict:
506
+ - all_manifests: List of all manifests for cross-validation
507
+ - resource_path: Path for error context
508
+ - strict: Boolean for strict mode
509
+ level: Validation level
510
+ - 'schema': Structure and types only
511
+ - 'values': Value constraints
512
+ - 'dependencies': Cross-resource dependencies
513
+ - 'all': All validations (default)
514
+
515
+ Returns:
516
+ struct(
517
+ valid=True/False,
518
+ errors=[], # Critical errors
519
+ warnings=[], # Non-critical issues
520
+ stats={ # Validation statistics
521
+ 'fields_checked': N,
522
+ 'rules_passed': N,
523
+ 'rules_failed': N,
524
+ }
525
+ )
526
+ """
527
+
528
+ def validate_schema(manifest):
529
+ """
530
+ Level 1: Schema Validation
531
+ - Check all required fields present
532
+ - Validate field types
533
+ - Check field formats (regex patterns)
534
+ - Validate enum values
535
+ """
536
+
537
+ def validate_values(manifest):
538
+ """
539
+ Level 2: Value Validation
540
+ - Port range validation
541
+ - Name format validation
542
+ - String length constraints
543
+ - Numeric range constraints
544
+ - Pattern matching
545
+ """
546
+
547
+ def validate_cross_field(manifest):
548
+ """
549
+ Level 3: Cross-Field Validation
550
+ - Frontend requires backend
551
+ - Prisma requires database
552
+ - Port conflicts with app type
553
+ - Dependencies valid
554
+ """
555
+
556
+ def validate_dependencies(manifest, all_manifests):
557
+ """
558
+ Level 4: Cross-Resource Validation
559
+ - dependsOn exist as resources
560
+ - No circular dependencies
561
+ - Backend references are valid
562
+ - Port uniqueness across resources
563
+ """
564
+
565
+ def validate_ports_unique(manifests):
566
+ """
567
+ Check for port conflicts across all manifests.
568
+
569
+ Returns:
570
+ List of port conflict errors
571
+ """
572
+
573
+ def validate_naming_consistency(manifests):
574
+ """
575
+ Check naming conventions across all resources.
576
+
577
+ Validates:
578
+ - Resource names follow convention: {stack}-{function}-{type}
579
+ - No duplicate names
580
+ - Consistent kebab-case
581
+ """
582
+
583
+ def is_valid(manifest):
584
+ """Quick check if manifest is valid (returns boolean)."""
585
+
586
+ def get_validation_report(manifest, context=None):
587
+ """
588
+ Generate detailed validation report.
589
+
590
+ Returns:
591
+ Human-readable report with all issues and suggestions
592
+ """
593
+ ```
594
+
595
+ **Validation Rules:**
596
+
597
+ ```starlark
598
+ VALIDATION_RULES = {
599
+ # Schema rules
600
+ 'required_fields': {
601
+ 'severity': 'error',
602
+ 'check': lambda m: all(m.get(f) for f in get_required_fields(m)),
603
+ 'message': 'Missing required field: {field}',
604
+ },
605
+
606
+ 'field_types': {
607
+ 'severity': 'error',
608
+ 'check': _check_field_types,
609
+ 'message': 'Field {field} has invalid type: {actual}, expected: {expected}',
610
+ },
611
+
612
+ # Value rules
613
+ 'port_range': {
614
+ 'severity': 'error',
615
+ 'check': lambda m: _check_port_in_range(m),
616
+ 'message': 'Port {port} is outside valid range for {appType}: {min}-{max}',
617
+ },
618
+
619
+ 'name_format': {
620
+ 'severity': 'error',
621
+ 'check': lambda m: re.match(r'^[a-z][a-z0-9-]*$', m.get('appName', '')),
622
+ 'message': 'Invalid appName format: {name}',
623
+ },
624
+
625
+ # Cross-field rules
626
+ 'frontend_has_backend': {
627
+ 'severity': 'error',
628
+ 'condition': lambda m: m.get('appType') == 'frontend',
629
+ 'check': lambda m: m.get('backendName'),
630
+ 'message': 'Frontend {name} must specify backendName',
631
+ },
632
+
633
+ 'prisma_has_database': {
634
+ 'severity': 'warning',
635
+ 'condition': lambda m: 'prisma' in m.get('features', []),
636
+ 'check': lambda m: m.get('databaseName'),
637
+ 'message': 'Service with prisma feature should specify databaseName',
638
+ },
639
+
640
+ # Cross-resource rules
641
+ 'dependencies_exist': {
642
+ 'severity': 'error',
643
+ 'check': lambda m, ctx: _check_deps_exist(m, ctx.get('all_manifests', [])),
644
+ 'message': 'Dependency {dep} does not exist as a resource',
645
+ },
646
+
647
+ 'no_circular_deps': {
648
+ 'severity': 'error',
649
+ 'check': _check_no_circular_deps,
650
+ 'message': 'Circular dependency detected: {path}',
651
+ },
652
+ }
653
+ ```
654
+
655
+ ---
656
+
657
+ ### 6. `manifest/fetch.star` - Remote Manifest Fetching (Future)
658
+
659
+ **Purpose:** Fetch manifests from remote sources (for distributed teams or external resources)
660
+
661
+ ```starlark
662
+ def fetch_from_git(repo_url, branch="main", path=""):
663
+ """
664
+ Fetch manifest from git repository.
665
+
666
+ Future use case: External resource definitions
667
+ """
668
+
669
+ def fetch_from_http(url):
670
+ """
671
+ Fetch manifest from HTTP endpoint.
672
+
673
+ Future use case: Resource registry API
674
+ """
675
+
676
+ def fetch_from_registry(resource_name, registry_url):
677
+ """
678
+ Fetch manifest from resource registry.
679
+
680
+ Future use case: Centralized resource catalog
681
+ """
682
+ ```
683
+
684
+ **Note:** This module is for future use. Initial refactoring focuses on local manifests.
685
+
686
+ ---
687
+
688
+ ### 7. `manifest/errors.star` - Error Types and Handling
689
+
690
+ **Purpose:** Standardized error handling with context
691
+
692
+ ```starlark
693
+ # Error severity levels
694
+ SEVERITY = {
695
+ 'CRITICAL': 'critical', # Must fix, system won't function
696
+ 'ERROR': 'error', # Should fix, may cause issues
697
+ 'WARNING': 'warning', # Should consider, non-blocking
698
+ 'INFO': 'info', # Informational only
699
+ }
700
+
701
+ # Error categories
702
+ CATEGORY = {
703
+ 'SCHEMA': 'schema',
704
+ 'VALIDATION': 'validation',
705
+ 'IO': 'io',
706
+ 'PARSE': 'parse',
707
+ 'DEPENDENCY': 'dependency',
708
+ }
709
+
710
+ def new_error(message, category, severity, context=None):
711
+ """
712
+ Create standardized error struct.
713
+
714
+ Args:
715
+ message: Human-readable error message
716
+ category: Error category
717
+ severity: Error severity
718
+ context: Optional dict with:
719
+ - field: Field name if field-specific
720
+ - path: File path
721
+ - value: Invalid value
722
+ - suggestion: Suggested fix
723
+
724
+ Returns:
725
+ Error struct
726
+ """
727
+
728
+ def format_error(error):
729
+ """Format error for display."""
730
+
731
+ def group_errors(errors):
732
+ """Group errors by category and severity."""
733
+
734
+ def has_critical_errors(errors):
735
+ """Check if any critical errors exist."""
736
+ ```
737
+
738
+ ---
739
+
740
+ ## Migration Strategy
741
+
742
+ ### Phase 1: Foundation (Week 1-2)
743
+
744
+ **Goals:**
745
+ - Create new `manifest/` module structure
746
+ - Implement `constants.star`, `errors.star`, `schema.star`
747
+ - Write comprehensive tests
748
+
749
+ **Tasks:**
750
+ 1. Create directory structure
751
+ 2. Migrate `discovery/manifest/constants.star` → `manifest/constants.star`
752
+ 3. Implement `schema.star` with complete field definitions
753
+ 4. Implement `errors.star` with error handling
754
+ 5. Write unit tests for schema and errors
755
+
756
+ **Backward Compatibility:**
757
+ - Keep `discovery/manifest/constants.star` as re-export wrapper
758
+ - Mark old path as deprecated in comments
759
+
760
+ ### Phase 2: Core Implementation (Week 3-4)
761
+
762
+ **Goals:**
763
+ - Implement `loader.star` and `parser.star`
764
+ - Migrate loading logic from `discovery.star`
765
+
766
+ **Tasks:**
767
+ 1. Implement `loader.star` with all loading functions
768
+ 2. Implement `parser.star` with normalization logic
769
+ 3. Extract parsing logic from `discovery.star`
770
+ 4. Create comprehensive parser tests
771
+ 5. Benchmark performance vs old implementation
772
+
773
+ **Backward Compatibility:**
774
+ - `discovery.star` re-exports from new module
775
+ - Gradual migration of consumers
776
+
777
+ ### Phase 3: Validation (Week 5-6)
778
+
779
+ **Goals:**
780
+ - Implement comprehensive `validator.star`
781
+ - Replace inline validation in generators
782
+
783
+ **Tasks:**
784
+ 1. Implement `validator.star` with all validation levels
785
+ 2. Migrate validation from `generators/validators.star`
786
+ 3. Add validation to manifest loading pipeline
787
+ 4. Create validation report generator
788
+ 5. Add CLI command to validate all manifests
789
+
790
+ **Backward Compatibility:**
791
+ - Old validators call new validator module
792
+ - Maintain same validation behavior
793
+
794
+ ### Phase 4: Integration (Week 7)
795
+
796
+ **Goals:**
797
+ - Wire up `__init__.star` facade
798
+ - Migrate all consumers
799
+ - Clean up old code
800
+
801
+ **Tasks:**
802
+ 1. Implement `__init__.star` with clean API
803
+ 2. Update `discovery.star` to use new module
804
+ 3. Update `registry.star` to use new module
805
+ 4. Update `generators/` to use new module
806
+ 5. Update `resources/orchestrator/` to use new module
807
+ 6. Remove deprecated re-export files
808
+ 7. Update all `load()` statements
809
+
810
+ ### Phase 5: Cleanup (Week 8)
811
+
812
+ **Goals:**
813
+ - Remove deprecated code
814
+ - Update documentation
815
+ - Final testing
816
+
817
+ **Tasks:**
818
+ 1. Remove old `discovery/manifest/` directory
819
+ 2. Remove deprecated re-export wrappers
820
+ 3. Update all documentation references
821
+ 4. Run full integration tests
822
+ 5. Update AGENTS.md with new structure
823
+
824
+ ---
825
+
826
+ ## Backward Compatibility Plan
827
+
828
+ ### During Migration (Phases 1-4)
829
+
830
+ **Re-Export Pattern:**
831
+ ```starlark
832
+ # In old file (e.g., discovery/manifest/constants.star)
833
+ # DEPRECATED: Use manifest/constants.star instead
834
+ load("../../manifest/constants.star",
835
+ MANIFEST_FILENAME="MANIFEST_FILENAME",
836
+ MANIFEST_DEFAULTS="MANIFEST_DEFAULTS",
837
+ # ... etc
838
+ )
839
+ ```
840
+
841
+ **Gradual Migration:**
842
+ - Each consumer updated individually
843
+ - PRs reviewed separately
844
+ - No breaking changes during migration
845
+
846
+ ### After Migration (Phase 5)
847
+
848
+ **Breaking Changes:**
849
+ - Old import paths removed
850
+ - Clear migration guide provided
851
+ - One-time update required
852
+
853
+ **Migration Guide:**
854
+ ```starlark
855
+ # OLD (deprecated)
856
+ load("../discovery/manifest/constants.star", "MANIFEST_DEFAULTS")
857
+ load("../discovery/discovery.star", "_load_manifest_json")
858
+
859
+ # NEW
860
+ load("../manifest/__init__.star", "Manifest")
861
+ # Use Manifest.defaults, Manifest.load_from_file, etc.
862
+ ```
863
+
864
+ ---
865
+
866
+ ## Testing Strategy
867
+
868
+ ### Unit Tests
869
+
870
+ Each module has comprehensive unit tests:
871
+
872
+ ```
873
+ manifest/tests/
874
+ ├── test_loader.star # Test all loading scenarios
875
+ ├── test_parser.star # Test parsing and normalization
876
+ ├── test_validator.star # Test all validation rules
877
+ ├── test_schema.star # Test schema definitions
878
+ └── test_integration.star # End-to-end integration tests
879
+ ```
880
+
881
+ **Test Coverage:**
882
+ - Happy path: Valid manifests load correctly
883
+ - Error cases: Invalid manifests produce clear errors
884
+ - Edge cases: Empty manifests, missing fields, etc.
885
+ - Performance: Loading 100+ manifests efficiently
886
+
887
+ ### Integration Tests
888
+
889
+ **Full Stack Test:**
890
+ ```starlark
891
+ def test_full_manifest_pipeline():
892
+ # Load all manifests
893
+ result = Manifest.load_all("services/product")
894
+
895
+ # Validate all
896
+ for manifest in result.manifests:
897
+ validation = Manifest.validate(manifest, level='all')
898
+ assert validation.valid, validation.errors
899
+
900
+ # Check cross-resource dependencies
901
+ deps_validation = Manifest.validate_dependencies(
902
+ result.manifests
903
+ )
904
+ assert deps_validation.valid
905
+ ```
906
+
907
+ ---
908
+
909
+ ## Benefits
910
+
911
+ ### 1. **Separation of Concerns**
912
+ - Loading, parsing, and validation are distinct
913
+ - Each module has single responsibility
914
+ - Easier to understand and maintain
915
+
916
+ ### 2. **Testability**
917
+ - Each module independently testable
918
+ - Clear inputs and outputs
919
+ - Mock-friendly interfaces
920
+
921
+ ### 3. **Extensibility**
922
+ - Easy to add new validation rules
923
+ - Easy to support new manifest formats
924
+ - Easy to add remote fetching
925
+
926
+ ### 4. **Developer Experience**
927
+ - Clear API via `__init__.star` facade
928
+ - Comprehensive error messages
929
+ - Validation reports with suggestions
930
+
931
+ ### 5. **Documentation**
932
+ - Schema serves as living documentation
933
+ - Each field has description and example
934
+ - Constraints are explicitly defined
935
+
936
+ ---
937
+
938
+ ## Risk Mitigation
939
+
940
+ | Risk | Mitigation |
941
+ |------|------------|
942
+ | Breaking changes | Gradual migration with re-exports |
943
+ | Performance regression | Benchmark tests before/after |
944
+ | Validation behavior changes | Comprehensive test suite |
945
+ | Increased complexity | Clear module boundaries, good docs |
946
+ | Migration takes too long | Phased approach, each phase deliverable |
947
+
948
+ ---
949
+
950
+ ## Success Metrics
951
+
952
+ - [ ] All 538 manifest references migrated
953
+ - [ ] 100% test coverage for new modules
954
+ - [ ] Zero breaking changes during migration
955
+ - [ ] Load time for 100 manifests < 1 second
956
+ - [ ] Validation catches 100% of invalid manifests
957
+ - [ ] All developers can understand new structure in < 10 minutes
958
+
959
+ ---
960
+
961
+ ## Next Steps
962
+
963
+ 1. **Review this plan** with stakeholders
964
+ 2. **Create Phase 1 PR** with module structure
965
+ 3. **Set up test framework** for manifest tests
966
+ 4. **Begin implementation** following migration phases
967
+ 5. **Track progress** with success metrics
968
+
969
+ ---
970
+
971
+ **Document Version:** 1.0
972
+ **Last Updated:** 2026-04-07
973
+ **Author:** super (with topology-engineer consultation)
974
+ **Reviewers:** Pending