icdev 1.0.0__py3-none-any.whl

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 (1105) hide show
  1. icdev/__init__.py +18 -0
  2. icdev/_paths.py +85 -0
  3. icdev/_version.py +3 -0
  4. icdev/data/__init__.py +1 -0
  5. icdev/data/args/__init__.py +1 -0
  6. icdev/data/args/agent_authority.yaml +61 -0
  7. icdev/data/args/agent_config.yaml +355 -0
  8. icdev/data/args/agentic_fitness.yaml +31 -0
  9. icdev/data/args/ai_governance_config.yaml +137 -0
  10. icdev/data/args/atlas_critique_config.yaml +66 -0
  11. icdev/data/args/bedrock_models.yaml +63 -0
  12. icdev/data/args/cicd_config.yaml +82 -0
  13. icdev/data/args/classification_config.yaml +232 -0
  14. icdev/data/args/cli_config.yaml +154 -0
  15. icdev/data/args/cloud_config.yaml +63 -0
  16. icdev/data/args/code_pattern_config.yaml +151 -0
  17. icdev/data/args/code_quality_config.yaml +47 -0
  18. icdev/data/args/companion_registry.yaml +202 -0
  19. icdev/data/args/context_config.yaml +82 -0
  20. icdev/data/args/csp_monitor_config.yaml +268 -0
  21. icdev/data/args/cui_markings.yaml +35 -0
  22. icdev/data/args/db_config.yaml +40 -0
  23. icdev/data/args/deployment_profiles.yaml +248 -0
  24. icdev/data/args/dev_profile_config.yaml +144 -0
  25. icdev/data/args/devsecops_config.yaml +286 -0
  26. icdev/data/args/endpoint_security_config.yaml +137 -0
  27. icdev/data/args/extension_config.yaml +79 -0
  28. icdev/data/args/file_access_tiers.yaml +88 -0
  29. icdev/data/args/framework_registry.yaml +415 -0
  30. icdev/data/args/innovation_config.yaml +431 -0
  31. icdev/data/args/installation_manifest.yaml +1087 -0
  32. icdev/data/args/llm_config.yaml +495 -0
  33. icdev/data/args/maintenance_config.yaml +55 -0
  34. icdev/data/args/memory_config.yaml +83 -0
  35. icdev/data/args/monitoring_config.yaml +127 -0
  36. icdev/data/args/mosa_config.yaml +190 -0
  37. icdev/data/args/nlq_config.yaml +35 -0
  38. icdev/data/args/observability_config.yaml +39 -0
  39. icdev/data/args/observability_tracing_config.yaml +170 -0
  40. icdev/data/args/oscal_tools_config.yaml +43 -0
  41. icdev/data/args/owasp_agentic_config.yaml +171 -0
  42. icdev/data/args/phase_registry.yaml +618 -0
  43. icdev/data/args/project_defaults.yaml +235 -0
  44. icdev/data/args/prompt_chains.yaml +163 -0
  45. icdev/data/args/resilience_config.yaml +50 -0
  46. icdev/data/args/ricoas_config.yaml +191 -0
  47. icdev/data/args/role_personas.yaml +362 -0
  48. icdev/data/args/scaling_config.yaml +176 -0
  49. icdev/data/args/security_gates.yaml +685 -0
  50. icdev/data/args/skill_injection_config.yaml +322 -0
  51. icdev/data/args/spec_config.yaml +53 -0
  52. icdev/data/args/supply_chain_config.yaml +76 -0
  53. icdev/data/args/translation_config.yaml +228 -0
  54. icdev/data/args/workflow_templates/ato_acceleration.yaml +54 -0
  55. icdev/data/args/workflow_templates/build_deploy.yaml +63 -0
  56. icdev/data/args/workflow_templates/full_compliance.yaml +43 -0
  57. icdev/data/args/workflow_templates/security_hardening.yaml +55 -0
  58. icdev/data/args/worktree_config.yaml +34 -0
  59. icdev/data/args/zta_config.yaml +247 -0
  60. icdev/data/context/__init__.py +1 -0
  61. icdev/data/context/agent/__init__.py +1 -0
  62. icdev/data/context/agent/response_schemas/__init__.py +1 -0
  63. icdev/data/context/agent/response_schemas/debate_position.json +46 -0
  64. icdev/data/context/agent/response_schemas/fitness_scorecard.json +74 -0
  65. icdev/data/context/agent/response_schemas/review_decision.json +39 -0
  66. icdev/data/context/agent/response_schemas/task_decomposition.json +82 -0
  67. icdev/data/context/agent/response_schemas/veto_decision.json +40 -0
  68. icdev/data/context/agentic/__init__.py +1 -0
  69. icdev/data/context/agentic/architecture_patterns.md +269 -0
  70. icdev/data/context/agentic/capability_registry.yaml +202 -0
  71. icdev/data/context/agentic/csp_mcp_registry.yaml +280 -0
  72. icdev/data/context/agentic/fitness_rubric.md +56 -0
  73. icdev/data/context/agentic/governance_baseline.md +205 -0
  74. icdev/data/context/ci/__init__.py +1 -0
  75. icdev/data/context/ci/worktree_templates.json +44 -0
  76. icdev/data/context/cloud/__init__.py +1 -0
  77. icdev/data/context/cloud/csp_service_registry.json +739 -0
  78. icdev/data/context/compliance/__init__.py +1 -0
  79. icdev/data/context/compliance/atlas_mitigations.json +293 -0
  80. icdev/data/context/compliance/atlas_techniques.json +833 -0
  81. icdev/data/context/compliance/cisa_sbd_requirements.json +432 -0
  82. icdev/data/context/compliance/cjis_security_policy.json +522 -0
  83. icdev/data/context/compliance/cmmc_practices.json +2494 -0
  84. icdev/data/context/compliance/cmmc_report_template.md +142 -0
  85. icdev/data/context/compliance/cnssi_1253_overlay.json +109 -0
  86. icdev/data/context/compliance/control_crosswalk.json +1914 -0
  87. icdev/data/context/compliance/control_families/__init__.py +1 -0
  88. icdev/data/context/compliance/csp_certifications.json +251 -0
  89. icdev/data/context/compliance/cssp_report_template.md +193 -0
  90. icdev/data/context/compliance/cui_templates/__init__.py +1 -0
  91. icdev/data/context/compliance/cui_templates/banner_block.txt +4 -0
  92. icdev/data/context/compliance/cui_templates/code_header.txt +8 -0
  93. icdev/data/context/compliance/cui_templates/document_template.md +35 -0
  94. icdev/data/context/compliance/data_type_framework_map.json +321 -0
  95. icdev/data/context/compliance/data_type_registry.json +147 -0
  96. icdev/data/context/compliance/dod_cssp_8530.json +463 -0
  97. icdev/data/context/compliance/eu_ai_act_annex_iii.json +108 -0
  98. icdev/data/context/compliance/export_templates/__init__.py +1 -0
  99. icdev/data/context/compliance/export_templates/emass_controls.csv.j2 +4 -0
  100. icdev/data/context/compliance/export_templates/evidence_package.md.j2 +39 -0
  101. icdev/data/context/compliance/export_templates/executive_summary.md.j2 +55 -0
  102. icdev/data/context/compliance/export_templates/poam_tracking.csv.j2 +4 -0
  103. icdev/data/context/compliance/fedramp_20x_ksi_schemas.json +133 -0
  104. icdev/data/context/compliance/fedramp_high_baseline.json +4370 -0
  105. icdev/data/context/compliance/fedramp_moderate_baseline.json +2183 -0
  106. icdev/data/context/compliance/fedramp_report_template.md +181 -0
  107. icdev/data/context/compliance/fips_200_areas.json +362 -0
  108. icdev/data/context/compliance/gao_ai_accountability.json +262 -0
  109. icdev/data/context/compliance/hipaa_security_rule.json +720 -0
  110. icdev/data/context/compliance/hitrust_csf_v11.json +930 -0
  111. icdev/data/context/compliance/impact_level_profiles.json +251 -0
  112. icdev/data/context/compliance/incident_response_template.md +1110 -0
  113. icdev/data/context/compliance/iso27001_2022_controls.json +750 -0
  114. icdev/data/context/compliance/iso27001_nist_bridge.json +382 -0
  115. icdev/data/context/compliance/iso42001_controls.json +254 -0
  116. icdev/data/context/compliance/ivv_checklist_template.md +80 -0
  117. icdev/data/context/compliance/ivv_report_template.md +116 -0
  118. icdev/data/context/compliance/ivv_requirements.json +372 -0
  119. icdev/data/context/compliance/mosa_crosswalk.json +327 -0
  120. icdev/data/context/compliance/mosa_framework.json +250 -0
  121. icdev/data/context/compliance/narrative_templates/AC.md.j2 +101 -0
  122. icdev/data/context/compliance/narrative_templates/AU.md.j2 +106 -0
  123. icdev/data/context/compliance/narrative_templates/IA.md.j2 +104 -0
  124. icdev/data/context/compliance/narrative_templates/SC.md.j2 +102 -0
  125. icdev/data/context/compliance/narrative_templates/SI.md.j2 +111 -0
  126. icdev/data/context/compliance/narrative_templates/__init__.py +1 -0
  127. icdev/data/context/compliance/narrative_templates/default.md.j2 +50 -0
  128. icdev/data/context/compliance/narrative_templates/executive_summary.j2 +27 -0
  129. icdev/data/context/compliance/narrative_templates/poam_milestone.j2 +19 -0
  130. icdev/data/context/compliance/narrative_templates/ssp_section.j2 +11 -0
  131. icdev/data/context/compliance/nist_800_171_controls.json +1552 -0
  132. icdev/data/context/compliance/nist_800_207_crosswalk.json +399 -0
  133. icdev/data/context/compliance/nist_800_207_zta.json +258 -0
  134. icdev/data/context/compliance/nist_800_53.json +324 -0
  135. icdev/data/context/compliance/nist_ai_600_1_genai.json +326 -0
  136. icdev/data/context/compliance/nist_ai_rmf.json +206 -0
  137. icdev/data/context/compliance/nist_sp_800_60_types.json +1667 -0
  138. icdev/data/context/compliance/omb_m25_21_high_impact_ai.json +248 -0
  139. icdev/data/context/compliance/omb_m26_04_unbiased_ai.json +262 -0
  140. icdev/data/context/compliance/owasp_agentic_asi.json +133 -0
  141. icdev/data/context/compliance/owasp_agentic_threats.json +285 -0
  142. icdev/data/context/compliance/owasp_llm_top10.json +274 -0
  143. icdev/data/context/compliance/pci_dss_v4.json +510 -0
  144. icdev/data/context/compliance/poam_template.md +117 -0
  145. icdev/data/context/compliance/safeai_controls.json +512 -0
  146. icdev/data/context/compliance/sbd_report_template.md +77 -0
  147. icdev/data/context/compliance/siem_config_templates/__init__.py +1 -0
  148. icdev/data/context/compliance/siem_config_templates/filebeat.yml +213 -0
  149. icdev/data/context/compliance/siem_config_templates/log_sources.json +208 -0
  150. icdev/data/context/compliance/soc2_trust_criteria.json +661 -0
  151. icdev/data/context/compliance/ssp_template.md +432 -0
  152. icdev/data/context/compliance/stig_templates/__init__.py +1 -0
  153. icdev/data/context/compliance/stig_templates/webapp_stig.json +139 -0
  154. icdev/data/context/compliance/xai_requirements.json +108 -0
  155. icdev/data/context/dashboard/__init__.py +1 -0
  156. icdev/data/context/dashboard/nlq_examples.json +50 -0
  157. icdev/data/context/dashboard/schema_descriptions.json +23 -0
  158. icdev/data/context/integration/__init__.py +1 -0
  159. icdev/data/context/integration/approval_workflows.json +32 -0
  160. icdev/data/context/integration/gitlab_field_mappings.json +33 -0
  161. icdev/data/context/integration/jira_field_mappings.json +32 -0
  162. icdev/data/context/integration/reqif_export_schema.json +23 -0
  163. icdev/data/context/integration/servicenow_field_mappings.json +22 -0
  164. icdev/data/context/languages/__init__.py +1 -0
  165. icdev/data/context/languages/framework_patterns.json +205 -0
  166. icdev/data/context/languages/language_registry.json +279 -0
  167. icdev/data/context/llm/__init__.py +1 -0
  168. icdev/data/context/llm/example_provider.py +86 -0
  169. icdev/data/context/mbse/__init__.py +1 -0
  170. icdev/data/context/mbse/des_report_template.md +162 -0
  171. icdev/data/context/mbse/des_requirements.json +411 -0
  172. icdev/data/context/mbse/digital_thread_patterns.json +403 -0
  173. icdev/data/context/mbse/reqif_schema.json +280 -0
  174. icdev/data/context/mbse/sysml_element_types.json +432 -0
  175. icdev/data/context/modernization/__init__.py +1 -0
  176. icdev/data/context/modernization/db_type_mappings.json +148 -0
  177. icdev/data/context/modernization/decomposition_patterns.json +284 -0
  178. icdev/data/context/modernization/framework_migration_patterns.json +359 -0
  179. icdev/data/context/modernization/migration_report_template.md +168 -0
  180. icdev/data/context/modernization/seven_rs_catalog.json +369 -0
  181. icdev/data/context/modernization/version_upgrade_rules.json +279 -0
  182. icdev/data/context/oscal/NIST_SP-800-53_rev5_catalog.json +254987 -0
  183. icdev/data/context/oscal/README.md +43 -0
  184. icdev/data/context/patterns/__init__.py +1 -0
  185. icdev/data/context/profiles/__init__.py +1 -0
  186. icdev/data/context/profiles/dod_baseline_v1.yaml +145 -0
  187. icdev/data/context/profiles/fedramp_baseline_v1.yaml +143 -0
  188. icdev/data/context/profiles/financial_baseline_v1.yaml +142 -0
  189. icdev/data/context/profiles/healthcare_baseline_v1.yaml +135 -0
  190. icdev/data/context/profiles/law_enforcement_v1.yaml +129 -0
  191. icdev/data/context/profiles/startup_v1.yaml +134 -0
  192. icdev/data/context/requirements/__init__.py +1 -0
  193. icdev/data/context/requirements/ambiguity_patterns.json +97 -0
  194. icdev/data/context/requirements/boundary_impact_rules.json +123 -0
  195. icdev/data/context/requirements/default_constitutions.json +67 -0
  196. icdev/data/context/requirements/document_extraction_rules.json +58 -0
  197. icdev/data/context/requirements/gap_patterns.json +108 -0
  198. icdev/data/context/requirements/readiness_rubric.json +78 -0
  199. icdev/data/context/requirements/red_alternative_patterns.json +210 -0
  200. icdev/data/context/requirements/safe_templates.json +72 -0
  201. icdev/data/context/requirements/spec_quality_checklist.json +122 -0
  202. icdev/data/context/simulation/__init__.py +1 -0
  203. icdev/data/context/simulation/architecture_patterns.json +36 -0
  204. icdev/data/context/simulation/coa_templates.json +38 -0
  205. icdev/data/context/simulation/cost_models.json +23 -0
  206. icdev/data/context/simulation/risk_categories.json +46 -0
  207. icdev/data/context/supply_chain/__init__.py +1 -0
  208. icdev/data/context/supply_chain/isa_templates.json +129 -0
  209. icdev/data/context/supply_chain/nist_800_161_controls.json +247 -0
  210. icdev/data/context/supply_chain/scrm_risk_matrix.json +147 -0
  211. icdev/data/context/templates/__init__.py +1 -0
  212. icdev/data/context/templates/ansible/__init__.py +1 -0
  213. icdev/data/context/templates/ansible/playbooks/__init__.py +1 -0
  214. icdev/data/context/templates/ansible/roles/__init__.py +1 -0
  215. icdev/data/context/templates/gitlab_ci/__init__.py +1 -0
  216. icdev/data/context/templates/grafana/__init__.py +1 -0
  217. icdev/data/context/templates/kubernetes/__init__.py +1 -0
  218. icdev/data/context/templates/project/__init__.py +1 -0
  219. icdev/data/context/templates/project/api/__init__.py +1 -0
  220. icdev/data/context/templates/project/cli/__init__.py +1 -0
  221. icdev/data/context/templates/project/data_pipeline/__init__.py +1 -0
  222. icdev/data/context/templates/project/iac/__init__.py +1 -0
  223. icdev/data/context/templates/project/javascript_frontend/__init__.py +1 -0
  224. icdev/data/context/templates/project/javascript_frontend/src/__init__.py +1 -0
  225. icdev/data/context/templates/project/javascript_frontend/tests/__init__.py +1 -0
  226. icdev/data/context/templates/project/microservice/__init__.py +1 -0
  227. icdev/data/context/templates/project/python_backend/__init__.py +1 -0
  228. icdev/data/context/templates/project/python_backend/src/__init__.py +1 -0
  229. icdev/data/context/templates/project/python_backend/tests/__init__.py +1 -0
  230. icdev/data/context/templates/project/python_backend/tests/features/__init__.py +1 -0
  231. icdev/data/context/templates/project/python_backend/tests/steps/__init__.py +1 -0
  232. icdev/data/context/templates/terraform/__init__.py +1 -0
  233. icdev/data/context/templates/terraform/govcloud_base/__init__.py +1 -0
  234. icdev/data/context/templates/terraform/modules/__init__.py +1 -0
  235. icdev/data/context/tone/__init__.py +1 -0
  236. icdev/data/context/translation/dependency_mappings.json +186 -0
  237. icdev/data/context/translation/type_mappings.json +149 -0
  238. icdev/data/docs/README.md +187 -0
  239. icdev/data/docs/__init__.py +1 -0
  240. icdev/data/docs/admin/gateway-guide.md +338 -0
  241. icdev/data/docs/admin/marketplace-guide.md +396 -0
  242. icdev/data/docs/admin/monitoring-guide.md +509 -0
  243. icdev/data/docs/architecture/compliance-framework.md +764 -0
  244. icdev/data/docs/architecture/database-schema.md +689 -0
  245. icdev/data/docs/architecture/gotcha-framework.md +518 -0
  246. icdev/data/docs/architecture/multi-agent-system.md +603 -0
  247. icdev/data/docs/dx/README.md +106 -0
  248. icdev/data/docs/dx/__init__.py +1 -0
  249. icdev/data/docs/dx/ci-cd-integration.md +378 -0
  250. icdev/data/docs/dx/claude-code-guide.md +213 -0
  251. icdev/data/docs/dx/companion-guide.md +232 -0
  252. icdev/data/docs/dx/dev-profiles.md +309 -0
  253. icdev/data/docs/dx/icdev-yaml-spec.md +219 -0
  254. icdev/data/docs/dx/integration-tiers.md +279 -0
  255. icdev/data/docs/dx/llm-routing-guide.md +456 -0
  256. icdev/data/docs/dx/quickstart.md +192 -0
  257. icdev/data/docs/dx/sdk-reference.md +356 -0
  258. icdev/data/docs/dx/unified-mcp-setup.md +525 -0
  259. icdev/data/docs/features/__init__.py +1 -0
  260. icdev/data/docs/features/phase-01-gotcha-framework.md +249 -0
  261. icdev/data/docs/features/phase-02-atlas-build-workflow.md +223 -0
  262. icdev/data/docs/features/phase-03-tdd-bdd-testing.md +261 -0
  263. icdev/data/docs/features/phase-04-nist-compliance.md +255 -0
  264. icdev/data/docs/features/phase-05-security-scanning.md +229 -0
  265. icdev/data/docs/features/phase-06-infrastructure-deployment.md +288 -0
  266. icdev/data/docs/features/phase-07-code-review-gates.md +276 -0
  267. icdev/data/docs/features/phase-08-self-healing.md +223 -0
  268. icdev/data/docs/features/phase-09-monitoring-observability.md +230 -0
  269. icdev/data/docs/features/phase-10-dashboard-web-ui.md +218 -0
  270. icdev/data/docs/features/phase-11-multi-agent-architecture.md +272 -0
  271. icdev/data/docs/features/phase-12-integration-testing.md +228 -0
  272. icdev/data/docs/features/phase-13-cicd-integration.md +257 -0
  273. icdev/data/docs/features/phase-14-secure-by-design-ivv.md +240 -0
  274. icdev/data/docs/features/phase-15-maintenance-audit.md +192 -0
  275. icdev/data/docs/features/phase-16-ato-acceleration.md +228 -0
  276. icdev/data/docs/features/phase-17-multi-framework-compliance.md +223 -0
  277. icdev/data/docs/features/phase-18-mbse-integration.md +242 -0
  278. icdev/data/docs/features/phase-19-agentic-generation.md +202 -0
  279. icdev/data/docs/features/phase-20-fips-security-categorization.md +198 -0
  280. icdev/data/docs/features/phase-21-saas-multi-tenancy.md +273 -0
  281. icdev/data/docs/features/phase-22-federated-gotcha-marketplace.md +242 -0
  282. icdev/data/docs/features/phase-23-universal-compliance-platform.md +238 -0
  283. icdev/data/docs/features/phase-24-devsecops-pipeline-security.md +198 -0
  284. icdev/data/docs/features/phase-25-zero-trust-architecture.md +220 -0
  285. icdev/data/docs/features/phase-26-dod-mosa.md +205 -0
  286. icdev/data/docs/features/phase-27-cli-capabilities.md +222 -0
  287. icdev/data/docs/features/phase-28-remote-command-gateway.md +235 -0
  288. icdev/data/docs/features/phase-29-proactive-monitoring.md +212 -0
  289. icdev/data/docs/features/phase-30-dashboard-auth.md +215 -0
  290. icdev/data/docs/features/phase-31-dashboard-ux-low-impact.md +188 -0
  291. icdev/data/docs/features/phase-32-dashboard-ux-medium-impact.md +223 -0
  292. icdev/data/docs/features/phase-33-modular-installation.md +218 -0
  293. icdev/data/docs/features/phase-34-dev-profiles.md +239 -0
  294. icdev/data/docs/features/phase-35-innovation-engine.md +257 -0
  295. icdev/data/docs/features/phase-36-evolutionary-intelligence.md +351 -0
  296. icdev/data/docs/features/phase-37-mitre-atlas-integration.md +485 -0
  297. icdev/data/docs/features/phase-38-cloud-agnostic-architecture.md +1033 -0
  298. icdev/data/docs/features/phase-39-observability-operations.md +178 -0
  299. icdev/data/docs/features/phase-40-nlq-compliance-queries.md +176 -0
  300. icdev/data/docs/features/phase-41-parallel-cicd.md +169 -0
  301. icdev/data/docs/features/phase-42-framework-planning.md +177 -0
  302. icdev/data/docs/features/phase-43-cross-language-translation.md +225 -0
  303. icdev/data/docs/features/phase-44-innovation-adaptation.md +227 -0
  304. icdev/data/docs/features/phase-45-owasp-agentic-security.md +239 -0
  305. icdev/data/docs/features/phase-46-observability-traceability-xai.md +240 -0
  306. icdev/data/docs/features/phase-47-unified-mcp-gateway.md +257 -0
  307. icdev/data/docs/features/phase-48-ai-transparency.md +203 -0
  308. icdev/data/docs/features/phase-49-ai-accountability.md +243 -0
  309. icdev/data/docs/features/phase-50-ai-governance-intake-chat.md +195 -0
  310. icdev/data/docs/features/phase-51-unified-chat-dashboard.md +240 -0
  311. icdev/data/docs/features/phase-52-code-intelligence.md +244 -0
  312. icdev/data/docs/features/phase-53-fedramp-20x-owasp-asi.md +359 -0
  313. icdev/data/docs/features/phase-54-slsa-swft-orchestration.md +379 -0
  314. icdev/data/docs/features/phase-55-a2a-v03-mcp-oauth.md +322 -0
  315. icdev/data/docs/features/phase-56-evidence-lineage.md +352 -0
  316. icdev/data/docs/features/phase-57-eu-ai-act-iron-bank.md +319 -0
  317. icdev/data/docs/features/phase-58-creative-engine.md +370 -0
  318. icdev/data/docs/features/phase-59-govcon-intelligence.md +535 -0
  319. icdev/data/docs/features/phase-60-cpmp.md +528 -0
  320. icdev/data/docs/features/phase-61-orchestration-improvements.md +534 -0
  321. icdev/data/docs/operations/dashboard-guide.md +354 -0
  322. icdev/data/docs/operations/deployment-guide.md +556 -0
  323. icdev/data/docs/operations/saas-admin-guide.md +439 -0
  324. icdev/data/docs/operations/security-operations-guide.md +733 -0
  325. icdev/data/docs/runbooks/backup-restore.md +412 -0
  326. icdev/data/docs/runbooks/troubleshooting.md +499 -0
  327. icdev/data/features/__init__.py +1 -0
  328. icdev/data/features/cicd_integration.feature +41 -0
  329. icdev/data/features/compliance_gates.feature +46 -0
  330. icdev/data/features/dashboard.feature +72 -0
  331. icdev/data/features/environment.py +25 -0
  332. icdev/data/features/project_management.feature +32 -0
  333. icdev/data/features/requirements_intake.feature +42 -0
  334. icdev/data/features/saas_platform.feature +53 -0
  335. icdev/data/features/security_scanning.feature +36 -0
  336. icdev/data/features/steps/__init__.py +1 -0
  337. icdev/data/features/steps/cicd_steps.py +465 -0
  338. icdev/data/features/steps/compliance_steps.py +308 -0
  339. icdev/data/features/steps/dashboard_steps.py +88 -0
  340. icdev/data/features/steps/project_steps.py +126 -0
  341. icdev/data/features/steps/requirements_intake_steps.py +689 -0
  342. icdev/data/features/steps/saas_platform_steps.py +572 -0
  343. icdev/data/features/steps/security_steps.py +236 -0
  344. icdev/data/features/steps/testing_steps.py +226 -0
  345. icdev/data/features/testing_pipeline.feature +42 -0
  346. icdev/data/goals/__init__.py +1 -0
  347. icdev/data/goals/agent_management.md +144 -0
  348. icdev/data/goals/agentic_generation.md +345 -0
  349. icdev/data/goals/agentic_threat_model.md +309 -0
  350. icdev/data/goals/ai_accountability.md +90 -0
  351. icdev/data/goals/ai_governance_intake.md +132 -0
  352. icdev/data/goals/ai_transparency.md +76 -0
  353. icdev/data/goals/atlas_integration.md +405 -0
  354. icdev/data/goals/ato_acceleration.md +139 -0
  355. icdev/data/goals/boundary_supply_chain.md +206 -0
  356. icdev/data/goals/build_app.md +544 -0
  357. icdev/data/goals/cicd_integration.md +86 -0
  358. icdev/data/goals/claude_dir_maintenance.md +77 -0
  359. icdev/data/goals/cli_capabilities.md +340 -0
  360. icdev/data/goals/cloud_agnostic.md +312 -0
  361. icdev/data/goals/code_intelligence.md +197 -0
  362. icdev/data/goals/code_review.md +94 -0
  363. icdev/data/goals/compliance_workflow.md +858 -0
  364. icdev/data/goals/continuous_harmonization.md +140 -0
  365. icdev/data/goals/cross_language_translation.md +171 -0
  366. icdev/data/goals/dashboard.md +142 -0
  367. icdev/data/goals/deploy_workflow.md +390 -0
  368. icdev/data/goals/devsecops_workflow.md +408 -0
  369. icdev/data/goals/evolutionary_intelligence.md +305 -0
  370. icdev/data/goals/external_integration.md +113 -0
  371. icdev/data/goals/framework_planning.md +63 -0
  372. icdev/data/goals/init_project.md +235 -0
  373. icdev/data/goals/innovation_engine.md +199 -0
  374. icdev/data/goals/integration_testing.md +189 -0
  375. icdev/data/goals/maintenance_audit.md +196 -0
  376. icdev/data/goals/manifest.md +56 -0
  377. icdev/data/goals/mbse_integration.md +504 -0
  378. icdev/data/goals/modernization_workflow.md +618 -0
  379. icdev/data/goals/monitoring.md +126 -0
  380. icdev/data/goals/mosa_workflow.md +463 -0
  381. icdev/data/goals/multi_agent_orchestration.md +68 -0
  382. icdev/data/goals/nlq_compliance.md +63 -0
  383. icdev/data/goals/observability.md +64 -0
  384. icdev/data/goals/observability_traceability_xai.md +154 -0
  385. icdev/data/goals/owasp_agentic_security.md +395 -0
  386. icdev/data/goals/parallel_cicd.md +61 -0
  387. icdev/data/goals/requirements_intake.md +213 -0
  388. icdev/data/goals/sbd_ivv_workflow.md +195 -0
  389. icdev/data/goals/security_categorization.md +133 -0
  390. icdev/data/goals/security_scan.md +381 -0
  391. icdev/data/goals/self_healing.md +120 -0
  392. icdev/data/goals/simulation_engine.md +111 -0
  393. icdev/data/goals/tdd_workflow.md +403 -0
  394. icdev/data/goals/zero_trust_architecture.md +403 -0
  395. icdev/data/hardprompts/__init__.py +1 -0
  396. icdev/data/hardprompts/agent/__init__.py +1 -0
  397. icdev/data/hardprompts/agent/agentic_architect.md +100 -0
  398. icdev/data/hardprompts/agent/debate_prompt.md +32 -0
  399. icdev/data/hardprompts/agent/fitness_evaluation.md +48 -0
  400. icdev/data/hardprompts/agent/governance_review.md +214 -0
  401. icdev/data/hardprompts/agent/reviewer_prompt.md +34 -0
  402. icdev/data/hardprompts/agent/skill_design.md +172 -0
  403. icdev/data/hardprompts/agent/task_decomposition.md +275 -0
  404. icdev/data/hardprompts/agent/veto_check_prompt.md +33 -0
  405. icdev/data/hardprompts/architect/__init__.py +1 -0
  406. icdev/data/hardprompts/architect/api_design.md +283 -0
  407. icdev/data/hardprompts/architect/data_model.md +277 -0
  408. icdev/data/hardprompts/architect/system_design.md +180 -0
  409. icdev/data/hardprompts/builder/__init__.py +1 -0
  410. icdev/data/hardprompts/builder/code_generation.md +59 -0
  411. icdev/data/hardprompts/builder/refactor.md +58 -0
  412. icdev/data/hardprompts/builder/scaffold_project.md +69 -0
  413. icdev/data/hardprompts/builder/test_generation.md +87 -0
  414. icdev/data/hardprompts/ci/__init__.py +1 -0
  415. icdev/data/hardprompts/ci/worktree_setup.md +35 -0
  416. icdev/data/hardprompts/compliance/__init__.py +1 -0
  417. icdev/data/hardprompts/compliance/cmmc_assessment.md +63 -0
  418. icdev/data/hardprompts/compliance/cssp_assessment.md +75 -0
  419. icdev/data/hardprompts/compliance/cui_marking.md +86 -0
  420. icdev/data/hardprompts/compliance/fedramp_assessment.md +55 -0
  421. icdev/data/hardprompts/compliance/ivv_assessment.md +96 -0
  422. icdev/data/hardprompts/compliance/poam_generation.md +57 -0
  423. icdev/data/hardprompts/compliance/sbd_assessment.md +101 -0
  424. icdev/data/hardprompts/compliance/security_categorization.md +74 -0
  425. icdev/data/hardprompts/compliance/ssp_generation.md +56 -0
  426. icdev/data/hardprompts/compliance/stig_evaluation.md +63 -0
  427. icdev/data/hardprompts/dashboard/__init__.py +1 -0
  428. icdev/data/hardprompts/dashboard/nlq_system_prompt.md +26 -0
  429. icdev/data/hardprompts/infra/__init__.py +1 -0
  430. icdev/data/hardprompts/infra/k8s_manifests.md +118 -0
  431. icdev/data/hardprompts/infra/pipeline_generation.md +160 -0
  432. icdev/data/hardprompts/infra/terraform_generation.md +92 -0
  433. icdev/data/hardprompts/integration/__init__.py +1 -0
  434. icdev/data/hardprompts/integration/approval_review.md +17 -0
  435. icdev/data/hardprompts/integration/jira_mapping.md +25 -0
  436. icdev/data/hardprompts/integration/servicenow_mapping.md +14 -0
  437. icdev/data/hardprompts/knowledge/__init__.py +1 -0
  438. icdev/data/hardprompts/knowledge/pattern_detection.md +73 -0
  439. icdev/data/hardprompts/knowledge/recommendation_engine.md +90 -0
  440. icdev/data/hardprompts/knowledge/root_cause_analysis.md +91 -0
  441. icdev/data/hardprompts/maintenance/__init__.py +1 -0
  442. icdev/data/hardprompts/maintenance/maintenance_assessment.md +82 -0
  443. icdev/data/hardprompts/mbse/__init__.py +1 -0
  444. icdev/data/hardprompts/mbse/digital_thread.md +67 -0
  445. icdev/data/hardprompts/mbse/model_import.md +62 -0
  446. icdev/data/hardprompts/mbse/model_to_code.md +65 -0
  447. icdev/data/hardprompts/modernization/__init__.py +1 -0
  448. icdev/data/hardprompts/modernization/legacy_analysis.md +93 -0
  449. icdev/data/hardprompts/modernization/migration_planning.md +150 -0
  450. icdev/data/hardprompts/modernization/seven_r_assessment.md +107 -0
  451. icdev/data/hardprompts/requirements/__init__.py +1 -0
  452. icdev/data/hardprompts/requirements/bdd_generation.md +35 -0
  453. icdev/data/hardprompts/requirements/clarification_prioritization.md +29 -0
  454. icdev/data/hardprompts/requirements/decomposition.md +60 -0
  455. icdev/data/hardprompts/requirements/document_extraction.md +45 -0
  456. icdev/data/hardprompts/requirements/gap_detection.md +70 -0
  457. icdev/data/hardprompts/requirements/intake_conversation.md +101 -0
  458. icdev/data/hardprompts/requirements/readiness_assessment.md +39 -0
  459. icdev/data/hardprompts/requirements/spec_quality.md +33 -0
  460. icdev/data/hardprompts/requirements/traceability_analysis.md +23 -0
  461. icdev/data/hardprompts/security/__init__.py +1 -0
  462. icdev/data/hardprompts/security/endpoint_security.md +78 -0
  463. icdev/data/hardprompts/security/threat_model.md +70 -0
  464. icdev/data/hardprompts/security/vulnerability_assessment.md +81 -0
  465. icdev/data/hardprompts/simulation/__init__.py +1 -0
  466. icdev/data/hardprompts/simulation/architecture_impact.md +27 -0
  467. icdev/data/hardprompts/simulation/coa_alternative.md +27 -0
  468. icdev/data/hardprompts/simulation/coa_generation.md +25 -0
  469. icdev/data/hardprompts/simulation/compliance_impact.md +28 -0
  470. icdev/data/hardprompts/simulation/cost_estimation.md +33 -0
  471. icdev/data/hardprompts/simulation/risk_assessment.md +28 -0
  472. icdev/data/hardprompts/translation/code_translation.md +68 -0
  473. icdev/data/hardprompts/translation/dependency_suggestion.md +44 -0
  474. icdev/data/hardprompts/translation/test_translation.md +64 -0
  475. icdev/data/hardprompts/translation/translation_repair.md +59 -0
  476. icdev/py.typed +0 -0
  477. icdev/tools/__init__.py +1 -0
  478. icdev/tools/_gen_formatter.py +12 -0
  479. icdev/tools/a2a/__init__.py +1 -0
  480. icdev/tools/a2a/agent_cards/architect.json +43 -0
  481. icdev/tools/a2a/agent_cards/builder.json +50 -0
  482. icdev/tools/a2a/agent_cards/compliance.json +57 -0
  483. icdev/tools/a2a/agent_cards/devsecops.json +71 -0
  484. icdev/tools/a2a/agent_cards/infra.json +57 -0
  485. icdev/tools/a2a/agent_cards/integration.json +57 -0
  486. icdev/tools/a2a/agent_cards/knowledge.json +43 -0
  487. icdev/tools/a2a/agent_cards/mbse.json +57 -0
  488. icdev/tools/a2a/agent_cards/modernization.json +50 -0
  489. icdev/tools/a2a/agent_cards/monitor.json +43 -0
  490. icdev/tools/a2a/agent_cards/orchestrator.json +36 -0
  491. icdev/tools/a2a/agent_cards/requirements_analyst.json +64 -0
  492. icdev/tools/a2a/agent_cards/security.json +50 -0
  493. icdev/tools/a2a/agent_cards/simulation.json +57 -0
  494. icdev/tools/a2a/agent_cards/supply_chain.json +50 -0
  495. icdev/tools/a2a/agent_client.py +349 -0
  496. icdev/tools/a2a/agent_registry.py +412 -0
  497. icdev/tools/a2a/agent_server.py +579 -0
  498. icdev/tools/a2a/task.py +200 -0
  499. icdev/tools/agent/__init__.py +2 -0
  500. icdev/tools/agent/a2a_agent_card_generator.py +285 -0
  501. icdev/tools/agent/a2a_discovery_server.py +250 -0
  502. icdev/tools/agent/agent_executor.py +529 -0
  503. icdev/tools/agent/agent_memory.py +557 -0
  504. icdev/tools/agent/agent_models.py +51 -0
  505. icdev/tools/agent/atlas_critique.py +908 -0
  506. icdev/tools/agent/authority.py +443 -0
  507. icdev/tools/agent/bedrock_client.py +1075 -0
  508. icdev/tools/agent/collaboration.py +871 -0
  509. icdev/tools/agent/dispatcher_mode.py +665 -0
  510. icdev/tools/agent/mailbox.py +575 -0
  511. icdev/tools/agent/prompt_chain_executor.py +1064 -0
  512. icdev/tools/agent/session_purpose.py +350 -0
  513. icdev/tools/agent/skill_router.py +638 -0
  514. icdev/tools/agent/skill_selector.py +486 -0
  515. icdev/tools/agent/team_orchestrator.py +1108 -0
  516. icdev/tools/agent/token_tracker.py +290 -0
  517. icdev/tools/analysis/__init__.py +1 -0
  518. icdev/tools/analysis/code_analyzer.py +780 -0
  519. icdev/tools/analysis/runtime_feedback.py +389 -0
  520. icdev/tools/audit/__init__.py +1 -0
  521. icdev/tools/audit/audit_logger.py +196 -0
  522. icdev/tools/audit/audit_query.py +157 -0
  523. icdev/tools/audit/decision_recorder.py +72 -0
  524. icdev/tools/builder/__init__.py +1 -0
  525. icdev/tools/builder/agentic_fitness.py +534 -0
  526. icdev/tools/builder/agentic_test_templates/test_a2a_callback.py +117 -0
  527. icdev/tools/builder/agentic_test_templates/test_a2a_lifecycle.feature +52 -0
  528. icdev/tools/builder/agentic_test_templates/test_agent_card.feature +37 -0
  529. icdev/tools/builder/agentic_test_templates/test_agent_health.py +128 -0
  530. icdev/tools/builder/agentic_test_templates/test_memory_system.feature +50 -0
  531. icdev/tools/builder/agentic_test_templates/test_skill_execution.feature +40 -0
  532. icdev/tools/builder/app_blueprint.py +1583 -0
  533. icdev/tools/builder/child_app_generator.py +2852 -0
  534. icdev/tools/builder/claude_md_generator.py +1734 -0
  535. icdev/tools/builder/code_generator.py +3703 -0
  536. icdev/tools/builder/db_init_generator.py +1709 -0
  537. icdev/tools/builder/dev_profile_manager.py +954 -0
  538. icdev/tools/builder/formatter.py +768 -0
  539. icdev/tools/builder/goal_adapter.py +592 -0
  540. icdev/tools/builder/gotcha_validator.py +812 -0
  541. icdev/tools/builder/language_support.py +441 -0
  542. icdev/tools/builder/linter.py +976 -0
  543. icdev/tools/builder/profile_detector.py +657 -0
  544. icdev/tools/builder/profile_md_generator.py +723 -0
  545. icdev/tools/builder/scaffolder.py +1590 -0
  546. icdev/tools/builder/scaffolder_extended.py +1771 -0
  547. icdev/tools/builder/test_writer.py +950 -0
  548. icdev/tools/ci/__init__.py +2 -0
  549. icdev/tools/ci/connectors/__init__.py +2 -0
  550. icdev/tools/ci/connectors/base_connector.py +80 -0
  551. icdev/tools/ci/connectors/connector_registry.py +188 -0
  552. icdev/tools/ci/connectors/mattermost_connector.py +159 -0
  553. icdev/tools/ci/connectors/slack_connector.py +197 -0
  554. icdev/tools/ci/core/__init__.py +2 -0
  555. icdev/tools/ci/core/air_gap_detector.py +115 -0
  556. icdev/tools/ci/core/comment_handler.py +192 -0
  557. icdev/tools/ci/core/conversation_manager.py +479 -0
  558. icdev/tools/ci/core/event_envelope.py +500 -0
  559. icdev/tools/ci/core/event_router.py +443 -0
  560. icdev/tools/ci/core/failure_parser.py +397 -0
  561. icdev/tools/ci/core/recovery_engine.py +527 -0
  562. icdev/tools/ci/modules/__init__.py +2 -0
  563. icdev/tools/ci/modules/agent.py +271 -0
  564. icdev/tools/ci/modules/git_ops.py +175 -0
  565. icdev/tools/ci/modules/state.py +117 -0
  566. icdev/tools/ci/modules/vcs.py +303 -0
  567. icdev/tools/ci/modules/workflow_ops.py +295 -0
  568. icdev/tools/ci/modules/worktree.py +340 -0
  569. icdev/tools/ci/pipeline_config_generator.py +558 -0
  570. icdev/tools/ci/triggers/__init__.py +2 -0
  571. icdev/tools/ci/triggers/gitlab_task_monitor.py +330 -0
  572. icdev/tools/ci/triggers/poll_trigger.py +237 -0
  573. icdev/tools/ci/triggers/webhook_server.py +356 -0
  574. icdev/tools/ci/workflows/__init__.py +2 -0
  575. icdev/tools/ci/workflows/icdev_build.py +140 -0
  576. icdev/tools/ci/workflows/icdev_comply.py +284 -0
  577. icdev/tools/ci/workflows/icdev_document.py +152 -0
  578. icdev/tools/ci/workflows/icdev_e2e.py +188 -0
  579. icdev/tools/ci/workflows/icdev_patch.py +186 -0
  580. icdev/tools/ci/workflows/icdev_plan.py +202 -0
  581. icdev/tools/ci/workflows/icdev_plan_build.py +41 -0
  582. icdev/tools/ci/workflows/icdev_plan_build_test.py +46 -0
  583. icdev/tools/ci/workflows/icdev_plan_build_test_review.py +47 -0
  584. icdev/tools/ci/workflows/icdev_review.py +126 -0
  585. icdev/tools/ci/workflows/icdev_sdlc.py +261 -0
  586. icdev/tools/ci/workflows/icdev_test.py +240 -0
  587. icdev/tools/cli/__init__.py +1 -0
  588. icdev/tools/cli/output_formatter.py +756 -0
  589. icdev/tools/cli_formatter.py +42 -0
  590. icdev/tools/cloud/__init__.py +11 -0
  591. icdev/tools/cloud/cloud_mode_manager.py +364 -0
  592. icdev/tools/cloud/csp_changelog.py +383 -0
  593. icdev/tools/cloud/csp_health_checker.py +268 -0
  594. icdev/tools/cloud/csp_monitor.py +951 -0
  595. icdev/tools/cloud/iam_provider.py +593 -0
  596. icdev/tools/cloud/kms_provider.py +346 -0
  597. icdev/tools/cloud/monitoring_provider.py +628 -0
  598. icdev/tools/cloud/provider_factory.py +376 -0
  599. icdev/tools/cloud/region_validator.py +345 -0
  600. icdev/tools/cloud/registry_provider.py +563 -0
  601. icdev/tools/cloud/secrets_provider.py +486 -0
  602. icdev/tools/cloud/storage_provider.py +446 -0
  603. icdev/tools/compat/__init__.py +21 -0
  604. icdev/tools/compat/cli_harmonizer.py +251 -0
  605. icdev/tools/compat/datetime_utils.py +18 -0
  606. icdev/tools/compat/db_utils.py +160 -0
  607. icdev/tools/compat/platform_utils.py +123 -0
  608. icdev/tools/compliance/__init__.py +1 -0
  609. icdev/tools/compliance/accountability_manager.py +397 -0
  610. icdev/tools/compliance/ai_accountability_audit.py +294 -0
  611. icdev/tools/compliance/ai_impact_assessor.py +273 -0
  612. icdev/tools/compliance/ai_incident_response.py +301 -0
  613. icdev/tools/compliance/ai_inventory_manager.py +239 -0
  614. icdev/tools/compliance/ai_reassessment_scheduler.py +256 -0
  615. icdev/tools/compliance/ai_transparency_audit.py +248 -0
  616. icdev/tools/compliance/atlas_assessor.py +278 -0
  617. icdev/tools/compliance/atlas_report_generator.py +1211 -0
  618. icdev/tools/compliance/base_assessor.py +597 -0
  619. icdev/tools/compliance/cato_monitor.py +1385 -0
  620. icdev/tools/compliance/cato_scheduler.py +699 -0
  621. icdev/tools/compliance/cjis_assessor.py +76 -0
  622. icdev/tools/compliance/classification_manager.py +1353 -0
  623. icdev/tools/compliance/cmmc_assessor.py +1491 -0
  624. icdev/tools/compliance/cmmc_report_generator.py +1100 -0
  625. icdev/tools/compliance/compliance_detector.py +463 -0
  626. icdev/tools/compliance/compliance_exporter.py +427 -0
  627. icdev/tools/compliance/compliance_status.py +825 -0
  628. icdev/tools/compliance/control_mapper.py +505 -0
  629. icdev/tools/compliance/crosswalk_engine.py +1203 -0
  630. icdev/tools/compliance/cssp_assessor.py +1045 -0
  631. icdev/tools/compliance/cssp_evidence_collector.py +729 -0
  632. icdev/tools/compliance/cssp_report_generator.py +1116 -0
  633. icdev/tools/compliance/cui_marker.py +388 -0
  634. icdev/tools/compliance/diagram_validator.py +600 -0
  635. icdev/tools/compliance/emass/__init__.py +2 -0
  636. icdev/tools/compliance/emass/emass_client.py +840 -0
  637. icdev/tools/compliance/emass/emass_export.py +777 -0
  638. icdev/tools/compliance/emass/emass_sync.py +826 -0
  639. icdev/tools/compliance/eu_ai_act_classifier.py +194 -0
  640. icdev/tools/compliance/evidence_collector.py +468 -0
  641. icdev/tools/compliance/fairness_assessor.py +316 -0
  642. icdev/tools/compliance/fedramp_assessor.py +1808 -0
  643. icdev/tools/compliance/fedramp_authorization_packager.py +137 -0
  644. icdev/tools/compliance/fedramp_ksi_generator.py +355 -0
  645. icdev/tools/compliance/fedramp_report_generator.py +1128 -0
  646. icdev/tools/compliance/fips199_categorizer.py +881 -0
  647. icdev/tools/compliance/fips200_validator.py +315 -0
  648. icdev/tools/compliance/gao_ai_assessor.py +231 -0
  649. icdev/tools/compliance/gao_evidence_builder.py +308 -0
  650. icdev/tools/compliance/hipaa_assessor.py +78 -0
  651. icdev/tools/compliance/hitrust_assessor.py +49 -0
  652. icdev/tools/compliance/incident_response_plan.py +718 -0
  653. icdev/tools/compliance/iso27001_assessor.py +92 -0
  654. icdev/tools/compliance/iso42001_assessor.py +114 -0
  655. icdev/tools/compliance/ivv_assessor.py +2327 -0
  656. icdev/tools/compliance/ivv_report_generator.py +1662 -0
  657. icdev/tools/compliance/model_card_generator.py +297 -0
  658. icdev/tools/compliance/mosa_assessor.py +117 -0
  659. icdev/tools/compliance/multi_regime_assessor.py +451 -0
  660. icdev/tools/compliance/narrative_generator.py +1013 -0
  661. icdev/tools/compliance/nist_800_207_assessor.py +191 -0
  662. icdev/tools/compliance/nist_ai_600_1_assessor.py +188 -0
  663. icdev/tools/compliance/nist_ai_rmf_assessor.py +110 -0
  664. icdev/tools/compliance/nist_lookup.py +245 -0
  665. icdev/tools/compliance/omb_m25_21_assessor.py +228 -0
  666. icdev/tools/compliance/omb_m26_04_assessor.py +188 -0
  667. icdev/tools/compliance/oscal_catalog_adapter.py +395 -0
  668. icdev/tools/compliance/oscal_generator.py +2170 -0
  669. icdev/tools/compliance/oscal_tools.py +1182 -0
  670. icdev/tools/compliance/owasp_agentic_assessor.py +226 -0
  671. icdev/tools/compliance/owasp_asi_assessor.py +200 -0
  672. icdev/tools/compliance/owasp_llm_assessor.py +244 -0
  673. icdev/tools/compliance/pci_dss_assessor.py +80 -0
  674. icdev/tools/compliance/pi_compliance_tracker.py +1461 -0
  675. icdev/tools/compliance/poam_generator.py +405 -0
  676. icdev/tools/compliance/resolve_marking.py +283 -0
  677. icdev/tools/compliance/sbd_assessor.py +2068 -0
  678. icdev/tools/compliance/sbd_report_generator.py +1236 -0
  679. icdev/tools/compliance/sbom_generator.py +1008 -0
  680. icdev/tools/compliance/siem_config_generator.py +674 -0
  681. icdev/tools/compliance/slsa_attestation_generator.py +490 -0
  682. icdev/tools/compliance/soc2_assessor.py +77 -0
  683. icdev/tools/compliance/ssp_generator.py +573 -0
  684. icdev/tools/compliance/stig_checker.py +727 -0
  685. icdev/tools/compliance/swft_evidence_bundler.py +337 -0
  686. icdev/tools/compliance/system_card_generator.py +309 -0
  687. icdev/tools/compliance/traceability_matrix.py +1281 -0
  688. icdev/tools/compliance/universal_classification_manager.py +1172 -0
  689. icdev/tools/compliance/xacta/__init__.py +2 -0
  690. icdev/tools/compliance/xacta/xacta_client.py +449 -0
  691. icdev/tools/compliance/xacta/xacta_export.py +557 -0
  692. icdev/tools/compliance/xacta/xacta_sync.py +333 -0
  693. icdev/tools/compliance/xai_assessor.py +231 -0
  694. icdev/tools/dashboard/__init__.py +1 -0
  695. icdev/tools/dashboard/api/__init__.py +1 -0
  696. icdev/tools/dashboard/api/_pipeline_state.py +17 -0
  697. icdev/tools/dashboard/api/activity.py +206 -0
  698. icdev/tools/dashboard/api/admin.py +176 -0
  699. icdev/tools/dashboard/api/agents.py +53 -0
  700. icdev/tools/dashboard/api/ai_accountability.py +163 -0
  701. icdev/tools/dashboard/api/ai_transparency.py +198 -0
  702. icdev/tools/dashboard/api/audit.py +58 -0
  703. icdev/tools/dashboard/api/batch.py +666 -0
  704. icdev/tools/dashboard/api/chat.py +241 -0
  705. icdev/tools/dashboard/api/cicd.py +219 -0
  706. icdev/tools/dashboard/api/code_quality.py +223 -0
  707. icdev/tools/dashboard/api/compliance.py +171 -0
  708. icdev/tools/dashboard/api/cpmp.py +915 -0
  709. icdev/tools/dashboard/api/diagrams.py +65 -0
  710. icdev/tools/dashboard/api/events.py +250 -0
  711. icdev/tools/dashboard/api/evidence.py +99 -0
  712. icdev/tools/dashboard/api/fedramp_20x.py +77 -0
  713. icdev/tools/dashboard/api/govcon.py +1095 -0
  714. icdev/tools/dashboard/api/intake.py +1171 -0
  715. icdev/tools/dashboard/api/lineage.py +163 -0
  716. icdev/tools/dashboard/api/metrics.py +155 -0
  717. icdev/tools/dashboard/api/nlq.py +72 -0
  718. icdev/tools/dashboard/api/orchestration.py +472 -0
  719. icdev/tools/dashboard/api/oscal.py +183 -0
  720. icdev/tools/dashboard/api/prod_audit.py +183 -0
  721. icdev/tools/dashboard/api/projects.py +191 -0
  722. icdev/tools/dashboard/api/proposals.py +1084 -0
  723. icdev/tools/dashboard/api/traces.py +363 -0
  724. icdev/tools/dashboard/api/usage.py +234 -0
  725. icdev/tools/dashboard/app.py +1986 -0
  726. icdev/tools/dashboard/auth.py +500 -0
  727. icdev/tools/dashboard/byok.py +245 -0
  728. icdev/tools/dashboard/chat_manager.py +675 -0
  729. icdev/tools/dashboard/config.py +116 -0
  730. icdev/tools/dashboard/diagram_definitions.py +642 -0
  731. icdev/tools/dashboard/nlq_processor.py +323 -0
  732. icdev/tools/dashboard/phase_loader.py +136 -0
  733. icdev/tools/dashboard/sse_manager.py +89 -0
  734. icdev/tools/dashboard/state_tracker.py +267 -0
  735. icdev/tools/dashboard/static/css/style.css +706 -0
  736. icdev/tools/dashboard/static/css/ux.css +2047 -0
  737. icdev/tools/dashboard/static/js/activity.js +322 -0
  738. icdev/tools/dashboard/static/js/api.js +161 -0
  739. icdev/tools/dashboard/static/js/batch.js +814 -0
  740. icdev/tools/dashboard/static/js/charts.js +618 -0
  741. icdev/tools/dashboard/static/js/chat.js +1514 -0
  742. icdev/tools/dashboard/static/js/kanban.js +113 -0
  743. icdev/tools/dashboard/static/js/live.js +569 -0
  744. icdev/tools/dashboard/static/js/mermaid-icdev.js +332 -0
  745. icdev/tools/dashboard/static/js/proposals.js +588 -0
  746. icdev/tools/dashboard/static/js/shortcuts.js +544 -0
  747. icdev/tools/dashboard/static/js/tables.js +652 -0
  748. icdev/tools/dashboard/static/js/tour.js +524 -0
  749. icdev/tools/dashboard/static/js/ux.js +942 -0
  750. icdev/tools/dashboard/templates/404.html +10 -0
  751. icdev/tools/dashboard/templates/activity.html +80 -0
  752. icdev/tools/dashboard/templates/admin/users.html +144 -0
  753. icdev/tools/dashboard/templates/ai_accountability.html +235 -0
  754. icdev/tools/dashboard/templates/ai_transparency.html +263 -0
  755. icdev/tools/dashboard/templates/base.html +104 -0
  756. icdev/tools/dashboard/templates/batch.html +23 -0
  757. icdev/tools/dashboard/templates/chat.html +332 -0
  758. icdev/tools/dashboard/templates/children.html +149 -0
  759. icdev/tools/dashboard/templates/cicd.html +253 -0
  760. icdev/tools/dashboard/templates/code_quality.html +214 -0
  761. icdev/tools/dashboard/templates/cpmp/cor_detail.html +220 -0
  762. icdev/tools/dashboard/templates/cpmp/cor_portal.html +91 -0
  763. icdev/tools/dashboard/templates/cpmp/deliverable_detail.html +197 -0
  764. icdev/tools/dashboard/templates/cpmp/detail.html +578 -0
  765. icdev/tools/dashboard/templates/cpmp/portfolio.html +202 -0
  766. icdev/tools/dashboard/templates/dev_profiles.html +304 -0
  767. icdev/tools/dashboard/templates/diagrams.html +224 -0
  768. icdev/tools/dashboard/templates/events/timeline.html +232 -0
  769. icdev/tools/dashboard/templates/evidence.html +134 -0
  770. icdev/tools/dashboard/templates/fedramp_20x.html +207 -0
  771. icdev/tools/dashboard/templates/gateway.html +244 -0
  772. icdev/tools/dashboard/templates/govcon/capabilities.html +135 -0
  773. icdev/tools/dashboard/templates/govcon/pipeline.html +214 -0
  774. icdev/tools/dashboard/templates/govcon/requirements.html +120 -0
  775. icdev/tools/dashboard/templates/index.html +254 -0
  776. icdev/tools/dashboard/templates/lineage.html +141 -0
  777. icdev/tools/dashboard/templates/login.html +51 -0
  778. icdev/tools/dashboard/templates/monitoring/overview.html +193 -0
  779. icdev/tools/dashboard/templates/orchestration/dashboard.html +545 -0
  780. icdev/tools/dashboard/templates/oscal.html +263 -0
  781. icdev/tools/dashboard/templates/phases.html +150 -0
  782. icdev/tools/dashboard/templates/prod_audit.html +280 -0
  783. icdev/tools/dashboard/templates/profile.html +183 -0
  784. icdev/tools/dashboard/templates/projects/detail.html +583 -0
  785. icdev/tools/dashboard/templates/projects/list.html +47 -0
  786. icdev/tools/dashboard/templates/proposals/detail.html +1253 -0
  787. icdev/tools/dashboard/templates/proposals/list.html +179 -0
  788. icdev/tools/dashboard/templates/proposals/section_detail.html +193 -0
  789. icdev/tools/dashboard/templates/provenance.html +181 -0
  790. icdev/tools/dashboard/templates/query/nlq.html +234 -0
  791. icdev/tools/dashboard/templates/quick_paths.html +69 -0
  792. icdev/tools/dashboard/templates/traces.html +155 -0
  793. icdev/tools/dashboard/templates/translation_detail.html +199 -0
  794. icdev/tools/dashboard/templates/translations.html +162 -0
  795. icdev/tools/dashboard/templates/usage.html +225 -0
  796. icdev/tools/dashboard/templates/wizard.html +539 -0
  797. icdev/tools/dashboard/templates/xai.html +208 -0
  798. icdev/tools/dashboard/ux_helpers.py +962 -0
  799. icdev/tools/dashboard/websocket.py +81 -0
  800. icdev/tools/db/__init__.py +1 -0
  801. icdev/tools/db/backup.py +312 -0
  802. icdev/tools/db/backup_manager.py +832 -0
  803. icdev/tools/db/init_icdev_db.py +5900 -0
  804. icdev/tools/db/migrate.py +178 -0
  805. icdev/tools/db/migration_runner.py +549 -0
  806. icdev/tools/db/migrations/001_baseline/meta.json +9 -0
  807. icdev/tools/db/migrations/001_baseline/up.py +68 -0
  808. icdev/tools/db/migrations/002_memory_enhancements/down.sql +8 -0
  809. icdev/tools/db/migrations/002_memory_enhancements/meta.json +9 -0
  810. icdev/tools/db/migrations/002_memory_enhancements/up.py +118 -0
  811. icdev/tools/db/migrations/003_dev_profiles/meta.json +8 -0
  812. icdev/tools/db/migrations/003_dev_profiles/up.py +93 -0
  813. icdev/tools/db/migrations/004_innovation_engine/down.py +19 -0
  814. icdev/tools/db/migrations/004_innovation_engine/up.py +227 -0
  815. icdev/tools/db/migrations/005_phase_37_ai_security/down.py +19 -0
  816. icdev/tools/db/migrations/005_phase_37_ai_security/up.py +258 -0
  817. icdev/tools/db/migrations/006_phase_36_evolution/down.py +21 -0
  818. icdev/tools/db/migrations/006_phase_36_evolution/up.py +323 -0
  819. icdev/tools/db/migrations/007_phase_38_cloud/down.py +14 -0
  820. icdev/tools/db/migrations/007_phase_38_cloud/up.py +110 -0
  821. icdev/tools/db/migrations/008_phase36_37_integration/up.py +55 -0
  822. icdev/tools/db/migrations/__init__.py +2 -0
  823. icdev/tools/devsecops/__init__.py +2 -0
  824. icdev/tools/devsecops/attestation_manager.py +458 -0
  825. icdev/tools/devsecops/network_segmentation_generator.py +614 -0
  826. icdev/tools/devsecops/pdp_config_generator.py +1256 -0
  827. icdev/tools/devsecops/pipeline_security_generator.py +484 -0
  828. icdev/tools/devsecops/policy_generator.py +653 -0
  829. icdev/tools/devsecops/profile_manager.py +388 -0
  830. icdev/tools/devsecops/service_mesh_generator.py +1073 -0
  831. icdev/tools/devsecops/zta_maturity_scorer.py +368 -0
  832. icdev/tools/devsecops/zta_terraform_generator.py +1303 -0
  833. icdev/tools/dx/__init__.py +3 -0
  834. icdev/tools/dx/companion.py +266 -0
  835. icdev/tools/dx/instruction_generator.py +753 -0
  836. icdev/tools/dx/mcp_config_generator.py +282 -0
  837. icdev/tools/dx/skill_translator.py +425 -0
  838. icdev/tools/dx/tool_detector.py +144 -0
  839. icdev/tools/extensions/__init__.py +21 -0
  840. icdev/tools/extensions/builtins/010_ai_governance_chat.py +277 -0
  841. icdev/tools/extensions/builtins/__init__.py +2 -0
  842. icdev/tools/extensions/extension_manager.py +455 -0
  843. icdev/tools/infra/__init__.py +1 -0
  844. icdev/tools/infra/ansible_generator.py +869 -0
  845. icdev/tools/infra/dockerfile_generator.py +361 -0
  846. icdev/tools/infra/infra_status.py +393 -0
  847. icdev/tools/infra/ironbank_metadata_generator.py +411 -0
  848. icdev/tools/infra/k8s_generator.py +1002 -0
  849. icdev/tools/infra/pipeline_generator.py +832 -0
  850. icdev/tools/infra/rollback.py +400 -0
  851. icdev/tools/infra/terraform_generator.py +1142 -0
  852. icdev/tools/infra/terraform_generator_azure.py +1254 -0
  853. icdev/tools/infra/terraform_generator_gcp.py +953 -0
  854. icdev/tools/infra/terraform_generator_ibm.py +360 -0
  855. icdev/tools/infra/terraform_generator_oci.py +919 -0
  856. icdev/tools/infra/terraform_generator_onprem.py +319 -0
  857. icdev/tools/innovation/__init__.py +8 -0
  858. icdev/tools/innovation/competitive_intel.py +492 -0
  859. icdev/tools/innovation/innovation_manager.py +681 -0
  860. icdev/tools/innovation/introspective_analyzer.py +774 -0
  861. icdev/tools/innovation/register_external_patterns.py +440 -0
  862. icdev/tools/innovation/signal_ranker.py +1038 -0
  863. icdev/tools/innovation/solution_generator.py +697 -0
  864. icdev/tools/innovation/standards_monitor.py +466 -0
  865. icdev/tools/innovation/trend_detector.py +1046 -0
  866. icdev/tools/innovation/triage_engine.py +1149 -0
  867. icdev/tools/innovation/web_scanner.py +894 -0
  868. icdev/tools/installer/__init__.py +1 -0
  869. icdev/tools/installer/compliance_configurator.py +637 -0
  870. icdev/tools/installer/installer.py +1711 -0
  871. icdev/tools/installer/module_registry.py +805 -0
  872. icdev/tools/installer/platform_setup.py +961 -0
  873. icdev/tools/integration/__init__.py +2 -0
  874. icdev/tools/integration/approval_manager.py +561 -0
  875. icdev/tools/integration/doors_exporter.py +627 -0
  876. icdev/tools/integration/gitlab_connector.py +784 -0
  877. icdev/tools/integration/jira_connector.py +774 -0
  878. icdev/tools/integration/servicenow_connector.py +693 -0
  879. icdev/tools/knowledge/__init__.py +1 -0
  880. icdev/tools/knowledge/knowledge_ingest.py +293 -0
  881. icdev/tools/knowledge/pattern_detector.py +693 -0
  882. icdev/tools/knowledge/recommendation_engine.py +461 -0
  883. icdev/tools/knowledge/self_heal_analyzer.py +504 -0
  884. icdev/tools/llm/__init__.py +72 -0
  885. icdev/tools/llm/anthropic_provider.py +170 -0
  886. icdev/tools/llm/azure_openai_provider.py +338 -0
  887. icdev/tools/llm/bedrock_provider.py +315 -0
  888. icdev/tools/llm/embedding_provider.py +438 -0
  889. icdev/tools/llm/gemini_provider.py +381 -0
  890. icdev/tools/llm/ibm_watsonx_provider.py +232 -0
  891. icdev/tools/llm/oci_genai_provider.py +462 -0
  892. icdev/tools/llm/ollama_provider.py +340 -0
  893. icdev/tools/llm/openai_provider.py +225 -0
  894. icdev/tools/llm/provider.py +355 -0
  895. icdev/tools/llm/provider_sdk.py +175 -0
  896. icdev/tools/llm/router.py +780 -0
  897. icdev/tools/llm/vertex_ai_provider.py +374 -0
  898. icdev/tools/maintenance/__init__.py +2 -0
  899. icdev/tools/maintenance/dependency_scanner.py +1030 -0
  900. icdev/tools/maintenance/maintenance_auditor.py +815 -0
  901. icdev/tools/maintenance/remediation_engine.py +966 -0
  902. icdev/tools/maintenance/vulnerability_checker.py +987 -0
  903. icdev/tools/mbse/__init__.py +3 -0
  904. icdev/tools/mbse/des_assessor.py +1186 -0
  905. icdev/tools/mbse/des_report_generator.py +800 -0
  906. icdev/tools/mbse/diagram_extractor.py +811 -0
  907. icdev/tools/mbse/digital_thread.py +1665 -0
  908. icdev/tools/mbse/model_code_generator.py +1122 -0
  909. icdev/tools/mbse/model_control_mapper.py +420 -0
  910. icdev/tools/mbse/pi_model_tracker.py +1093 -0
  911. icdev/tools/mbse/reqif_parser.py +1483 -0
  912. icdev/tools/mbse/sync_engine.py +1805 -0
  913. icdev/tools/mbse/xmi_parser.py +1573 -0
  914. icdev/tools/mcp/__init__.py +1 -0
  915. icdev/tools/mcp/base_server.py +535 -0
  916. icdev/tools/mcp/builder_server.py +725 -0
  917. icdev/tools/mcp/compliance_server.py +1407 -0
  918. icdev/tools/mcp/context_indexer.py +199 -0
  919. icdev/tools/mcp/context_server.py +305 -0
  920. icdev/tools/mcp/core_server.py +679 -0
  921. icdev/tools/mcp/devsecops_server.py +432 -0
  922. icdev/tools/mcp/gap_handlers.py +1079 -0
  923. icdev/tools/mcp/gateway_server.py +339 -0
  924. icdev/tools/mcp/generate_registry.py +623 -0
  925. icdev/tools/mcp/infra_server.py +264 -0
  926. icdev/tools/mcp/innovation_server.py +316 -0
  927. icdev/tools/mcp/integration_server.py +527 -0
  928. icdev/tools/mcp/knowledge_server.py +429 -0
  929. icdev/tools/mcp/maintenance_server.py +248 -0
  930. icdev/tools/mcp/marketplace_server.py +499 -0
  931. icdev/tools/mcp/mbse_server.py +398 -0
  932. icdev/tools/mcp/modernization_server.py +496 -0
  933. icdev/tools/mcp/observability_server.py +354 -0
  934. icdev/tools/mcp/requirements_server.py +415 -0
  935. icdev/tools/mcp/simulation_server.py +468 -0
  936. icdev/tools/mcp/standalone/__init__.py +2 -0
  937. icdev/tools/mcp/standalone/builder.py +59 -0
  938. icdev/tools/mcp/standalone/compliance.py +59 -0
  939. icdev/tools/mcp/standalone/core.py +59 -0
  940. icdev/tools/mcp/standalone/knowledge.py +59 -0
  941. icdev/tools/mcp/standalone/maintenance.py +59 -0
  942. icdev/tools/mcp/supply_chain_server.py +476 -0
  943. icdev/tools/mcp/tool_registry.py +2008 -0
  944. icdev/tools/mcp/unified_server.py +158 -0
  945. icdev/tools/memory/__init__.py +2 -0
  946. icdev/tools/memory/auto_capture.py +347 -0
  947. icdev/tools/memory/embed_memory.py +158 -0
  948. icdev/tools/memory/history_compressor.py +334 -0
  949. icdev/tools/memory/hybrid_search.py +236 -0
  950. icdev/tools/memory/maintenance_cron.py +289 -0
  951. icdev/tools/memory/memory_consolidation.py +444 -0
  952. icdev/tools/memory/memory_db.py +133 -0
  953. icdev/tools/memory/memory_read.py +102 -0
  954. icdev/tools/memory/memory_write.py +222 -0
  955. icdev/tools/memory/semantic_search.py +139 -0
  956. icdev/tools/memory/time_decay.py +435 -0
  957. icdev/tools/modernization/__init__.py +3 -0
  958. icdev/tools/modernization/architecture_extractor.py +734 -0
  959. icdev/tools/modernization/compliance_bridge.py +1499 -0
  960. icdev/tools/modernization/db_migration_planner.py +1385 -0
  961. icdev/tools/modernization/doc_generator.py +1428 -0
  962. icdev/tools/modernization/framework_migrator.py +1525 -0
  963. icdev/tools/modernization/legacy_analyzer.py +1948 -0
  964. icdev/tools/modernization/migration_code_generator.py +1639 -0
  965. icdev/tools/modernization/migration_report_generator.py +1653 -0
  966. icdev/tools/modernization/migration_tracker.py +1726 -0
  967. icdev/tools/modernization/monolith_decomposer.py +1508 -0
  968. icdev/tools/modernization/seven_r_assessor.py +1658 -0
  969. icdev/tools/modernization/strangler_fig_manager.py +1705 -0
  970. icdev/tools/modernization/ui_analyzer.py +771 -0
  971. icdev/tools/modernization/version_migrator.py +1392 -0
  972. icdev/tools/monitor/__init__.py +1 -0
  973. icdev/tools/monitor/alert_correlator.py +495 -0
  974. icdev/tools/monitor/auto_resolver.py +612 -0
  975. icdev/tools/monitor/health_checker.py +509 -0
  976. icdev/tools/monitor/heartbeat_daemon.py +792 -0
  977. icdev/tools/monitor/log_analyzer.py +516 -0
  978. icdev/tools/monitor/metric_collector.py +496 -0
  979. icdev/tools/mosa/__init__.py +10 -0
  980. icdev/tools/mosa/icd_generator.py +370 -0
  981. icdev/tools/mosa/modular_design_analyzer.py +683 -0
  982. icdev/tools/mosa/mosa_code_enforcer.py +349 -0
  983. icdev/tools/mosa/tsp_generator.py +265 -0
  984. icdev/tools/observability/__init__.py +100 -0
  985. icdev/tools/observability/genai_attributes.py +88 -0
  986. icdev/tools/observability/instrumentation.py +140 -0
  987. icdev/tools/observability/mlflow_exporter.py +194 -0
  988. icdev/tools/observability/otel_tracer.py +168 -0
  989. icdev/tools/observability/provenance/__init__.py +3 -0
  990. icdev/tools/observability/provenance/prov_recorder.py +324 -0
  991. icdev/tools/observability/shap/__init__.py +3 -0
  992. icdev/tools/observability/shap/agent_shap.py +275 -0
  993. icdev/tools/observability/sqlite_tracer.py +361 -0
  994. icdev/tools/observability/trace_context.py +205 -0
  995. icdev/tools/observability/tracer.py +230 -0
  996. icdev/tools/orchestration/__init__.py +2 -0
  997. icdev/tools/orchestration/workflow_composer.py +361 -0
  998. icdev/tools/project/__init__.py +1 -0
  999. icdev/tools/project/manifest_loader.py +418 -0
  1000. icdev/tools/project/project_create.py +350 -0
  1001. icdev/tools/project/project_list.py +174 -0
  1002. icdev/tools/project/project_scaffold.py +1715 -0
  1003. icdev/tools/project/project_status.py +479 -0
  1004. icdev/tools/project/session_context_builder.py +757 -0
  1005. icdev/tools/project/validate_manifest.py +55 -0
  1006. icdev/tools/registry/__init__.py +10 -0
  1007. icdev/tools/registry/absorption_engine.py +832 -0
  1008. icdev/tools/registry/capability_evaluator.py +668 -0
  1009. icdev/tools/registry/child_registry.py +617 -0
  1010. icdev/tools/registry/cross_pollinator.py +1065 -0
  1011. icdev/tools/registry/genome_manager.py +671 -0
  1012. icdev/tools/registry/learning_collector.py +912 -0
  1013. icdev/tools/registry/propagation_manager.py +942 -0
  1014. icdev/tools/registry/staging_manager.py +742 -0
  1015. icdev/tools/registry/telemetry_collector.py +423 -0
  1016. icdev/tools/requirements/__init__.py +1 -0
  1017. icdev/tools/requirements/ai_governance_scorer.py +208 -0
  1018. icdev/tools/requirements/boundary_analyzer.py +1293 -0
  1019. icdev/tools/requirements/clarification_engine.py +618 -0
  1020. icdev/tools/requirements/complexity_scorer.py +387 -0
  1021. icdev/tools/requirements/consistency_analyzer.py +803 -0
  1022. icdev/tools/requirements/constitution_manager.py +605 -0
  1023. icdev/tools/requirements/decomposition_engine.py +778 -0
  1024. icdev/tools/requirements/document_extractor.py +1016 -0
  1025. icdev/tools/requirements/elicitation_techniques.py +519 -0
  1026. icdev/tools/requirements/gap_detector.py +271 -0
  1027. icdev/tools/requirements/intake_engine.py +2188 -0
  1028. icdev/tools/requirements/prd_generator.py +847 -0
  1029. icdev/tools/requirements/prd_validator.py +595 -0
  1030. icdev/tools/requirements/readiness_scorer.py +313 -0
  1031. icdev/tools/requirements/spec_organizer.py +1029 -0
  1032. icdev/tools/requirements/spec_quality_checker.py +1097 -0
  1033. icdev/tools/requirements/traceability_builder.py +579 -0
  1034. icdev/tools/resilience/__init__.py +34 -0
  1035. icdev/tools/resilience/circuit_breaker.py +340 -0
  1036. icdev/tools/resilience/correlation.py +150 -0
  1037. icdev/tools/resilience/errors.py +81 -0
  1038. icdev/tools/resilience/retry.py +95 -0
  1039. icdev/tools/schemas/__init__.py +27 -0
  1040. icdev/tools/schemas/chat.py +61 -0
  1041. icdev/tools/schemas/compliance.py +56 -0
  1042. icdev/tools/schemas/core.py +85 -0
  1043. icdev/tools/schemas/innovation.py +37 -0
  1044. icdev/tools/schemas/validation.py +109 -0
  1045. icdev/tools/sdk/__init__.py +3 -0
  1046. icdev/tools/sdk/icdev_client.py +218 -0
  1047. icdev/tools/security/__init__.py +1 -0
  1048. icdev/tools/security/agent_output_validator.py +330 -0
  1049. icdev/tools/security/agent_trust_scorer.py +466 -0
  1050. icdev/tools/security/ai_bom_generator.py +725 -0
  1051. icdev/tools/security/ai_telemetry_logger.py +469 -0
  1052. icdev/tools/security/atlas_red_team.py +543 -0
  1053. icdev/tools/security/code_pattern_scanner.py +378 -0
  1054. icdev/tools/security/confabulation_detector.py +271 -0
  1055. icdev/tools/security/container_scanner.py +491 -0
  1056. icdev/tools/security/dependency_auditor.py +944 -0
  1057. icdev/tools/security/endpoint_security_scanner.py +579 -0
  1058. icdev/tools/security/mcp_tool_authorizer.py +243 -0
  1059. icdev/tools/security/prompt_injection_detector.py +737 -0
  1060. icdev/tools/security/sast_runner.py +948 -0
  1061. icdev/tools/security/secret_detector.py +378 -0
  1062. icdev/tools/security/tool_chain_validator.py +357 -0
  1063. icdev/tools/security/vuln_scanner.py +539 -0
  1064. icdev/tools/simulation/__init__.py +2 -0
  1065. icdev/tools/simulation/coa_generator.py +1552 -0
  1066. icdev/tools/simulation/monte_carlo.py +758 -0
  1067. icdev/tools/simulation/scenario_manager.py +1073 -0
  1068. icdev/tools/simulation/simulation_engine.py +1104 -0
  1069. icdev/tools/supply_chain/__init__.py +2 -0
  1070. icdev/tools/supply_chain/cve_triager.py +705 -0
  1071. icdev/tools/supply_chain/dependency_graph.py +645 -0
  1072. icdev/tools/supply_chain/isa_manager.py +540 -0
  1073. icdev/tools/supply_chain/scrm_assessor.py +546 -0
  1074. icdev/tools/testing/__init__.py +2 -0
  1075. icdev/tools/testing/acceptance_validator.py +411 -0
  1076. icdev/tools/testing/claude_dir_validator.py +831 -0
  1077. icdev/tools/testing/data_types.py +199 -0
  1078. icdev/tools/testing/e2e_runner.py +715 -0
  1079. icdev/tools/testing/fuzz_cli.py +306 -0
  1080. icdev/tools/testing/health_check.py +483 -0
  1081. icdev/tools/testing/platform_check.py +143 -0
  1082. icdev/tools/testing/production_audit.py +1862 -0
  1083. icdev/tools/testing/production_remediate.py +804 -0
  1084. icdev/tools/testing/screenshot_validator.py +539 -0
  1085. icdev/tools/testing/smoke_test.py +283 -0
  1086. icdev/tools/testing/test_agent_models.py +117 -0
  1087. icdev/tools/testing/test_orchestrator.py +957 -0
  1088. icdev/tools/testing/utils.py +229 -0
  1089. icdev/tools/translation/__init__.py +17 -0
  1090. icdev/tools/translation/code_translator.py +550 -0
  1091. icdev/tools/translation/dependency_mapper.py +277 -0
  1092. icdev/tools/translation/feature_map.py +395 -0
  1093. icdev/tools/translation/project_assembler.py +439 -0
  1094. icdev/tools/translation/source_extractor.py +609 -0
  1095. icdev/tools/translation/test_translator.py +333 -0
  1096. icdev/tools/translation/translation_manager.py +582 -0
  1097. icdev/tools/translation/translation_validator.py +662 -0
  1098. icdev/tools/translation/type_checker.py +371 -0
  1099. icdev-1.0.0.dist-info/METADATA +868 -0
  1100. icdev-1.0.0.dist-info/RECORD +1105 -0
  1101. icdev-1.0.0.dist-info/WHEEL +5 -0
  1102. icdev-1.0.0.dist-info/entry_points.txt +9 -0
  1103. icdev-1.0.0.dist-info/licenses/LICENSE +254 -0
  1104. icdev-1.0.0.dist-info/licenses/NOTICE +268 -0
  1105. icdev-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,2852 @@
1
+ #!/usr/bin/env python3
2
+ # CUI // SP-CTI
3
+ # Controlled by: Department of Defense
4
+ # CUI Category: CTI
5
+ # Distribution: D
6
+ # POC: ICDEV System Administrator
7
+ """Child App Generator - generates mini-ICDEV clone applications from blueprints.
8
+
9
+ This is the core engine for ICDEV Phase 19 agentic app generation. Every child
10
+ app includes the full GOTCHA framework, ATLAS workflow, own agents, memory system,
11
+ and CI/CD — everything except the ability to generate new applications.
12
+
13
+ Decision D21: Copy-and-adapt over template library.
14
+ Decision D28: 3-layer grandchild prevention.
15
+ Decision D29: Port offset for child agents.
16
+
17
+ CLI: python tools/builder/child_app_generator.py --blueprint bp.json --project-path /tmp --name my-app --json
18
+ """
19
+
20
+ import argparse
21
+ import json
22
+ import logging
23
+ import os
24
+ import re
25
+ import shutil
26
+ import sqlite3
27
+ import subprocess
28
+ import sys
29
+ import uuid
30
+ from datetime import datetime, timedelta, timezone
31
+ from pathlib import Path
32
+ from typing import Any, Dict, List, Optional, Tuple
33
+ from icdev._paths import get_project_root
34
+
35
+ BASE_DIR = get_project_root()
36
+ # Use centralized DB path resolution (D152 pattern)
37
+ try:
38
+ from icdev.tools.compat.db_utils import get_icdev_db_path
39
+ DB_PATH = get_icdev_db_path()
40
+ except ImportError:
41
+ DB_PATH = BASE_DIR / "data" / "icdev.db"
42
+
43
+ logger = logging.getLogger("icdev.child_app_generator")
44
+
45
+
46
+ # Sister module imports (graceful fallback)
47
+ def _import_sister(module_name, func_name):
48
+ """Lazy import helper for sister modules."""
49
+ try:
50
+ mod = __import__(f"tools.builder.{module_name}", fromlist=[func_name])
51
+ return getattr(mod, func_name)
52
+ except (ImportError, AttributeError):
53
+ return None
54
+
55
+
56
+ try:
57
+ from icdev.tools.audit.audit_logger import log_event as audit_log_event
58
+ except ImportError:
59
+ def audit_log_event(**kwargs):
60
+ logger.debug("audit_logger unavailable — %s", kwargs.get("action", ""))
61
+
62
+
63
+ def _get_child_app_model_config() -> dict:
64
+ """Get model config for child apps from llm_config.yaml or defaults."""
65
+ try:
66
+ from icdev.tools.llm.router import LLMRouter
67
+ router = LLMRouter()
68
+ _p, model_id, _mc = router.get_provider_for_function("child_app")
69
+ if model_id:
70
+ provider = "bedrock" if "anthropic." in model_id else "openai"
71
+ return {"provider": provider, "model_id": model_id}
72
+ except Exception:
73
+ pass
74
+ return {
75
+ "provider": "bedrock",
76
+ "model_id": "anthropic.claude-sonnet-4-5-20250929-v1:0",
77
+ }
78
+
79
+
80
+ # ---------------------------------------------------------------------------
81
+ # Constants
82
+ # ---------------------------------------------------------------------------
83
+
84
+ # ICDEV base ports — used for port remapping
85
+ ICDEV_PORTS = {
86
+ "orchestrator": 8443, "architect": 8444, "builder": 8445,
87
+ "compliance": 8446, "security": 8447, "infrastructure": 8448,
88
+ "knowledge": 8449, "monitor": 8450, "mbse": 8451,
89
+ "modernization": 8452,
90
+ # D-CHILD-1: Enterprise agents
91
+ "requirements_analyst": 8453, "supply_chain": 8454,
92
+ "simulation": 8455, "devsecops_zta": 8457,
93
+ }
94
+
95
+ # D-CHILD-3: Parent-only directories — never copied to child apps
96
+ PARENT_ONLY_DIRS = {
97
+ "tools/govcon", "tools/saas", "tools/creative", "tools/innovation",
98
+ "tools/marketplace", "tools/translation", "tools/gateway", "tools/rfx",
99
+ }
100
+
101
+ # D-CHILD-3: Parent-only Claude Code artifacts — excluded from child inheritance
102
+ PARENT_ONLY_COMMANDS = {"icdev-agentic.md", "icdev-innovate.md", "icdev-translate.md"}
103
+ PARENT_ONLY_SKILLS = {"icdev-innovate", "icdev-market"}
104
+ PARENT_ONLY_E2E = {"saas_portal.md"}
105
+ PARENT_ONLY_TEMPLATES = {"proposals", "cpmp", "govcon", "rfx"}
106
+ PARENT_ONLY_API_MODULES = {"proposals.py", "cpmp.py", "govcon.py"}
107
+ # D-CHILD-10: Parent-only context directories — excluded from bulk context/ copy
108
+ PARENT_ONLY_CONTEXT = {
109
+ "govcon", "marketplace", "translation", "modernization",
110
+ }
111
+ # D-CHILD-10: Parent-only static JS files
112
+ PARENT_ONLY_STATIC_JS = {"proposals.js"}
113
+ # D-CHILD-10: Skill-to-capability mapping — skills excluded when capability is off
114
+ SKILL_CAPABILITY_MAP = {
115
+ "icdev-mbse": "mbse",
116
+ "icdev-modernize": "modernization",
117
+ "icdev-secure": "security",
118
+ "icdev-query": "dashboard",
119
+ }
120
+
121
+ # Files that MUST NOT be copied to child apps (grandchild prevention D28)
122
+ GENERATION_TOOLS = {
123
+ "agentic_fitness.py", "app_blueprint.py", "child_app_generator.py",
124
+ "claude_md_generator.py", "goal_adapter.py", "db_init_generator.py",
125
+ }
126
+
127
+ # Builder tools that ARE safe to copy
128
+ SAFE_BUILDER_TOOLS = {
129
+ "scaffolder.py", "scaffolder_extended.py", "code_generator.py",
130
+ "test_writer.py", "linter.py", "formatter.py", "language_support.py",
131
+ }
132
+
133
+ # Full directory tree for child apps
134
+ DIRECTORY_TREE = [
135
+ "goals",
136
+ "tools/agent", "tools/a2a", "tools/audit", "tools/memory",
137
+ "tools/knowledge", "tools/monitor", "tools/db", "tools/project",
138
+ "tools/testing", "tools/ci/triggers", "tools/ci/workflows",
139
+ "tools/infra", "tools/maintenance", "tools/mcp", "tools/builder",
140
+ "tools/security", # D-EPSEC-7: security is always-on, not conditional
141
+ "tools/llm", "tools/compat", "tools/cli", # D-CHILD-9: fundamental infra
142
+ "args", "context/agentic", "context/compliance", "context/languages",
143
+ "hardprompts/agent", "hardprompts/security", # D-EPSEC-7
144
+ "memory/logs", "data",
145
+ ".claude/commands/e2e", ".tmp",
146
+ "k8s", "docker", "features/steps", "tests",
147
+ ]
148
+
149
+ # Conditional directories — only created when capability is enabled
150
+ CONDITIONAL_DIRS = {
151
+ "compliance": [
152
+ "tools/compliance", "tools/compliance/xacta",
153
+ "tools/compliance/emass", "hardprompts/compliance",
154
+ "context/compliance",
155
+ ],
156
+ # "security" removed — now always-on via DIRECTORY_TREE (D-EPSEC-7)
157
+ "mbse": ["tools/mbse", "context/mbse", "hardprompts/mbse"],
158
+ "dashboard": [
159
+ "tools/dashboard", "tools/dashboard/templates",
160
+ "tools/dashboard/static", "tools/dashboard/api",
161
+ ],
162
+ # D-CHILD-1: Enterprise capability directories
163
+ "ricoas": [
164
+ "tools/requirements", "tools/supply_chain", "tools/simulation",
165
+ "tools/integration", "context/requirements",
166
+ ],
167
+ "devsecops_zta": ["tools/devsecops", "context/devsecops"],
168
+ "observability": [
169
+ "tools/observability", "tools/observability/shap",
170
+ "tools/observability/provenance",
171
+ ],
172
+ "code_intelligence": ["tools/analysis"],
173
+ }
174
+
175
+
176
+ # ---------------------------------------------------------------------------
177
+ # Adaptation Functions
178
+ # ---------------------------------------------------------------------------
179
+
180
+ def _apply_adaptations(content: str, adaptations: List[str], blueprint: dict) -> str:
181
+ """Apply a list of text adaptations to file content."""
182
+ app_name = blueprint["app_name"]
183
+ classification = blueprint.get("classification", "CUI")
184
+
185
+ for adaptation in adaptations:
186
+ if adaptation == "db_rename":
187
+ content = content.replace("icdev.db", f"{app_name}.db")
188
+ content = content.replace("data/icdev.db", f"data/{app_name}.db")
189
+ content = content.replace('"icdev"', f'"{app_name}"')
190
+
191
+ elif adaptation == "port_remap":
192
+ for agent in blueprint.get("agents", []):
193
+ old_port = ICDEV_PORTS.get(agent["name"])
194
+ if old_port:
195
+ content = content.replace(str(old_port), str(agent["port"]))
196
+
197
+ elif adaptation == "app_name_replace":
198
+ # Replace identifiers but preserve CUI header structure
199
+ content = re.sub(
200
+ r'\bICDEV\b', app_name.upper().replace('-', '_'), content)
201
+ content = re.sub(
202
+ r'\bicdev\b', app_name.lower().replace('-', '_'), content)
203
+
204
+ elif adaptation == "bot_identifier_replace":
205
+ bot_id = blueprint.get("cicd_config", {}).get(
206
+ "bot_identifier", f"[{app_name.upper()}-BOT]")
207
+ content = content.replace("[ICDEV-BOT]", bot_id)
208
+
209
+ elif adaptation == "classification_update":
210
+ if classification == "SECRET":
211
+ content = content.replace("CUI // SP-CTI", "SECRET // NOFORN")
212
+ content = content.replace(
213
+ "CUI Category: CTI", "Classification: SECRET")
214
+
215
+ elif adaptation == "impact_level_update":
216
+ impact = blueprint.get("impact_level", "IL4")
217
+ content = re.sub(r'\bIL[2456]\b', impact, content)
218
+
219
+ # Other adaptations: endpoint_remap, agent_filter, goal_filter,
220
+ # selective_copy, tls_cert_path, threshold_adjust are handled
221
+ # at the step level rather than as text replacements.
222
+
223
+ return content
224
+
225
+
226
+ def _copy_and_adapt_file(
227
+ src: Path, dest: Path, adaptations: List[str], blueprint: dict
228
+ ) -> bool:
229
+ """Copy a single file with adaptations applied."""
230
+ try:
231
+ dest.parent.mkdir(parents=True, exist_ok=True)
232
+
233
+ # Binary files: copy directly
234
+ if src.suffix in {
235
+ '.pyc', '.so', '.dll', '.png', '.jpg',
236
+ '.gif', '.ico', '.woff', '.woff2',
237
+ }:
238
+ shutil.copy2(src, dest)
239
+ return True
240
+
241
+ # Text files: read, adapt, write
242
+ try:
243
+ content = src.read_text(encoding="utf-8")
244
+ except UnicodeDecodeError:
245
+ shutil.copy2(src, dest)
246
+ return True
247
+
248
+ adapted = _apply_adaptations(content, adaptations, blueprint)
249
+ dest.write_text(adapted, encoding="utf-8")
250
+ return True
251
+ except Exception as e:
252
+ logger.warning("Failed to copy %s -> %s: %s", src, dest, e)
253
+ return False
254
+
255
+
256
+ def _copy_directory(
257
+ src_dir: Path, dest_dir: Path, adaptations: List[str], blueprint: dict,
258
+ exclude_files: Optional[set] = None,
259
+ skip_subdirs: Optional[set] = None,
260
+ ) -> Tuple[int, int]:
261
+ """Copy a directory tree with adaptations. Returns (copied, skipped).
262
+
263
+ Args:
264
+ skip_subdirs: Set of immediate subdirectory names to skip entirely.
265
+ E.g. {"govcon", "marketplace"} skips context/govcon/*.
266
+ """
267
+ exclude_files = exclude_files or set()
268
+ skip_subdirs = skip_subdirs or set()
269
+ copied = 0
270
+ skipped = 0
271
+
272
+ if not src_dir.exists():
273
+ logger.warning("Source directory does not exist: %s", src_dir)
274
+ return 0, 0
275
+
276
+ for src_file in sorted(src_dir.rglob("*")):
277
+ if not src_file.is_file():
278
+ continue
279
+ if src_file.name in exclude_files:
280
+ logger.debug("Skipping excluded file: %s", src_file.name)
281
+ skipped += 1
282
+ continue
283
+ if src_file.suffix == '.pyc' or '__pycache__' in str(src_file):
284
+ continue
285
+ # D-CHILD-10: Skip files under parent-only subdirectories
286
+ if skip_subdirs:
287
+ rel_parts = src_file.relative_to(src_dir).parts
288
+ if rel_parts and rel_parts[0] in skip_subdirs:
289
+ logger.debug("Skipping parent-only subdir: %s", rel_parts[0])
290
+ skipped += 1
291
+ continue
292
+
293
+ rel = src_file.relative_to(src_dir)
294
+ dest_file = dest_dir / rel
295
+
296
+ if _copy_and_adapt_file(src_file, dest_file, adaptations, blueprint):
297
+ copied += 1
298
+ else:
299
+ skipped += 1
300
+
301
+ return copied, skipped
302
+
303
+
304
+ # ---------------------------------------------------------------------------
305
+ # Step 1: Create Directory Tree
306
+ # ---------------------------------------------------------------------------
307
+
308
+ def step_01_create_directory_tree(child_root: Path, blueprint: dict) -> dict:
309
+ """Step 1: Create the full GOTCHA directory structure."""
310
+ created_dirs = []
311
+ capabilities = blueprint.get("capabilities", {})
312
+
313
+ # Always-on directories
314
+ for dir_path in DIRECTORY_TREE:
315
+ full_path = child_root / dir_path
316
+ full_path.mkdir(parents=True, exist_ok=True)
317
+ created_dirs.append(str(dir_path))
318
+
319
+ # Conditional directories
320
+ for cap_name, dirs in CONDITIONAL_DIRS.items():
321
+ if capabilities.get(cap_name, False):
322
+ for dir_path in dirs:
323
+ full_path = child_root / dir_path
324
+ full_path.mkdir(parents=True, exist_ok=True)
325
+ created_dirs.append(str(dir_path))
326
+
327
+ logger.info("Step 1: Created %d directories", len(created_dirs))
328
+ return {"directories_created": len(created_dirs), "dirs": created_dirs}
329
+
330
+
331
+ # ---------------------------------------------------------------------------
332
+ # Step 2: Copy and Adapt Tools
333
+ # ---------------------------------------------------------------------------
334
+
335
+ def step_02_copy_and_adapt_tools(
336
+ child_root: Path, blueprint: dict, icdev_root: Path
337
+ ) -> dict:
338
+ """Step 2: Copy ICDEV tools to child app with adaptations applied."""
339
+ manifest = blueprint.get("file_manifest", [])
340
+ total_copied = 0
341
+ total_skipped = 0
342
+ results = []
343
+
344
+ for entry in manifest:
345
+ source = entry.get("source", "")
346
+ dest = entry.get("dest", source)
347
+ adaptations = entry.get("adaptations", [])
348
+
349
+ # D-CHILD-3: Skip parent-only directories
350
+ if any(source == d or source.startswith(d + "/") for d in PARENT_ONLY_DIRS):
351
+ total_skipped += 1
352
+ results.append({"source": source, "status": "skipped_parent_only"})
353
+ continue
354
+
355
+ src_path = icdev_root / source
356
+ dest_path = child_root / dest
357
+
358
+ if src_path.is_file():
359
+ # Single file copy
360
+ if _copy_and_adapt_file(src_path, dest_path, adaptations, blueprint):
361
+ total_copied += 1
362
+ results.append({"source": source, "status": "copied"})
363
+ else:
364
+ total_skipped += 1
365
+ results.append({"source": source, "status": "skipped"})
366
+
367
+ elif src_path.is_dir():
368
+ # Directory copy with exclusions
369
+ exclude = set()
370
+
371
+ # For tools/builder/, only copy safe tools
372
+ if source == "tools/builder" or source.startswith("tools/builder"):
373
+ exclude = GENERATION_TOOLS
374
+
375
+ # D-CHILD-10: For context/ bulk copy, skip parent-only subdirs
376
+ skip_subdirs: set = set()
377
+ if source.rstrip("/") == "context":
378
+ skip_subdirs = PARENT_ONLY_CONTEXT
379
+
380
+ copied, skipped = _copy_directory(
381
+ src_path, dest_path, adaptations, blueprint,
382
+ exclude_files=exclude,
383
+ skip_subdirs=skip_subdirs,
384
+ )
385
+ total_copied += copied
386
+ total_skipped += skipped
387
+ results.append({
388
+ "source": source, "status": "copied",
389
+ "files_copied": copied, "files_skipped": skipped,
390
+ })
391
+
392
+ else:
393
+ logger.warning(
394
+ "Source not found: %s (entry=%s)", src_path, source)
395
+ results.append({"source": source, "status": "not_found"})
396
+
397
+ logger.info(
398
+ "Step 2: Copied %d files, skipped %d", total_copied, total_skipped)
399
+ return {
400
+ "files_copied": total_copied,
401
+ "files_skipped": total_skipped,
402
+ "entries": results,
403
+ }
404
+
405
+
406
+ # ---------------------------------------------------------------------------
407
+ # Step 3: Agent Infrastructure
408
+ # ---------------------------------------------------------------------------
409
+
410
+ def _get_agent_skills(agent_name: str, blueprint: dict) -> list:
411
+ """Return skills for an agent based on its role.
412
+
413
+ Priority:
414
+ 1. Blueprint agent 'skills' field (if provided by the blueprint)
415
+ 2. Known ICDEV defaults (orchestrator, architect, builder, etc.)
416
+ 3. Auto-generated from the agent's 'role' description
417
+ """
418
+ # 1. Check blueprint for explicit skills
419
+ for agent in blueprint.get("agents", []):
420
+ if agent.get("name") == agent_name and agent.get("skills"):
421
+ return agent["skills"]
422
+
423
+ # 2. Known ICDEV defaults for standard agents
424
+ skills_map = {
425
+ "orchestrator": [
426
+ {
427
+ "id": "task-dispatch",
428
+ "name": "Task Dispatch",
429
+ "description": "Route tasks to appropriate agents",
430
+ },
431
+ {
432
+ "id": "workflow-manage",
433
+ "name": "Workflow Management",
434
+ "description": "Manage multi-step workflows",
435
+ },
436
+ ],
437
+ "architect": [
438
+ {
439
+ "id": "system-design",
440
+ "name": "System Design",
441
+ "description": "Design system architecture",
442
+ },
443
+ {
444
+ "id": "atlas-workflow",
445
+ "name": "ATLAS Workflow",
446
+ "description": "Execute ATLAS build phases",
447
+ },
448
+ ],
449
+ "builder": [
450
+ {
451
+ "id": "code-generate",
452
+ "name": "Code Generation",
453
+ "description": "Generate code from specs",
454
+ },
455
+ {
456
+ "id": "tdd-cycle",
457
+ "name": "TDD Cycle",
458
+ "description": "RED-GREEN-REFACTOR cycle",
459
+ },
460
+ {
461
+ "id": "scaffold",
462
+ "name": "Scaffold",
463
+ "description": "Scaffold new projects",
464
+ },
465
+ ],
466
+ "compliance": [
467
+ {
468
+ "id": "ssp-generate",
469
+ "name": "SSP Generation",
470
+ "description": "Generate System Security Plans",
471
+ },
472
+ {
473
+ "id": "ato-assess",
474
+ "name": "ATO Assessment",
475
+ "description": "Assess ATO readiness",
476
+ },
477
+ ],
478
+ "security": [
479
+ {
480
+ "id": "sast-scan",
481
+ "name": "SAST Scan",
482
+ "description": "Static analysis security testing",
483
+ },
484
+ {
485
+ "id": "dep-audit",
486
+ "name": "Dependency Audit",
487
+ "description": "Audit dependencies for vulns",
488
+ },
489
+ ],
490
+ "knowledge": [
491
+ {
492
+ "id": "pattern-detect",
493
+ "name": "Pattern Detection",
494
+ "description": "Detect patterns in failures",
495
+ },
496
+ {
497
+ "id": "self-heal",
498
+ "name": "Self Heal",
499
+ "description": "Auto-remediate known issues",
500
+ },
501
+ ],
502
+ "monitor": [
503
+ {
504
+ "id": "log-analyze",
505
+ "name": "Log Analysis",
506
+ "description": "Analyze application logs",
507
+ },
508
+ {
509
+ "id": "health-check",
510
+ "name": "Health Check",
511
+ "description": "Check system health",
512
+ },
513
+ ],
514
+ }
515
+ if agent_name in skills_map:
516
+ return skills_map[agent_name]
517
+
518
+ # 3. Auto-generate skills from the agent's role description
519
+ for agent in blueprint.get("agents", []):
520
+ if agent.get("name") == agent_name:
521
+ role = agent.get("role", agent_name)
522
+ return [
523
+ {
524
+ "id": f"{agent_name}-primary",
525
+ "name": role.split(",")[0].strip().title()
526
+ if role else agent_name.title(),
527
+ "description": role or f"{agent_name} agent capabilities",
528
+ },
529
+ ]
530
+ return []
531
+
532
+
533
+ def _generate_agent_config(
534
+ agents: list, app_name: str, blueprint: dict
535
+ ) -> str:
536
+ """Generate agent_config.yaml content."""
537
+ try:
538
+ import yaml
539
+ config = {
540
+ "application": app_name,
541
+ "classification": blueprint.get("classification", "CUI"),
542
+ "agents": {},
543
+ }
544
+ for agent in agents:
545
+ config["agents"][agent["name"]] = {
546
+ "port": agent["port"],
547
+ "role": agent.get("role", ""),
548
+ "health_endpoint": agent.get(
549
+ "health_endpoint",
550
+ f"https://localhost:{agent['port']}/health",
551
+ ),
552
+ "tls": {
553
+ "enabled": True,
554
+ "cert_path": (
555
+ f"/etc/ssl/certs/{app_name}-{agent['name']}.crt"
556
+ ),
557
+ },
558
+ "model": _get_child_app_model_config(),
559
+ }
560
+ return yaml.dump(config, default_flow_style=False, sort_keys=False)
561
+ except ImportError:
562
+ # Fallback: manual YAML generation
563
+ lines = [
564
+ f"# Agent configuration for {app_name}",
565
+ f"application: {app_name}",
566
+ f"classification: {blueprint.get('classification', 'CUI')}",
567
+ "agents:",
568
+ ]
569
+ for agent in agents:
570
+ lines.append(f" {agent['name']}:")
571
+ lines.append(f" port: {agent['port']}")
572
+ lines.append(f" role: \"{agent.get('role', '')}\"")
573
+ lines.append(
574
+ f" health_endpoint: "
575
+ f"\"https://localhost:{agent['port']}/health\""
576
+ )
577
+ return "\n".join(lines) + "\n"
578
+
579
+
580
+ def _generate_mcp_stubs(
581
+ mcp_dir: Path, agents: list, app_name: str, blueprint: dict
582
+ ) -> int:
583
+ """Generate MCP server stub files for each agent role."""
584
+ classification = blueprint.get("classification", "CUI")
585
+ cui_line = (
586
+ "SECRET // NOFORN" if classification == "SECRET" else "CUI // SP-CTI"
587
+ )
588
+
589
+ stubs_written = 0
590
+ # Map known ICDEV agent roles to MCP server names
591
+ mcp_map = {
592
+ "orchestrator": "core_server",
593
+ "architect": "core_server", # shared
594
+ "builder": "builder_server",
595
+ "compliance": "compliance_server",
596
+ "security": "security_server",
597
+ "knowledge": "knowledge_server",
598
+ "monitor": "monitor_server",
599
+ }
600
+
601
+ written_servers = set()
602
+ for agent in agents:
603
+ # Use known mapping for standard agents, derive name for custom agents
604
+ server_name = mcp_map.get(
605
+ agent["name"], f"{agent['name']}_server")
606
+ if server_name in written_servers:
607
+ continue
608
+ written_servers.add(server_name)
609
+
610
+ stub_content = (
611
+ f'#!/usr/bin/env python3\n'
612
+ f'# {cui_line}\n'
613
+ f'"""MCP Server: {server_name} for {app_name}\n'
614
+ f'\n'
615
+ f'Provides tool-calling interface for Claude Code integration.\n'
616
+ f'Transport: stdio\n'
617
+ f'"""\n'
618
+ f'\n'
619
+ f'import json\n'
620
+ f'import sys\n'
621
+ f'import logging\n'
622
+ f'\n'
623
+ f'logger = logging.getLogger("{app_name}.mcp.{server_name}")\n'
624
+ f'\n'
625
+ f'\n'
626
+ f'def handle_request(request: dict) -> dict:\n'
627
+ f' """Handle incoming MCP JSON-RPC request."""\n'
628
+ f' method = request.get("method", "")\n'
629
+ f' params = request.get("params", {{}})\n'
630
+ f' request_id = request.get("id")\n'
631
+ f'\n'
632
+ f' # Tool dispatch based on method\n'
633
+ f' handlers = {{}} # Populated by tool registration\n'
634
+ f'\n'
635
+ f' handler = handlers.get(method)\n'
636
+ f' if handler:\n'
637
+ f' try:\n'
638
+ f' result = handler(params)\n'
639
+ f' return {{"jsonrpc": "2.0", "id": request_id, "result": result}}\n'
640
+ f' except Exception as e:\n'
641
+ f' return {{\n'
642
+ f' "jsonrpc": "2.0", "id": request_id,\n'
643
+ f' "error": {{"code": -32603, "message": str(e)}},\n'
644
+ f' }}\n'
645
+ f'\n'
646
+ f' return {{\n'
647
+ f' "jsonrpc": "2.0", "id": request_id,\n'
648
+ f' "error": {{"code": -32601, "message": f"Method not found: {{method}}"}},\n'
649
+ f' }}\n'
650
+ f'\n'
651
+ f'\n'
652
+ f'def main():\n'
653
+ f' """Run MCP server in stdio mode."""\n'
654
+ f' logger.info("Starting {server_name} MCP server for {app_name}")\n'
655
+ f' for line in sys.stdin:\n'
656
+ f' line = line.strip()\n'
657
+ f' if not line:\n'
658
+ f' continue\n'
659
+ f' try:\n'
660
+ f' request = json.loads(line)\n'
661
+ f' response = handle_request(request)\n'
662
+ f' sys.stdout.write(json.dumps(response) + "\\n")\n'
663
+ f' sys.stdout.flush()\n'
664
+ f' except json.JSONDecodeError:\n'
665
+ f' error = {{\n'
666
+ f' "jsonrpc": "2.0", "id": None,\n'
667
+ f' "error": {{"code": -32700, "message": "Parse error"}},\n'
668
+ f' }}\n'
669
+ f' sys.stdout.write(json.dumps(error) + "\\n")\n'
670
+ f' sys.stdout.flush()\n'
671
+ f'\n'
672
+ f'\n'
673
+ f'if __name__ == "__main__":\n'
674
+ f' main()\n'
675
+ )
676
+
677
+ stub_path = mcp_dir / f"{server_name}.py"
678
+ stub_path.write_text(stub_content, encoding="utf-8")
679
+ stubs_written += 1
680
+
681
+ return stubs_written
682
+
683
+
684
+ def _generate_dashboard_stub(
685
+ child_root: Path, blueprint: dict
686
+ ) -> bool:
687
+ """Generate a minimal capability-driven Flask dashboard stub.
688
+
689
+ Instead of copying ICDEV's dashboard (which has ICDEV-specific routes),
690
+ generate a minimal Flask app with routes driven by the child app's
691
+ enabled capabilities. The child app developer fills in domain-specific
692
+ logic.
693
+
694
+ The generated dashboard adapts to any app type — multi-agent, single
695
+ service, data pipeline, CLI tool, etc.
696
+ """
697
+ app_name = blueprint["app_name"]
698
+ classification = blueprint.get("classification", "CUI")
699
+ agents = blueprint.get("agents", [])
700
+ capabilities = blueprint.get("capabilities", {})
701
+ demo_mode = blueprint.get("demo_mode", False)
702
+
703
+ cui_line = (
704
+ "SECRET // NOFORN" if classification == "SECRET" else "CUI // SP-CTI"
705
+ )
706
+
707
+ # Demo banner HTML (orange, top + bottom of every page, like CUI banners)
708
+ demo_banner_style = (
709
+ ".demo-banner { background: #e65100; color: #fff; text-align: center; "
710
+ "padding: 6px; font-weight: bold; font-size: 0.85rem; "
711
+ "letter-spacing: 1px; }"
712
+ )
713
+ demo_banner_top = (
714
+ '<div class="demo-banner">'
715
+ "DEMONSTRATION ONLY \\u2014 NOT FOR OPERATIONAL USE"
716
+ "</div>"
717
+ )
718
+
719
+ # Build nav links and page functions based on enabled capabilities
720
+ nav_links = ['"<a href=\\"/\\">Home</a>"']
721
+ page_functions = []
722
+
723
+ # Home page — always present
724
+ page_functions.append(
725
+ ' @app.route("/")\n'
726
+ ' def home():\n'
727
+ ' return _render("Home", "<h2>Welcome</h2>"\n'
728
+ f' "<p>{app_name} dashboard.</p>")\n'
729
+ )
730
+
731
+ # Agents page — only if the app has agents
732
+ if agents:
733
+ nav_links.append('"<a href=\\"/agents\\">Agents</a>"')
734
+ agent_list_items = "".join(
735
+ f'<li><strong>{a["name"]}</strong> (port {a.get("port", "?")}) '
736
+ f'\\u2014 {a.get("role", "")}</li>'
737
+ for a in agents
738
+ )
739
+ page_functions.append(
740
+ ' @app.route("/agents")\n'
741
+ ' def agents_page():\n'
742
+ f' return _render("Agents", "<h2>Agents</h2>"\n'
743
+ f' "<ul>{agent_list_items}</ul>")\n'
744
+ )
745
+
746
+ # Compliance page — only if compliance capability enabled
747
+ if capabilities.get("compliance", False):
748
+ nav_links.append('"<a href=\\"/compliance\\">Compliance</a>"')
749
+ page_functions.append(
750
+ ' @app.route("/compliance")\n'
751
+ ' def compliance_page():\n'
752
+ ' # TODO: Add compliance status from DB\n'
753
+ ' return _render("Compliance",\n'
754
+ ' "<h2>Compliance</h2>"\n'
755
+ ' "<p>Compliance status placeholder.</p>")\n'
756
+ )
757
+
758
+ # Security page — only if security capability enabled
759
+ if capabilities.get("security", False):
760
+ nav_links.append('"<a href=\\"/security\\">Security</a>"')
761
+ page_functions.append(
762
+ ' @app.route("/security")\n'
763
+ ' def security_page():\n'
764
+ ' # TODO: Add security scan results from DB\n'
765
+ ' return _render("Security",\n'
766
+ ' "<h2>Security</h2>"\n'
767
+ ' "<p>Security scan placeholder.</p>")\n'
768
+ )
769
+
770
+ # API health endpoint — always present
771
+ page_functions.append(
772
+ ' @app.route("/api/health")\n'
773
+ ' def api_health():\n'
774
+ f' return jsonify({{"status": "healthy", '
775
+ f'"app": "{app_name}"}})\n'
776
+ )
777
+
778
+ nav_html = "\n ".join(nav_links)
779
+
780
+ stub_content = (
781
+ f'#!/usr/bin/env python3\n'
782
+ f'# {cui_line}\n'
783
+ f'"""{app_name} Dashboard — Flask SSR + HTMX\n'
784
+ f'\n'
785
+ f'Generated by ICDEV child app generator.\n'
786
+ f'Customize routes and pages for your domain.\n'
787
+ f'"""\n'
788
+ f'\n'
789
+ f'import sqlite3\n'
790
+ f'from pathlib import Path\n'
791
+ f'from flask import Flask, jsonify\n'
792
+ f'\n'
793
+ f'DB_PATH = str(Path(__file__).resolve().parent.parent.parent\n'
794
+ f' / "data" / "{app_name}.db")\n'
795
+ f'\n'
796
+ f'\n'
797
+ f'def _layout(title: str, body: str) -> str:\n'
798
+ f' """Wrap page body in HTML layout."""\n'
799
+ f' return (\n'
800
+ f' "<!DOCTYPE html><html><head>"\n'
801
+ f' f"<title>{{title}} — {app_name}</title>"\n'
802
+ f' "<style>"\n'
803
+ f' "body {{ font-family: system-ui; margin: 2rem; "\n'
804
+ f' "background: #1a1a2e; color: #e0e0e0; }}"\n'
805
+ f' "a {{ color: #64b5f6; }} nav {{ margin-bottom: 1.5rem; }}"\n'
806
+ f' "nav a {{ margin-right: 1rem; }}"\n'
807
+ f' ".card {{ background: #16213e; padding: 1rem; "\n'
808
+ f' "border-radius: 8px; margin: 0.5rem 0; }}"\n'
809
+ f' "{demo_banner_style if demo_mode else ""}"\n'
810
+ f' "</style></head><body>"\n'
811
+ f' "{demo_banner_top if demo_mode else ""}"\n'
812
+ f' "<h1>{app_name}</h1>"\n'
813
+ f' "<nav>"\n'
814
+ f' {nav_html}\n'
815
+ f' "</nav>"\n'
816
+ f' f"{{body}}"\n'
817
+ f' "{demo_banner_top if demo_mode else ""}"\n'
818
+ f' "</body></html>"\n'
819
+ f' )\n'
820
+ f'\n'
821
+ f'\n'
822
+ f'def _render(title: str, body: str) -> str:\n'
823
+ f' """Render a page with the standard layout."""\n'
824
+ f' return _layout(title, body)\n'
825
+ f'\n'
826
+ f'\n'
827
+ f'def create_app() -> Flask:\n'
828
+ f' """Create and configure the Flask application."""\n'
829
+ f' app = Flask(__name__)\n'
830
+ f'\n'
831
+ )
832
+
833
+ for fn in page_functions:
834
+ stub_content += fn + "\n"
835
+
836
+ stub_content += (
837
+ f' return app\n'
838
+ f'\n'
839
+ f'\n'
840
+ f'app = create_app()\n'
841
+ f'\n'
842
+ f'\n'
843
+ f'if __name__ == "__main__":\n'
844
+ f' app.run(host="0.0.0.0", port=5000, debug=os.environ.get("FLASK_DEBUG", "false").lower() == "true")\n'
845
+ )
846
+
847
+ dash_dir = child_root / "tools" / "dashboard"
848
+ dash_dir.mkdir(parents=True, exist_ok=True)
849
+ (dash_dir / "app.py").write_text(stub_content, encoding="utf-8")
850
+ return True
851
+
852
+
853
+ def _strip_govcon_from_dashboard(content: str) -> str:
854
+ """Remove GovProposal/CPMP/GovCon imports and registrations from app.py.
855
+
856
+ D-CHILD-3: Children never receive GovProposal functionality.
857
+
858
+ The parent's govcon init block looks like::
859
+
860
+ # D-CHILD-6: ...
861
+ import os as _os
862
+ _GOVCON_ENABLED = _os.environ.get(...)
863
+ _HAS_GOVCON = False
864
+ if _GOVCON_ENABLED:
865
+ try:
866
+ from icdev.tools.dashboard.api.proposals import proposals_api
867
+ ...
868
+ _HAS_GOVCON = True
869
+ except ImportError:
870
+ _HAS_GOVCON = False
871
+
872
+ This function replaces that entire block with a single constant::
873
+
874
+ _HAS_GOVCON = False # D-CHILD-3: GovCon disabled in child apps
875
+ """
876
+ lines = content.split("\n")
877
+ filtered = []
878
+ # --- State: govcon init block removal ---
879
+ in_govcon_init = False
880
+ govcon_init_done = False
881
+ govcon_init_indent = 0
882
+ # --- State: inline route block removal ---
883
+ skip_route_block = False
884
+
885
+ for line in lines:
886
+ stripped = line.strip()
887
+
888
+ # ── Govcon init block: detect start ────────────────────────
889
+ if not govcon_init_done and not in_govcon_init:
890
+ if "_GOVCON_ENABLED" in stripped and "=" in stripped:
891
+ in_govcon_init = True
892
+ # Also retroactively remove the preceding comment + import _os
893
+ # that belong to this block
894
+ while filtered and filtered[-1].strip() in (
895
+ "# D-CHILD-6: GovProposal/CPMP/GovCon conditionally loaded",
896
+ "import os as _os",
897
+ "",
898
+ ):
899
+ filtered.pop()
900
+ # Emit the replacement constant
901
+ filtered.append(
902
+ "_HAS_GOVCON = False "
903
+ "# D-CHILD-3: GovCon disabled in child apps"
904
+ )
905
+ continue
906
+
907
+ # ── Govcon init block: skip body ───────────────────────────
908
+ if in_govcon_init:
909
+ # The block ends when we hit a top-level statement (indent 0)
910
+ # that is NOT part of the if/try/except/else structure and is
911
+ # NOT a blank line.
912
+ if stripped == "":
913
+ continue # skip blank lines inside the block
914
+ indent = len(line) - len(line.lstrip())
915
+ if indent == 0 and stripped not in ("", ) and not stripped.startswith(
916
+ ("if _GOVCON_ENABLED", "_HAS_GOVCON", "else:")
917
+ ):
918
+ # This line is the FIRST line AFTER the govcon init block
919
+ in_govcon_init = False
920
+ govcon_init_done = True
921
+ # fall through to normal processing for this line
922
+ else:
923
+ continue # still inside the govcon init block
924
+
925
+ # ── Skip GovProposal blueprint imports and registrations ───
926
+ if any(mod in stripped for mod in (
927
+ "from tools.dashboard.api.proposals",
928
+ "from tools.dashboard.api.govcon",
929
+ "from tools.dashboard.api.cpmp",
930
+ )):
931
+ continue
932
+
933
+ if any(mod in stripped for mod in (
934
+ "proposals_api", "govcon_api", "cpmp_api",
935
+ )):
936
+ if "register_blueprint" in stripped or "import" in stripped:
937
+ continue
938
+
939
+ # ── Skip GovProposal/CPMP inline route blocks ─────────────
940
+ if any(pat in stripped for pat in (
941
+ 'def proposals_', 'def cpmp_', 'def govcon_',
942
+ '@app.route("/proposals', '@app.route("/cpmp',
943
+ '@app.route("/govcon',
944
+ 'SECTION_TRANSITIONS',
945
+ )):
946
+ skip_route_block = True
947
+ continue
948
+
949
+ # End skip block at next function/route decorator
950
+ if skip_route_block and (stripped.startswith("@app.route") or
951
+ stripped.startswith("def ") or
952
+ stripped.startswith("# ===")):
953
+ if not any(k in stripped for k in ("/proposals", "/cpmp", "/govcon",
954
+ "proposals_", "cpmp_", "govcon_")):
955
+ skip_route_block = False
956
+
957
+ if skip_route_block:
958
+ continue
959
+
960
+ filtered.append(line)
961
+
962
+ return "\n".join(filtered)
963
+
964
+
965
+ def _copy_full_dashboard(
966
+ child_root: Path, blueprint: dict, icdev_root: Path,
967
+ ) -> dict:
968
+ """D-CHILD-4: Copy full 40+ page dashboard to child app.
969
+
970
+ Copies all dashboard components except GovProposal/CPMP/GovCon content.
971
+ Falls back to _generate_dashboard_stub() if source doesn't exist.
972
+ """
973
+ dash_src = icdev_root / "tools" / "dashboard"
974
+ if not dash_src.exists():
975
+ _generate_dashboard_stub(child_root, blueprint)
976
+ return {"mode": "stub", "reason": "dashboard source not found"}
977
+
978
+ dash_dst = child_root / "tools" / "dashboard"
979
+ dash_dst.mkdir(parents=True, exist_ok=True)
980
+ copied = 0
981
+
982
+ # 1. Copy app.py with GovProposal stripped
983
+ app_src = dash_src / "app.py"
984
+ if app_src.exists():
985
+ content = app_src.read_text(encoding="utf-8", errors="replace")
986
+ content = _strip_govcon_from_dashboard(content)
987
+ content = _apply_adaptations(content, ["app_name_replace", "db_rename"], blueprint)
988
+ (dash_dst / "app.py").write_text(content, encoding="utf-8")
989
+ copied += 1
990
+
991
+ # 2. Copy templates (excluding PARENT_ONLY_TEMPLATES)
992
+ tpl_src = dash_src / "templates"
993
+ if tpl_src.exists():
994
+ tpl_dst = dash_dst / "templates"
995
+ tpl_dst.mkdir(parents=True, exist_ok=True)
996
+ for item in sorted(tpl_src.rglob("*")):
997
+ if item.is_file():
998
+ rel = item.relative_to(tpl_src)
999
+ # Skip parent-only template directories
1000
+ if any(rel.parts[0] == d for d in PARENT_ONLY_TEMPLATES
1001
+ if len(rel.parts) > 0):
1002
+ continue
1003
+ dst_file = tpl_dst / rel
1004
+ dst_file.parent.mkdir(parents=True, exist_ok=True)
1005
+ shutil.copy2(str(item), str(dst_file))
1006
+ copied += 1
1007
+
1008
+ # 3. Copy API modules (excluding PARENT_ONLY_API_MODULES)
1009
+ api_src = dash_src / "api"
1010
+ if api_src.exists():
1011
+ api_dst = dash_dst / "api"
1012
+ api_dst.mkdir(parents=True, exist_ok=True)
1013
+ for item in sorted(api_src.glob("*.py")):
1014
+ if item.name in PARENT_ONLY_API_MODULES:
1015
+ continue
1016
+ dst_file = api_dst / item.name
1017
+ content = item.read_text(encoding="utf-8", errors="replace")
1018
+ content = _apply_adaptations(content, ["app_name_replace", "db_rename"], blueprint)
1019
+ dst_file.write_text(content, encoding="utf-8")
1020
+ copied += 1
1021
+
1022
+ # 4. Copy static assets (JS, CSS) — excluding parent-only JS
1023
+ static_src = dash_src / "static"
1024
+ if static_src.exists():
1025
+ c, _ = _copy_directory(
1026
+ static_src, dash_dst / "static", [], blueprint,
1027
+ exclude_files=PARENT_ONLY_STATIC_JS,
1028
+ )
1029
+ copied += c
1030
+
1031
+ # 5. Copy helper modules (auth.py, ux_helpers.py, etc.)
1032
+ for helper in ("auth.py", "ux_helpers.py", "__init__.py"):
1033
+ helper_src = dash_src / helper
1034
+ if helper_src.exists():
1035
+ content = helper_src.read_text(encoding="utf-8", errors="replace")
1036
+ content = _apply_adaptations(
1037
+ content, ["app_name_replace", "db_rename"], blueprint
1038
+ )
1039
+ (dash_dst / helper).write_text(content, encoding="utf-8")
1040
+ copied += 1
1041
+
1042
+ logger.info("Step 3: Full dashboard copied — %d files (GovProposal stripped)", copied)
1043
+ return {"mode": "full", "files_copied": copied}
1044
+
1045
+
1046
+ def step_03_agent_infrastructure(
1047
+ child_root: Path, blueprint: dict, icdev_root: Optional[Path] = None
1048
+ ) -> dict:
1049
+ """Step 3: Generate agent cards, config, and MCP server stubs."""
1050
+ icdev_root = icdev_root or BASE_DIR
1051
+ agents = blueprint.get("agents", [])
1052
+ app_name = blueprint["app_name"]
1053
+ cards_written = 0
1054
+
1055
+ # Generate agent cards
1056
+ agent_cards_dir = child_root / "tools" / "agent" / "cards"
1057
+ agent_cards_dir.mkdir(parents=True, exist_ok=True)
1058
+
1059
+ for agent in agents:
1060
+ card = {
1061
+ "name": f"{app_name}-{agent['name']}",
1062
+ "description": agent.get("role", ""),
1063
+ "url": f"https://localhost:{agent['port']}",
1064
+ "version": "1.0.0",
1065
+ "capabilities": {
1066
+ "streaming": False,
1067
+ "pushNotifications": False,
1068
+ },
1069
+ "skills": _get_agent_skills(agent["name"], blueprint),
1070
+ "authentication": {
1071
+ "schemes": [{"scheme": "mutual-tls"}],
1072
+ },
1073
+ }
1074
+
1075
+ card_path = agent_cards_dir / f"{agent['name']}_card.json"
1076
+ card_path.write_text(
1077
+ json.dumps(card, indent=2), encoding="utf-8")
1078
+ cards_written += 1
1079
+
1080
+ # Generate agent_config.yaml
1081
+ agent_config = _generate_agent_config(agents, app_name, blueprint)
1082
+ config_path = child_root / "args" / "agent_config.yaml"
1083
+ config_path.parent.mkdir(parents=True, exist_ok=True)
1084
+ config_path.write_text(agent_config, encoding="utf-8")
1085
+
1086
+ # Generate MCP server stubs for each agent
1087
+ mcp_dir = child_root / "tools" / "mcp"
1088
+ mcp_dir.mkdir(parents=True, exist_ok=True)
1089
+ mcp_stubs_written = _generate_mcp_stubs(
1090
+ mcp_dir, agents, app_name, blueprint)
1091
+
1092
+ # D-CHILD-4: Full dashboard copy (replaces minimal stub)
1093
+ dashboard_result = {"mode": "none"}
1094
+ capabilities = blueprint.get("capabilities", {})
1095
+ if capabilities.get("dashboard", False):
1096
+ dashboard_result = _copy_full_dashboard(child_root, blueprint, icdev_root)
1097
+
1098
+ logger.info(
1099
+ "Step 3: %d agent cards, 1 config, %d MCP stubs, dashboard=%s",
1100
+ cards_written, mcp_stubs_written, dashboard_result.get("mode"),
1101
+ )
1102
+ return {
1103
+ "agent_cards": cards_written,
1104
+ "mcp_stubs": mcp_stubs_written,
1105
+ "dashboard": dashboard_result,
1106
+ }
1107
+
1108
+
1109
+ # ---------------------------------------------------------------------------
1110
+ # Step 4: Memory Bootstrap
1111
+ # ---------------------------------------------------------------------------
1112
+
1113
+ def step_04_memory_bootstrap(child_root: Path, blueprint: dict) -> dict:
1114
+ """Step 4: Bootstrap memory system with child identity."""
1115
+ app_name = blueprint["app_name"]
1116
+ classification = blueprint.get("classification", "CUI")
1117
+ impact_level = blueprint.get("impact_level", "IL4")
1118
+ agents = blueprint.get("agents", [])
1119
+ architecture = blueprint.get(
1120
+ "fitness_scorecard", {}).get("architecture", "hybrid")
1121
+ parent_cb = blueprint.get("parent_callback", {})
1122
+
1123
+ # Create MEMORY.md with blueprint-enriched content
1124
+ timestamp = datetime.now(tz=timezone.utc).isoformat()
1125
+
1126
+ demo_mode = blueprint.get("demo_mode", False)
1127
+
1128
+ # Extract capabilities list from blueprint
1129
+ capabilities = blueprint.get("capabilities", {})
1130
+ active_caps = [k for k, v in capabilities.items()
1131
+ if v] if isinstance(capabilities, dict) else []
1132
+
1133
+ # Extract description/purpose if provided
1134
+ description = blueprint.get("description", "")
1135
+ purpose = blueprint.get("purpose", "")
1136
+ scorecard = blueprint.get("fitness_scorecard", {})
1137
+ spec = scorecard.get("spec", description or purpose or "")
1138
+
1139
+ memory_content = (
1140
+ f"# MEMORY.md — {app_name}\n"
1141
+ f"\n"
1142
+ f"## Identity\n"
1143
+ f"- **Application:** {app_name}\n"
1144
+ f"- **Generated by:** ICDEV (parent application)\n"
1145
+ f"- **Classification:** {classification}\n"
1146
+ f"- **Impact Level:** {impact_level}\n"
1147
+ f"- **Architecture:** {architecture}\n"
1148
+ )
1149
+
1150
+ if demo_mode:
1151
+ memory_content += (
1152
+ f"- **Mode:** DEMONSTRATION ONLY\n"
1153
+ f" - This is a demo application. Do NOT use for operational or classified data.\n"
1154
+ )
1155
+
1156
+ # Agent details — only if the app has agents
1157
+ if agents:
1158
+ memory_content += f"- **Agents:** {len(agents)}\n"
1159
+ for a in agents:
1160
+ role = a.get("role", "")
1161
+ port = a.get("port", "")
1162
+ if role:
1163
+ memory_content += (
1164
+ f" - **{a['name'].title()}** (port {port}): {role}\n"
1165
+ )
1166
+ else:
1167
+ memory_content += (
1168
+ f" - **{a['name'].title()}** (port {port})\n"
1169
+ )
1170
+
1171
+ memory_content += f"- **Generated at:** {timestamp}\n"
1172
+
1173
+ if spec:
1174
+ memory_content += (
1175
+ f"\n"
1176
+ f"## Purpose\n"
1177
+ f"{spec}\n"
1178
+ )
1179
+
1180
+ if active_caps:
1181
+ memory_content += (
1182
+ f"\n"
1183
+ f"## Capabilities\n"
1184
+ )
1185
+ for cap in active_caps:
1186
+ memory_content += f"- {cap}\n"
1187
+
1188
+ memory_content += (
1189
+ f"\n"
1190
+ f"## User Preferences\n"
1191
+ f"(To be populated during first session)\n"
1192
+ f"\n"
1193
+ f"## Key Facts\n"
1194
+ f"- This is a generated child application of ICDEV\n"
1195
+ f"- This application CANNOT generate child applications "
1196
+ f"(grandchild prevention)\n"
1197
+ f"- ATLAS workflow does not include fitness assessment step\n"
1198
+ )
1199
+ if parent_cb.get("enabled"):
1200
+ memory_content += (
1201
+ f"- Parent ICDEV callback URL: "
1202
+ f"{parent_cb.get('url', 'N/A')}\n"
1203
+ )
1204
+ memory_content += (
1205
+ "\n"
1206
+ "## Session History\n"
1207
+ "(Populated automatically by memory system)\n"
1208
+ )
1209
+
1210
+ memory_path = child_root / "memory" / "MEMORY.md"
1211
+ memory_path.parent.mkdir(parents=True, exist_ok=True)
1212
+ memory_path.write_text(memory_content, encoding="utf-8")
1213
+
1214
+ # Create empty daily log for today
1215
+ today = datetime.now(tz=timezone.utc).strftime("%Y-%m-%d")
1216
+ log_path = child_root / "memory" / "logs" / f"{today}.md"
1217
+ log_path.parent.mkdir(parents=True, exist_ok=True)
1218
+ log_path.write_text(
1219
+ f"# {app_name} — Daily Log {today}\n\n", encoding="utf-8")
1220
+
1221
+ logger.info("Step 4: Memory bootstrapped (MEMORY.md + daily log)")
1222
+ return {"memory_md": str(memory_path), "daily_log": str(log_path)}
1223
+
1224
+
1225
+ # ---------------------------------------------------------------------------
1226
+ # Step 5: DB Init Script
1227
+ # ---------------------------------------------------------------------------
1228
+
1229
+ def step_05_db_init_script(child_root: Path, blueprint: dict) -> dict:
1230
+ """Step 5: Generate standalone DB init script for child app."""
1231
+ # Try to import sister module
1232
+ write_init_script_fn = _import_sister(
1233
+ "db_init_generator", "write_init_script")
1234
+
1235
+ if write_init_script_fn:
1236
+ output_dir = child_root / "tools" / "db"
1237
+ output_dir.mkdir(parents=True, exist_ok=True)
1238
+ script_path = write_init_script_fn(blueprint, output_dir)
1239
+ logger.info("Step 5: DB init script generated at %s", script_path)
1240
+ return {"script_path": str(script_path), "method": "db_init_generator"}
1241
+
1242
+ # Fallback: generate a minimal init script inline
1243
+ app_name = blueprint["app_name"]
1244
+ sanitized = re.sub(
1245
+ r'[^a-z0-9_]', '_', app_name.lower().replace('-', '_'))
1246
+
1247
+ script_content = (
1248
+ '#!/usr/bin/env python3\n'
1249
+ '# CUI // SP-CTI\n'
1250
+ f'"""{app_name} database initialization."""\n'
1251
+ '\n'
1252
+ 'import sqlite3\n'
1253
+ 'import sys\n'
1254
+ 'from pathlib import Path\n'
1255
+ '\n'
1256
+ 'DB_PATH = Path(__file__).resolve().parent.parent.parent / "data"'
1257
+ f' / "{app_name}.db"\n'
1258
+ '\n'
1259
+ '\n'
1260
+ 'def init_db(db_path=None):\n'
1261
+ ' db_path = db_path or str(DB_PATH)\n'
1262
+ ' Path(db_path).parent.mkdir(parents=True, exist_ok=True)\n'
1263
+ ' conn = sqlite3.connect(db_path)\n'
1264
+ ' conn.execute(\n'
1265
+ ' "CREATE TABLE IF NOT EXISTS projects "\n'
1266
+ ' "(id TEXT PRIMARY KEY, name TEXT, status TEXT '\
1267
+ "DEFAULT 'active', \"\n"
1268
+ ' "created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)"\n'
1269
+ ' )\n'
1270
+ ' conn.execute(\n'
1271
+ ' "CREATE TABLE IF NOT EXISTS audit_trail "\n'
1272
+ ' "(id TEXT PRIMARY KEY, event_type TEXT, action TEXT, "\n'
1273
+ ' "created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP)"\n'
1274
+ ' )\n'
1275
+ ' conn.commit()\n'
1276
+ ' tables = [\n'
1277
+ ' r[0] for r in conn.execute(\n'
1278
+ ' "SELECT name FROM sqlite_master WHERE type=\'table\'"\n'
1279
+ ' ).fetchall()\n'
1280
+ ' ]\n'
1281
+ f' print(f"{app_name} database initialized at {{db_path}}")\n'
1282
+ ' print(f"Tables created ({len(tables)}): '
1283
+ '{\\", \\".join(sorted(tables))}")\n'
1284
+ ' conn.close()\n'
1285
+ '\n'
1286
+ '\n'
1287
+ 'if __name__ == "__main__":\n'
1288
+ ' init_db()\n'
1289
+ )
1290
+
1291
+ output_dir = child_root / "tools" / "db"
1292
+ output_dir.mkdir(parents=True, exist_ok=True)
1293
+ script_path = output_dir / f"init_{sanitized}_db.py"
1294
+ script_path.write_text(script_content, encoding="utf-8")
1295
+
1296
+ logger.info(
1297
+ "Step 5: DB init script (fallback) generated at %s", script_path)
1298
+ return {"script_path": str(script_path), "method": "fallback"}
1299
+
1300
+
1301
+ # ---------------------------------------------------------------------------
1302
+ # Step 6: Goals and Hardprompts
1303
+ # ---------------------------------------------------------------------------
1304
+
1305
+ def step_06_goals_and_hardprompts(
1306
+ child_root: Path, blueprint: dict, icdev_root: Path
1307
+ ) -> dict:
1308
+ """Step 6: Copy and adapt goals + hardprompts using goal_adapter."""
1309
+ adapt_goals_fn = _import_sister("goal_adapter", "adapt_goals")
1310
+
1311
+ if adapt_goals_fn:
1312
+ result = adapt_goals_fn(blueprint, icdev_root, child_root)
1313
+ logger.info(
1314
+ "Step 6: Goals adapted — %d goals, %d hardprompts",
1315
+ result.get("goals_copied", 0),
1316
+ result.get("hardprompts_copied", 0),
1317
+ )
1318
+ return result
1319
+
1320
+ # Fallback: copy goals manually
1321
+ goals_config = blueprint.get("goals_config", [])
1322
+ goals_dir = child_root / "goals"
1323
+ goals_dir.mkdir(parents=True, exist_ok=True)
1324
+
1325
+ goal_files = {
1326
+ "build_app": "build_app.md",
1327
+ "tdd_workflow": "tdd_workflow.md",
1328
+ "compliance_workflow": "compliance_workflow.md",
1329
+ "security_scan": "security_scan.md",
1330
+ "deploy_workflow": "deploy_workflow.md",
1331
+ "monitoring": "monitoring.md",
1332
+ "self_healing": "self_healing.md",
1333
+ "agent_management": "agent_management.md",
1334
+ }
1335
+
1336
+ copied = 0
1337
+ for goal_name in goals_config:
1338
+ filename = goal_files.get(goal_name)
1339
+ if filename:
1340
+ src = icdev_root / "goals" / filename
1341
+ if src.exists():
1342
+ shutil.copy2(src, goals_dir / filename)
1343
+ copied += 1
1344
+
1345
+ # Generate minimal manifest
1346
+ manifest_content = f"# Goals Manifest — {blueprint['app_name']}\n\n"
1347
+ manifest_content += "| Goal | File |\n|------|------|\n"
1348
+ for goal_name in goals_config:
1349
+ filename = goal_files.get(goal_name, f"{goal_name}.md")
1350
+ manifest_content += f"| {goal_name} | goals/{filename} |\n"
1351
+ (goals_dir / "manifest.md").write_text(
1352
+ manifest_content, encoding="utf-8")
1353
+
1354
+ logger.info("Step 6: Goals copied (fallback) — %d goals", copied)
1355
+ return {"goals_copied": copied, "method": "fallback"}
1356
+
1357
+
1358
+ # ============================================================
1359
+ # STEP 7: Args + Context
1360
+ # ============================================================
1361
+
1362
+
1363
+ def step_07_args_and_context(child_root: Path, blueprint: dict, icdev_root: Path) -> dict:
1364
+ """Step 7: Copy and adapt args/ and context/ configuration files."""
1365
+ blueprint["app_name"]
1366
+ capabilities = blueprint.get("capabilities", {})
1367
+ copied = 0
1368
+
1369
+ # --- Args files ---
1370
+ args_dir = child_root / "args"
1371
+ args_dir.mkdir(parents=True, exist_ok=True)
1372
+
1373
+ args_files = [
1374
+ ("args/project_defaults.yaml", ["app_name_replace", "port_remap"]),
1375
+ ("args/monitoring_config.yaml", ["endpoint_remap", "app_name_replace"]),
1376
+ # D-EPSEC-7: Security config always copied (not conditional on compliance)
1377
+ ("args/security_gates.yaml", []),
1378
+ ("args/endpoint_security_config.yaml", []),
1379
+ ("args/code_pattern_config.yaml", []),
1380
+ ]
1381
+ if capabilities.get("compliance"):
1382
+ args_files.append(("args/cui_markings.yaml", ["classification_update"]))
1383
+
1384
+ # D-CHILD-1: Enterprise capability args files
1385
+ if capabilities.get("ricoas"):
1386
+ args_files.append(("args/ricoas_config.yaml", []))
1387
+ if capabilities.get("devsecops_zta"):
1388
+ args_files.append(("args/devsecops_config.yaml", []))
1389
+ args_files.append(("args/zta_config.yaml", []))
1390
+ if capabilities.get("ai_security"):
1391
+ args_files.append(("args/owasp_agentic_config.yaml", []))
1392
+ if capabilities.get("observability"):
1393
+ args_files.append(("args/observability_tracing_config.yaml", []))
1394
+ if capabilities.get("code_intelligence"):
1395
+ args_files.append(("args/code_quality_config.yaml", []))
1396
+ if capabilities.get("ai_governance"):
1397
+ args_files.append(("args/ai_governance_config.yaml", []))
1398
+
1399
+ for rel_path, adaptations in args_files:
1400
+ src = icdev_root / rel_path
1401
+ dest = child_root / rel_path
1402
+ if src.exists():
1403
+ if _copy_and_adapt_file(src, dest, adaptations, blueprint):
1404
+ copied += 1
1405
+ else:
1406
+ logger.debug("Args file not found: %s", src)
1407
+
1408
+ # --- Context files ---
1409
+ ctx_src = icdev_root / "context"
1410
+ ctx_dest = child_root / "context"
1411
+
1412
+ # Always copy: context/languages/
1413
+ lang_src = ctx_src / "languages"
1414
+ if lang_src.exists():
1415
+ c, _ = _copy_directory(lang_src, ctx_dest / "languages", [], blueprint)
1416
+ copied += c
1417
+
1418
+ # Copy context/agentic/ (without fitness rubric — ICDEV-only)
1419
+ agentic_src = ctx_src / "agentic"
1420
+ if agentic_src.exists():
1421
+ c, _ = _copy_directory(
1422
+ agentic_src, ctx_dest / "agentic", [], blueprint,
1423
+ exclude_files={"fitness_rubric.md"})
1424
+ copied += c
1425
+
1426
+ # Conditional: context/compliance/
1427
+ if capabilities.get("compliance"):
1428
+ comp_src = ctx_src / "compliance"
1429
+ if comp_src.exists():
1430
+ c, _ = _copy_directory(
1431
+ comp_src, ctx_dest / "compliance",
1432
+ ["classification_update"], blueprint)
1433
+ copied += c
1434
+
1435
+ # Conditional: context/mbse/
1436
+ if capabilities.get("mbse"):
1437
+ mbse_src = ctx_src / "mbse"
1438
+ if mbse_src.exists():
1439
+ c, _ = _copy_directory(mbse_src, ctx_dest / "mbse", [], blueprint)
1440
+ copied += c
1441
+
1442
+ # --- DevSecOps/ZTA inheritance (D122) ---
1443
+ # When parent project has a DevSecOps profile or ZTA is active,
1444
+ # copy devsecops configs and tools to child app
1445
+ devsecops_profile = blueprint.get("devsecops_profile") or {}
1446
+ zta_active = blueprint.get("zta_active", False) or devsecops_profile.get("zta_enabled", False)
1447
+
1448
+ if devsecops_profile or zta_active:
1449
+ # Copy DevSecOps config files
1450
+ for cfg in ("args/devsecops_config.yaml", "args/zta_config.yaml"):
1451
+ cfg_src = icdev_root / cfg
1452
+ cfg_dest = child_root / cfg
1453
+ if cfg_src.exists():
1454
+ if _copy_and_adapt_file(cfg_src, cfg_dest, [], blueprint):
1455
+ copied += 1
1456
+
1457
+ # Copy DevSecOps tools directory
1458
+ devsecops_src = icdev_root / "tools" / "devsecops"
1459
+ if devsecops_src.exists():
1460
+ c, _ = _copy_directory(
1461
+ devsecops_src, child_root / "tools" / "devsecops",
1462
+ ["app_name_replace"], blueprint)
1463
+ copied += c
1464
+
1465
+ # Copy NIST 800-207 compliance catalog + crosswalk
1466
+ for zta_file in ("context/compliance/nist_800_207_zta.json",
1467
+ "context/compliance/nist_800_207_crosswalk.json"):
1468
+ zta_src = icdev_root / zta_file
1469
+ zta_dest = child_root / zta_file
1470
+ if zta_src.exists():
1471
+ if _copy_and_adapt_file(zta_src, zta_dest, [], blueprint):
1472
+ copied += 1
1473
+
1474
+ # Copy NIST 800-207 assessor
1475
+ assessor_src = icdev_root / "tools" / "compliance" / "nist_800_207_assessor.py"
1476
+ assessor_dest = child_root / "tools" / "compliance" / "nist_800_207_assessor.py"
1477
+ if assessor_src.exists():
1478
+ if _copy_and_adapt_file(assessor_src, assessor_dest, ["app_name_replace"], blueprint):
1479
+ copied += 1
1480
+
1481
+ logger.info("Step 7: DevSecOps/ZTA inheritance applied (%s profile, ZTA=%s)",
1482
+ devsecops_profile.get("maturity_level", "detected"), zta_active)
1483
+
1484
+ # --- MOSA inheritance (D127) ---
1485
+ # When parent project is DoD/IC with MOSA enabled, copy MOSA config,
1486
+ # tools, and compliance artifacts to child app
1487
+ mosa_enabled = blueprint.get("mosa_enabled", False)
1488
+ if not mosa_enabled:
1489
+ # Auto-detect from impact level or customer org
1490
+ il = blueprint.get("impact_level", "").upper()
1491
+ org = (blueprint.get("customer_org") or "").lower()
1492
+ if il in ("IL4", "IL5", "IL6") or any(k in org for k in ["dod", "defense", "military"]):
1493
+ mosa_enabled = True
1494
+
1495
+ if mosa_enabled:
1496
+ # Copy MOSA config
1497
+ mosa_cfg_src = icdev_root / "args" / "mosa_config.yaml"
1498
+ mosa_cfg_dest = child_root / "args" / "mosa_config.yaml"
1499
+ if mosa_cfg_src.exists():
1500
+ if _copy_and_adapt_file(mosa_cfg_src, mosa_cfg_dest, [], blueprint):
1501
+ copied += 1
1502
+
1503
+ # Copy tools/mosa/ package
1504
+ mosa_tools_src = icdev_root / "tools" / "mosa"
1505
+ if mosa_tools_src.exists():
1506
+ c, _ = _copy_directory(mosa_tools_src, child_root / "tools" / "mosa",
1507
+ ["app_name_replace"], blueprint)
1508
+ copied += c
1509
+
1510
+ # Copy MOSA catalog and crosswalk
1511
+ for mosa_file in ("mosa_framework.json", "mosa_crosswalk.json"):
1512
+ src = icdev_root / "context" / "compliance" / mosa_file
1513
+ dest = child_root / "context" / "compliance" / mosa_file
1514
+ if src.exists():
1515
+ if _copy_and_adapt_file(src, dest, [], blueprint):
1516
+ copied += 1
1517
+
1518
+ # Copy MOSA assessor
1519
+ assessor_src = icdev_root / "tools" / "compliance" / "mosa_assessor.py"
1520
+ assessor_dest = child_root / "tools" / "compliance" / "mosa_assessor.py"
1521
+ if assessor_src.exists():
1522
+ if _copy_and_adapt_file(assessor_src, assessor_dest, ["app_name_replace"], blueprint):
1523
+ copied += 1
1524
+
1525
+ logger.info("Step 7: MOSA inheritance applied (DoD MOSA enabled)")
1526
+
1527
+ logger.info("Step 7: Copied %d args/context files", copied)
1528
+ return {"files_copied": copied}
1529
+
1530
+
1531
+ # ============================================================
1532
+ # STEP 8: A2A Callback Client
1533
+ # ============================================================
1534
+
1535
+
1536
+ def step_08_a2a_callback_client(child_root: Path, blueprint: dict) -> dict:
1537
+ """Step 8: Generate A2A callback client for parent ICDEV communication."""
1538
+ app_name = blueprint["app_name"]
1539
+ parent_cb = blueprint.get("parent_callback", {})
1540
+ classification = blueprint.get("classification", "CUI")
1541
+ cui_line = "SECRET // NOFORN" if classification == "SECRET" else "CUI // SP-CTI"
1542
+
1543
+ default_url = parent_cb.get("url", "")
1544
+ auth_method = parent_cb.get("auth", "none")
1545
+
1546
+ client_content = f'''#!/usr/bin/env python3
1547
+ # {cui_line}
1548
+ # Controlled by: Department of Defense
1549
+ # CUI Category: CTI
1550
+ """A2A Callback Client — calls parent ICDEV for capabilities not included locally.
1551
+
1552
+ This child application ({app_name}) can request services from its parent ICDEV
1553
+ instance using the A2A protocol (JSON-RPC 2.0).
1554
+
1555
+ Excluded capabilities (must call parent for):
1556
+ - Application generation (agentic fitness, blueprint, scaffolding)
1557
+ - Application modernization (7R assessment, migration)
1558
+
1559
+ Environment variable: ICDEV_PARENT_CALLBACK_URL
1560
+ """
1561
+
1562
+ import json
1563
+ import logging
1564
+ import os
1565
+ import uuid
1566
+ from urllib.error import HTTPError, URLError
1567
+ from urllib.request import Request, urlopen
1568
+
1569
+ PARENT_URL = os.environ.get("ICDEV_PARENT_CALLBACK_URL", "{default_url}")
1570
+ AUTH_METHOD = "{auth_method}"
1571
+
1572
+ logger = logging.getLogger("{app_name}.a2a_callback")
1573
+
1574
+
1575
+ def call_parent(method: str, params: dict = None, timeout: int = 30) -> dict:
1576
+ """Send JSON-RPC 2.0 request to parent ICDEV.
1577
+
1578
+ Args:
1579
+ method: The RPC method name (e.g. "modernization.analyze_legacy").
1580
+ params: Optional parameters dict.
1581
+ timeout: Request timeout in seconds.
1582
+
1583
+ Returns:
1584
+ Response result dict, or error dict on failure.
1585
+ """
1586
+ if not PARENT_URL:
1587
+ return {{"error": "ICDEV_PARENT_CALLBACK_URL not configured"}}
1588
+
1589
+ request_id = str(uuid.uuid4())
1590
+ payload = {{
1591
+ "jsonrpc": "2.0",
1592
+ "id": request_id,
1593
+ "method": method,
1594
+ "params": params or {{}},
1595
+ }}
1596
+
1597
+ headers = {{"Content-Type": "application/json"}}
1598
+ if AUTH_METHOD == "mtls":
1599
+ # mTLS handled at transport level; no additional auth header needed
1600
+ pass
1601
+ elif AUTH_METHOD == "bearer":
1602
+ token = os.environ.get("ICDEV_PARENT_AUTH_TOKEN", "")
1603
+ if token:
1604
+ headers["Authorization"] = f"Bearer {{token}}"
1605
+
1606
+ try:
1607
+ req = Request(
1608
+ PARENT_URL,
1609
+ data=json.dumps(payload).encode("utf-8"),
1610
+ headers=headers,
1611
+ method="POST",
1612
+ )
1613
+ with urlopen(req, timeout=timeout) as resp:
1614
+ body = json.loads(resp.read().decode("utf-8"))
1615
+ if "error" in body:
1616
+ logger.warning("Parent returned error: %s", body["error"])
1617
+ return {{"error": body["error"]}}
1618
+ return body.get("result", {{}})
1619
+ except HTTPError as e:
1620
+ logger.error("HTTP error calling parent: %s %s", e.code, e.reason)
1621
+ return {{"error": f"HTTP {{e.code}}: {{e.reason}}"}}
1622
+ except URLError as e:
1623
+ logger.error("Connection error calling parent: %s", e.reason)
1624
+ return {{"error": f"Connection failed: {{e.reason}}"}}
1625
+ except Exception as e:
1626
+ logger.error("Unexpected error calling parent: %s", e)
1627
+ return {{"error": str(e)}}
1628
+
1629
+
1630
+ def check_health() -> bool:
1631
+ """Check if parent ICDEV is reachable."""
1632
+ if not PARENT_URL:
1633
+ return False
1634
+ try:
1635
+ health_url = PARENT_URL.rstrip("/").rsplit("/", 1)[0] + "/health"
1636
+ req = Request(health_url, method="GET")
1637
+ with urlopen(req, timeout=5) as resp:
1638
+ return resp.status == 200
1639
+ except Exception:
1640
+ return False
1641
+
1642
+
1643
+ def list_parent_capabilities() -> list:
1644
+ """Query parent for available capabilities."""
1645
+ result = call_parent("system.list_methods")
1646
+ if "error" in result:
1647
+ return []
1648
+ return result.get("methods", [])
1649
+
1650
+
1651
+ if __name__ == "__main__":
1652
+ import sys
1653
+ if "--health" in sys.argv:
1654
+ ok = check_health()
1655
+ print(f"Parent health: {{'ok' if ok else 'unreachable'}}")
1656
+ sys.exit(0 if ok else 1)
1657
+ caps = list_parent_capabilities()
1658
+ print(f"Parent capabilities: {{len(caps)}}")
1659
+ for cap in caps:
1660
+ print(f" - {{cap}}")
1661
+ '''
1662
+
1663
+ client_path = child_root / "tools" / "a2a" / "icdev_callback_client.py"
1664
+ client_path.parent.mkdir(parents=True, exist_ok=True)
1665
+ client_path.write_text(client_content, encoding="utf-8")
1666
+
1667
+ logger.info("Step 8: A2A callback client generated (parent=%s)",
1668
+ "enabled" if parent_cb.get("enabled") else "disabled")
1669
+ return {
1670
+ "client_path": str(client_path),
1671
+ "parent_enabled": parent_cb.get("enabled", False),
1672
+ "parent_url": default_url,
1673
+ }
1674
+
1675
+
1676
+ # ============================================================
1677
+ # STEP 9: CI/CD Setup
1678
+ # ============================================================
1679
+
1680
+
1681
+ def step_09_cicd_setup(child_root: Path, blueprint: dict, icdev_root: Path) -> dict:
1682
+ """Step 9: Copy CI/CD tools and Claude Code commands."""
1683
+ blueprint["app_name"]
1684
+ copied = 0
1685
+
1686
+ # Copy tools/ci/
1687
+ ci_src = icdev_root / "tools" / "ci"
1688
+ ci_dest = child_root / "tools" / "ci"
1689
+ if ci_src.exists():
1690
+ c, _ = _copy_directory(
1691
+ ci_src, ci_dest,
1692
+ ["bot_identifier_replace", "app_name_replace"], blueprint)
1693
+ copied += c
1694
+
1695
+ # NOTE: .claude/commands/ is handled by step_09c_claude_code_config()
1696
+ # with proper PARENT_ONLY_COMMANDS and PARENT_ONLY_E2E filtering.
1697
+
1698
+ # Generate .gitignore
1699
+ gitignore_content = """# Python
1700
+ __pycache__/
1701
+ *.py[cod]
1702
+ *.egg-info/
1703
+ dist/
1704
+ build/
1705
+ .eggs/
1706
+
1707
+ # Environment
1708
+ .env
1709
+ .venv/
1710
+ env/
1711
+ venv/
1712
+
1713
+ # Data
1714
+ data/*.db
1715
+ data/*.db-journal
1716
+
1717
+ # IDE
1718
+ .idea/
1719
+ .vscode/
1720
+ *.swp
1721
+ *.swo
1722
+
1723
+ # Temp
1724
+ .tmp/
1725
+ *.log
1726
+
1727
+ # OS
1728
+ .DS_Store
1729
+ Thumbs.db
1730
+ """
1731
+ gitignore_path = child_root / ".gitignore"
1732
+ gitignore_path.write_text(gitignore_content, encoding="utf-8")
1733
+ copied += 1
1734
+
1735
+ # Generate requirements.txt
1736
+ requirements = [
1737
+ "pyyaml>=6.0", "jinja2>=3.1", "flask>=3.0",
1738
+ "pytest>=8.0", "pytest-cov>=5.0", "behave>=1.2",
1739
+ "requests>=2.31", "boto3>=1.34",
1740
+ "cyclonedx-bom>=4.0", "bandit>=1.7",
1741
+ "pip-audit>=2.7", "detect-secrets>=1.4",
1742
+ ]
1743
+ if blueprint.get("capabilities", {}).get("mbse"):
1744
+ requirements.append("# MBSE: no additional deps (stdlib xml.etree)")
1745
+ req_path = child_root / "requirements.txt"
1746
+ req_path.write_text("\n".join(requirements) + "\n", encoding="utf-8")
1747
+ copied += 1
1748
+
1749
+ logger.info("Step 9: CI/CD setup — %d files copied", copied)
1750
+ return {"files_copied": copied}
1751
+
1752
+
1753
+ # ============================================================
1754
+ # STEP 9b: License Files
1755
+ # ============================================================
1756
+
1757
+
1758
+ def _copy_license_files(
1759
+ child_root: Path, blueprint: dict, icdev_root: Path
1760
+ ) -> dict:
1761
+ """Copy ICDEV license validator (and optionally generator) to child app.
1762
+
1763
+ For demo apps, also auto-generates a 30-day trial license file.
1764
+
1765
+ Args:
1766
+ child_root: Root directory of the child app.
1767
+ blueprint: Blueprint dict.
1768
+ icdev_root: ICDEV project root.
1769
+
1770
+ Returns:
1771
+ Dict with files copied and license info.
1772
+ """
1773
+ app_name = blueprint["app_name"]
1774
+ demo_mode = blueprint.get("demo_mode", False)
1775
+ files_copied = []
1776
+
1777
+ # Create licensing directory in child app
1778
+ lic_dir = child_root / "tools" / "saas" / "licensing"
1779
+ lic_dir.mkdir(parents=True, exist_ok=True)
1780
+
1781
+ # Create __init__.py files for the package path
1782
+ for pkg_dir in [
1783
+ child_root / "tools" / "saas",
1784
+ lic_dir,
1785
+ ]:
1786
+ init_file = pkg_dir / "__init__.py"
1787
+ if not init_file.exists():
1788
+ init_file.write_text("", encoding="utf-8")
1789
+
1790
+ # Always copy license_validator.py
1791
+ validator_src = icdev_root / "tools" / "saas" / "licensing" / "license_validator.py"
1792
+ if validator_src.exists():
1793
+ _copy_and_adapt_file(
1794
+ validator_src, lic_dir / "license_validator.py",
1795
+ ["app_name_replace"], blueprint
1796
+ )
1797
+ files_copied.append("license_validator.py")
1798
+
1799
+ # Demo: also copy generator + create trial license
1800
+ license_info = None
1801
+ if demo_mode:
1802
+ gen_src = icdev_root / "tools" / "saas" / "licensing" / "license_generator.py"
1803
+ if gen_src.exists():
1804
+ _copy_and_adapt_file(
1805
+ gen_src, lic_dir / "license_generator.py",
1806
+ ["app_name_replace"], blueprint
1807
+ )
1808
+ files_copied.append("license_generator.py")
1809
+
1810
+ # Auto-generate 30-day demo license
1811
+ expires_at = (
1812
+ datetime.now(tz=timezone.utc) + timedelta(days=30)
1813
+ ).isoformat()
1814
+ license_info = {
1815
+ "license_id": f"demo-{uuid.uuid4().hex[:12]}",
1816
+ "customer": f"{app_name}-demo",
1817
+ "tier": "starter",
1818
+ "max_projects": 5,
1819
+ "max_users": 3,
1820
+ "allowed_il_levels": ["IL2"],
1821
+ "issued_at": datetime.now(tz=timezone.utc).isoformat(),
1822
+ "expires_at": expires_at,
1823
+ "signature": "",
1824
+ "demo": True,
1825
+ }
1826
+ data_dir = child_root / "data"
1827
+ data_dir.mkdir(parents=True, exist_ok=True)
1828
+ lic_path = data_dir / "license.json"
1829
+ lic_path.write_text(
1830
+ json.dumps(license_info, indent=2), encoding="utf-8"
1831
+ )
1832
+ files_copied.append("data/license.json")
1833
+
1834
+ # D-CHILD-5: AGPL-3.0 license for government deliveries
1835
+ license_type = blueprint.get("license", "AGPL-3.0")
1836
+ if license_type == "AGPL-3.0":
1837
+ agpl_text = (
1838
+ f"GNU AFFERO GENERAL PUBLIC LICENSE\n"
1839
+ f"Version 3, 19 November 2007\n\n"
1840
+ f"Copyright (C) {datetime.now(tz=timezone.utc).year} "
1841
+ f"{blueprint.get('customer_org', 'ICDEV Enterprise Delivery')}\n\n"
1842
+ f"This program is free software: you can redistribute it and/or modify\n"
1843
+ f"it under the terms of the GNU Affero General Public License as\n"
1844
+ f"published by the Free Software Foundation, either version 3 of the\n"
1845
+ f"License, or (at your option) any later version.\n\n"
1846
+ f"This program is distributed in the hope that it will be useful,\n"
1847
+ f"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
1848
+ f"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
1849
+ f"GNU Affero General Public License for more details.\n\n"
1850
+ f"You should have received a copy of the GNU Affero General Public\n"
1851
+ f"License along with this program. If not, see\n"
1852
+ f"<https://www.gnu.org/licenses/>.\n\n"
1853
+ f"---\n"
1854
+ f"Application: {app_name}\n"
1855
+ f"Generated by: ICDEV Enterprise Delivery (D374)\n"
1856
+ f"License grants free internal use for government operations.\n"
1857
+ f"Network use (SaaS) requires AGPL-3.0 source disclosure.\n"
1858
+ )
1859
+ lic_path = child_root / "LICENSE"
1860
+ lic_path.write_text(agpl_text, encoding="utf-8")
1861
+ files_copied.append("LICENSE (AGPL-3.0)")
1862
+
1863
+ logger.info(
1864
+ "Step 9b: License files copied: %s (demo=%s, license=%s)",
1865
+ files_copied, demo_mode, license_type,
1866
+ )
1867
+ return {
1868
+ "files_copied": files_copied,
1869
+ "demo_mode": demo_mode,
1870
+ "license_info": license_info,
1871
+ "license_type": license_type,
1872
+ }
1873
+
1874
+
1875
+ # ============================================================
1876
+ # STEP 9c: Claude Code Configuration Inheritance (D-CHILD-2)
1877
+ # ============================================================
1878
+
1879
+
1880
+ def step_09c_claude_code_config(
1881
+ child_root: Path, blueprint: dict, icdev_root: Path,
1882
+ ) -> dict:
1883
+ """Step 9c: Copy .claude/ directory artifacts from parent to child.
1884
+
1885
+ D-CHILD-2: .claude/ is a first-class generation artifact.
1886
+ D-CHILD-3: PARENT_ONLY_COMMANDS/SKILLS/E2E are excluded.
1887
+ """
1888
+ files_copied: List[str] = []
1889
+ files_skipped: List[str] = []
1890
+ claude_src = icdev_root / ".claude"
1891
+
1892
+ if not claude_src.exists():
1893
+ logger.info("Step 9c: No .claude directory found in ICDEV root — skipping")
1894
+ return {"files_copied": [], "files_skipped": [], "skipped": True}
1895
+
1896
+ claude_dst = child_root / ".claude"
1897
+
1898
+ # --- Hooks (copy all from .claude/hooks/) ---
1899
+ hooks_src = claude_src / "hooks"
1900
+ if hooks_src.exists():
1901
+ hooks_dst = claude_dst / "hooks"
1902
+ hooks_dst.mkdir(parents=True, exist_ok=True)
1903
+ for hook_file in sorted(hooks_src.glob("*")):
1904
+ if hook_file.is_file():
1905
+ dst_file = hooks_dst / hook_file.name
1906
+ content = hook_file.read_text(encoding="utf-8", errors="replace")
1907
+ # Adapt pre_tool_use.py: filter APPEND_ONLY_TABLES to child's schema
1908
+ if hook_file.name == "pre_tool_use.py":
1909
+ content = _adapt_pre_tool_use_for_child(content, blueprint)
1910
+ dst_file.write_text(content, encoding="utf-8")
1911
+ files_copied.append(f".claude/hooks/{hook_file.name}")
1912
+
1913
+ # --- Commands (exclude PARENT_ONLY_COMMANDS) ---
1914
+ cmds_src = claude_src / "commands"
1915
+ if cmds_src.exists():
1916
+ cmds_dst = claude_dst / "commands"
1917
+ cmds_dst.mkdir(parents=True, exist_ok=True)
1918
+ for cmd_file in sorted(cmds_src.glob("*.md")):
1919
+ if cmd_file.name in PARENT_ONLY_COMMANDS:
1920
+ files_skipped.append(f".claude/commands/{cmd_file.name}")
1921
+ continue
1922
+ dst_file = cmds_dst / cmd_file.name
1923
+ content = cmd_file.read_text(encoding="utf-8", errors="replace")
1924
+ content = content.replace("ICDEV", blueprint["app_name"])
1925
+ dst_file.write_text(content, encoding="utf-8")
1926
+ files_copied.append(f".claude/commands/{cmd_file.name}")
1927
+
1928
+ # E2E specs (exclude PARENT_ONLY_E2E)
1929
+ e2e_src = cmds_src / "e2e"
1930
+ if e2e_src.exists():
1931
+ e2e_dst = cmds_dst / "e2e"
1932
+ e2e_dst.mkdir(parents=True, exist_ok=True)
1933
+ for e2e_file in sorted(e2e_src.glob("*.md")):
1934
+ if e2e_file.name in PARENT_ONLY_E2E:
1935
+ files_skipped.append(f".claude/commands/e2e/{e2e_file.name}")
1936
+ continue
1937
+ dst_file = e2e_dst / e2e_file.name
1938
+ content = e2e_file.read_text(encoding="utf-8", errors="replace")
1939
+ dst_file.write_text(content, encoding="utf-8")
1940
+ files_copied.append(f".claude/commands/e2e/{e2e_file.name}")
1941
+
1942
+ # --- Skills (exclude PARENT_ONLY_SKILLS + capability-gated, D-CHILD-10) ---
1943
+ capabilities = blueprint.get("capabilities", {})
1944
+ skills_src = claude_src / "skills"
1945
+ if skills_src.exists():
1946
+ skills_dst = claude_dst / "skills"
1947
+ skills_dst.mkdir(parents=True, exist_ok=True)
1948
+ for skill_dir in sorted(skills_src.iterdir()):
1949
+ if not skill_dir.is_dir():
1950
+ continue
1951
+ # Check parent-only exclusion
1952
+ if skill_dir.name in PARENT_ONLY_SKILLS:
1953
+ files_skipped.append(f".claude/skills/{skill_dir.name}/")
1954
+ continue
1955
+ # Check capability-gated skills
1956
+ required_cap = SKILL_CAPABILITY_MAP.get(skill_dir.name)
1957
+ if required_cap and not capabilities.get(required_cap, False):
1958
+ files_skipped.append(f".claude/skills/{skill_dir.name}/")
1959
+ logger.debug(
1960
+ "Skipping skill %s — requires capability %s",
1961
+ skill_dir.name, required_cap,
1962
+ )
1963
+ continue
1964
+ dst_skill = skills_dst / skill_dir.name
1965
+ shutil.copytree(
1966
+ str(skill_dir), str(dst_skill), dirs_exist_ok=True
1967
+ )
1968
+ files_copied.append(f".claude/skills/{skill_dir.name}/")
1969
+
1970
+ # --- settings.json ---
1971
+ settings_src = claude_src / "settings.json"
1972
+ if settings_src.exists():
1973
+ settings_dst = claude_dst / "settings.json"
1974
+ content = settings_src.read_text(encoding="utf-8", errors="replace")
1975
+ content = content.replace("ICDEV", blueprint["app_name"])
1976
+ settings_dst.write_text(content, encoding="utf-8")
1977
+ files_copied.append(".claude/settings.json")
1978
+
1979
+ # --- file_access_tiers.yaml ---
1980
+ tiers_src = icdev_root / "args" / "file_access_tiers.yaml"
1981
+ if tiers_src.exists():
1982
+ tiers_dst = child_root / "args" / "file_access_tiers.yaml"
1983
+ tiers_dst.parent.mkdir(parents=True, exist_ok=True)
1984
+ shutil.copy2(str(tiers_src), str(tiers_dst))
1985
+ files_copied.append("args/file_access_tiers.yaml")
1986
+
1987
+ logger.info(
1988
+ "Step 9c: Claude Code config — %d files copied, %d excluded (parent-only)",
1989
+ len(files_copied), len(files_skipped)
1990
+ )
1991
+ return {
1992
+ "files_copied": files_copied,
1993
+ "files_skipped": files_skipped,
1994
+ }
1995
+
1996
+
1997
+ def _adapt_pre_tool_use_for_child(content: str, blueprint: dict) -> str:
1998
+ """Filter APPEND_ONLY_TABLES in pre_tool_use.py to child's DB schema.
1999
+
2000
+ Only keeps table names that exist in the child's enabled capability
2001
+ table groups. This prevents the hook from referencing tables that
2002
+ don't exist in the child's database.
2003
+ """
2004
+ # Ensure project root is in sys.path for deferred import
2005
+ _project_root = str(Path(__file__).resolve().parent.parent.parent)
2006
+ if _project_root not in sys.path:
2007
+ sys.path.insert(0, _project_root)
2008
+ from icdev.tools.builder.db_init_generator import (
2009
+ CORE_TABLES, CAPABILITY_TABLE_MAP,
2010
+ )
2011
+
2012
+ # Collect all table names present in the child's schema
2013
+ child_tables: set = set(CORE_TABLES.keys())
2014
+ capabilities = blueprint.get("capabilities", {})
2015
+ for cap_name, enabled in capabilities.items():
2016
+ if enabled and cap_name in CAPABILITY_TABLE_MAP:
2017
+ child_tables.update(CAPABILITY_TABLE_MAP[cap_name].keys())
2018
+
2019
+ # Find the APPEND_ONLY_TABLES set in the hook and filter it
2020
+ # Pattern: APPEND_ONLY_TABLES = { ... }
2021
+ import re as _re
2022
+ pattern = _re.compile(
2023
+ r"(APPEND_ONLY_TABLES\s*=\s*\{)(.*?)(\})",
2024
+ _re.DOTALL,
2025
+ )
2026
+ match = pattern.search(content)
2027
+ if not match:
2028
+ return content # Hook doesn't have the expected pattern — return as-is
2029
+
2030
+ # Parse existing table names from the set literal
2031
+ raw_tables = match.group(2)
2032
+ table_names = _re.findall(r'"([^"]+)"', raw_tables)
2033
+
2034
+ # Keep only tables in the child's schema
2035
+ filtered = [t for t in table_names if t in child_tables]
2036
+ filtered_str = ",\n ".join(f'"{t}"' for t in sorted(filtered))
2037
+
2038
+ replacement = f"{match.group(1)}\n {filtered_str},\n{match.group(3)}"
2039
+ content = content[:match.start()] + replacement + content[match.end():]
2040
+
2041
+ return content
2042
+
2043
+
2044
+ # ============================================================
2045
+ # STEP 10: CSP MCP Server Configuration
2046
+ # ============================================================
2047
+
2048
+
2049
+ def step_10_csp_mcp_config(child_root: Path, blueprint: dict) -> dict:
2050
+ """Step 10: Generate .mcp.json and CSP integration files."""
2051
+ app_name = blueprint["app_name"]
2052
+ agents = blueprint.get("agents", [])
2053
+ csp_servers = blueprint.get("csp_mcp_servers", [])
2054
+ cloud_config = blueprint.get("cloud_provider", {})
2055
+ provider = cloud_config.get("provider", "aws")
2056
+
2057
+ # Build .mcp.json combining agent MCP servers + CSP MCP servers
2058
+ mcp_config: Dict[str, Any] = {"mcpServers": {}}
2059
+
2060
+ # Agent MCP servers
2061
+ mcp_server_map = {
2062
+ "orchestrator": "core_server", "architect": "core_server",
2063
+ "builder": "builder_server", "compliance": "compliance_server",
2064
+ "security": "security_server", "knowledge": "knowledge_server",
2065
+ "monitor": "monitor_server",
2066
+ # D-CHILD-1: Enterprise agent MCP servers
2067
+ "requirements_analyst": "requirements_server",
2068
+ "supply_chain": "supply_chain_server",
2069
+ "simulation": "simulation_server",
2070
+ "devsecops_zta": "devsecops_server",
2071
+ }
2072
+ added_servers = set()
2073
+ for agent in agents:
2074
+ server_name = mcp_server_map.get(agent["name"])
2075
+ if server_name and server_name not in added_servers:
2076
+ added_servers.add(server_name)
2077
+ key = f"{app_name}-{server_name.replace('_', '-')}"
2078
+ mcp_config["mcpServers"][key] = {
2079
+ "command": "python",
2080
+ "args": [f"tools/mcp/{server_name}.py"],
2081
+ }
2082
+
2083
+ # CSP MCP servers
2084
+ for server in csp_servers:
2085
+ server_name = server.get("name", "")
2086
+ if server_name:
2087
+ mcp_config["mcpServers"][server_name] = {
2088
+ "command": "npx",
2089
+ "args": ["-y", server_name],
2090
+ }
2091
+
2092
+ mcp_path = child_root / ".mcp.json"
2093
+ mcp_path.write_text(json.dumps(mcp_config, indent=2), encoding="utf-8")
2094
+
2095
+ # Generate args/csp_mcp_config.yaml
2096
+ csp_config_lines = [
2097
+ f"# CSP MCP Configuration for {app_name}",
2098
+ f"provider: {provider}",
2099
+ f"region: {cloud_config.get('region', 'us-gov-west-1')}",
2100
+ f"govcloud: {str(cloud_config.get('govcloud', False)).lower()}",
2101
+ "mcp_servers:",
2102
+ ]
2103
+ for server in csp_servers:
2104
+ name = server.get("name", "unknown")
2105
+ cat = server.get("category", "core")
2106
+ csp_config_lines.append(f" - name: \"{name}\"")
2107
+ csp_config_lines.append(f" category: \"{cat}\"")
2108
+ csp_config_lines.append(" transport: stdio")
2109
+
2110
+ csp_config_path = child_root / "args" / "csp_mcp_config.yaml"
2111
+ csp_config_path.parent.mkdir(parents=True, exist_ok=True)
2112
+ csp_config_path.write_text("\n".join(csp_config_lines) + "\n", encoding="utf-8")
2113
+
2114
+ # Generate context/agentic/csp_integration.md
2115
+ integration_lines = [
2116
+ f"# CSP Integration — {app_name}",
2117
+ "",
2118
+ f"## Cloud Provider: {provider.upper()}",
2119
+ f"- **Region:** {cloud_config.get('region', 'us-gov-west-1')}",
2120
+ f"- **GovCloud:** {'Yes' if cloud_config.get('govcloud') else 'No'}",
2121
+ "",
2122
+ "## Available MCP Servers",
2123
+ "",
2124
+ "| Server | Category | Description |",
2125
+ "|--------|----------|-------------|",
2126
+ ]
2127
+ for server in csp_servers:
2128
+ integration_lines.append(
2129
+ f"| {server.get('name', '')} | {server.get('category', '')} "
2130
+ f"| {server.get('description', '')} |")
2131
+
2132
+ integration_lines.extend([
2133
+ "",
2134
+ "## Usage",
2135
+ "",
2136
+ "These MCP servers are configured in `.mcp.json` and available to Claude Code.",
2137
+ "Use them for cloud-native operations specific to the target deployment environment.",
2138
+ "",
2139
+ f"For capabilities not available via {provider.upper()} MCP servers, use the A2A",
2140
+ "callback to parent ICDEV.",
2141
+ ])
2142
+
2143
+ integration_path = child_root / "context" / "agentic" / "csp_integration.md"
2144
+ integration_path.parent.mkdir(parents=True, exist_ok=True)
2145
+ integration_path.write_text("\n".join(integration_lines) + "\n", encoding="utf-8")
2146
+
2147
+ logger.info("Step 10: CSP MCP config — %d servers for %s",
2148
+ len(csp_servers), provider)
2149
+ return {
2150
+ "mcp_json": str(mcp_path),
2151
+ "csp_config": str(csp_config_path),
2152
+ "csp_integration": str(integration_path),
2153
+ "total_mcp_servers": len(mcp_config["mcpServers"]),
2154
+ "csp_servers": len(csp_servers),
2155
+ }
2156
+
2157
+
2158
+ # ============================================================
2159
+ # STEP 11b: README Generation
2160
+ # ============================================================
2161
+
2162
+ # Human-readable capability descriptions for the README "sell" section
2163
+ CAP_DESCRIPTIONS: Dict[str, str] = {
2164
+ "compliance": "ATO Compliance — SSP, POAM, STIG, SBOM, CUI markings, NIST 800-53, FedRAMP, CMMC",
2165
+ "security": "Security Scanning — SAST (Bandit), dependency audit, secret detection, container scanning",
2166
+ "testing": "Testing Framework — pytest unit + behave BDD + Playwright E2E + security gates",
2167
+ "multi_agent": "Multi-Agent Architecture — A2A protocol, agent cards, MCP servers, domain routing",
2168
+ "cicd": "CI/CD Integration — GitHub Actions + GitLab CI, webhooks, poll triggers, slash commands",
2169
+ "mbse": "Model-Based Systems Engineering — SysML, DOORS NG, digital thread, model-code sync",
2170
+ "monitoring": "Production Monitoring — Log analysis, metrics, alerts, health checks, self-healing",
2171
+ "dashboard": "Web Dashboard — Flask SSR, real-time updates, role-based views, accessibility",
2172
+ "knowledge": "Knowledge Base — Pattern detection, self-healing, ML recommendations",
2173
+ "modernization": "App Modernization — 7R assessment, version/framework migration, strangler fig",
2174
+ "supply_chain": "Supply Chain Intelligence — Dependency graph, SBOM aggregation, ISA lifecycle, CVE triage",
2175
+ "simulation": "Digital Program Twin — 6-dimension simulation, Monte Carlo, COA generation",
2176
+ "devsecops": "DevSecOps — Pipeline security, policy-as-code (Kyverno/OPA), image attestation",
2177
+ "zta": "Zero Trust Architecture — 7-pillar maturity, NIST 800-207, service mesh, mTLS",
2178
+ "mosa": "DoD MOSA — Modular Open Systems, ICD/TSP generation, modularity analysis",
2179
+ "marketplace": "GOTCHA Marketplace — Federated asset sharing, 7-gate security pipeline",
2180
+ "innovation": "Innovation Engine — Autonomous self-improvement, web scanning, trend detection",
2181
+ "translation": "Cross-Language Translation — 5-phase hybrid pipeline, 30 language pairs",
2182
+ "observability": "Observability & XAI — Distributed tracing, provenance, AgentSHAP attribution",
2183
+ "ai_transparency": "AI Transparency — Model/system cards, AI inventory, fairness, confabulation detection",
2184
+ "ai_accountability": "AI Accountability — Oversight plans, CAIO designation, incident response",
2185
+ }
2186
+
2187
+
2188
+ def _generate_readme(child_root: Path, blueprint: dict) -> dict:
2189
+ """Generate README.md that tells the ICDEV story and lists capabilities used.
2190
+
2191
+ Args:
2192
+ child_root: Root directory of the generated child app.
2193
+ blueprint: Blueprint dict from app_blueprint.py.
2194
+
2195
+ Returns:
2196
+ Dict with readme_path and sections_count.
2197
+ """
2198
+ app_name = blueprint["app_name"]
2199
+ classification = blueprint.get("classification", "CUI")
2200
+ impact_level = blueprint.get("impact_level", "IL4")
2201
+ demo_mode = blueprint.get("demo_mode", False)
2202
+ agents = blueprint.get("agents", [])
2203
+ capabilities = blueprint.get("capabilities", {})
2204
+ scorecard = blueprint.get("fitness_scorecard", {})
2205
+
2206
+ active_caps = sorted(k for k, v in capabilities.items() if v)
2207
+ description = (
2208
+ blueprint.get("description", "")
2209
+ or blueprint.get("purpose", "")
2210
+ or scorecard.get("spec", "")
2211
+ )
2212
+
2213
+ sections: list = []
2214
+
2215
+ # Demo banner
2216
+ if demo_mode:
2217
+ sections.append(
2218
+ "> **DEMONSTRATION ONLY** — This application is a demo build. "
2219
+ "It uses PUBLIC classification and must NOT be used for operational, "
2220
+ "classified, or sensitive data.\n"
2221
+ )
2222
+
2223
+ # Title + ICDEV intro
2224
+ sections.append(f"# {app_name}\n")
2225
+ sections.append(
2226
+ f"**Built with [ICDEV](https://github.com/icdev) — the Intelligent "
2227
+ f"Coding Development platform.**\n\n"
2228
+ f"ICDEV is a meta-builder that autonomously constructs Gov/DoD applications "
2229
+ f"using the GOTCHA framework (Goals, Orchestration, Tools, Args, Context, "
2230
+ f"Hard Prompts) and the ATLAS workflow (Architect → Trace → Link → Assemble "
2231
+ f"→ Stress-test). It handles the full SDLC with TDD/BDD, NIST 800-53 RMF "
2232
+ f"compliance, and self-healing capabilities.\n"
2233
+ )
2234
+
2235
+ # Classification badge
2236
+ sections.append(
2237
+ f"**Classification:** `{classification}` | **Impact Level:** `{impact_level}`\n"
2238
+ )
2239
+
2240
+ # Purpose
2241
+ if description:
2242
+ sections.append(f"## Purpose\n\n{description}\n")
2243
+
2244
+ # Architecture
2245
+ sections.append(
2246
+ "## Architecture\n\n"
2247
+ "This application follows the **GOTCHA 6-Layer Framework**:\n\n"
2248
+ "| Layer | Role |\n"
2249
+ "|-------|------|\n"
2250
+ "| **Goals** | Process definitions — what to achieve, which tools, expected outputs |\n"
2251
+ "| **Orchestration** | AI reads goals → decides tool order → applies args → references context |\n"
2252
+ "| **Tools** | Python scripts, one job each. Deterministic. |\n"
2253
+ "| **Args** | YAML/JSON behavior settings |\n"
2254
+ "| **Context** | Static reference material |\n"
2255
+ "| **Hard Prompts** | Reusable LLM instruction templates |\n"
2256
+ )
2257
+
2258
+ # ICDEV Capabilities Used — the "sell" section
2259
+ if active_caps:
2260
+ sections.append("## ICDEV Capabilities Used\n")
2261
+ sections.append(
2262
+ "This application leverages the following ICDEV capabilities:\n"
2263
+ )
2264
+ for cap in active_caps:
2265
+ desc = CAP_DESCRIPTIONS.get(cap, cap.replace("_", " ").title())
2266
+ sections.append(f"- **{cap}** — {desc}")
2267
+ sections.append("") # blank line
2268
+
2269
+ # Agents
2270
+ if agents:
2271
+ sections.append("## Agents\n")
2272
+ sections.append("| Agent | Port | Role |")
2273
+ sections.append("|-------|------|------|")
2274
+ for a in agents:
2275
+ name = a.get("name", "unknown")
2276
+ port = a.get("port", "?")
2277
+ role = a.get("role", "")
2278
+ sections.append(f"| {name.title()} | {port} | {role} |")
2279
+ sections.append("")
2280
+
2281
+ # Compliance Posture
2282
+ if capabilities.get("compliance", False):
2283
+ sections.append(
2284
+ "## Compliance Posture\n\n"
2285
+ "This application includes compliance tooling for:\n"
2286
+ "- NIST 800-53 Rev 5 control mapping\n"
2287
+ "- FedRAMP Moderate/High baselines\n"
2288
+ "- CMMC Level 2/3 practices\n"
2289
+ "- ATO artifacts: SSP, POAM, STIG checklist, SBOM\n"
2290
+ "- CUI markings applied at generation time\n"
2291
+ )
2292
+
2293
+ # Quick Start
2294
+ quick_start_cmds = [
2295
+ "# Initialize database",
2296
+ "python tools/db/init_db.py",
2297
+ "",
2298
+ "# Load memory",
2299
+ "python tools/memory/memory_read.py --format markdown",
2300
+ ]
2301
+ if capabilities.get("dashboard", False):
2302
+ quick_start_cmds += ["", "# Start dashboard", "python tools/dashboard/app.py"]
2303
+ if capabilities.get("testing", False):
2304
+ quick_start_cmds += ["", "# Run tests", "pytest tests/ -v"]
2305
+
2306
+ sections.append("## Quick Start\n")
2307
+ sections.append("```bash")
2308
+ sections.extend(quick_start_cmds)
2309
+ sections.append("```\n")
2310
+
2311
+ # Footer
2312
+ gen_date = blueprint.get("generated_at", datetime.now(tz=timezone.utc).isoformat())
2313
+ sections.append("---\n")
2314
+ sections.append(
2315
+ f"*Generated by ICDEV on {gen_date[:10]}*\n"
2316
+ )
2317
+
2318
+ readme_content = "\n".join(sections)
2319
+ readme_path = child_root / "README.md"
2320
+ readme_path.write_text(readme_content, encoding="utf-8")
2321
+
2322
+ logger.info("Step 11b: README.md generated (%d sections)", len(sections))
2323
+ return {"readme_path": str(readme_path), "sections_count": len(sections)}
2324
+
2325
+
2326
+ # ============================================================
2327
+ # STEP 11: Dynamic CLAUDE.md
2328
+ # ============================================================
2329
+
2330
+
2331
+ def step_11_dynamic_claude_md(child_root: Path, blueprint: dict) -> dict:
2332
+ """Step 11: Generate dynamic CLAUDE.md using claude_md_generator."""
2333
+ generate_fn = _import_sister("claude_md_generator", "generate_claude_md")
2334
+
2335
+ if generate_fn:
2336
+ content = generate_fn(blueprint)
2337
+ method = "claude_md_generator"
2338
+ else:
2339
+ # Fallback: minimal CLAUDE.md
2340
+ app_name = blueprint["app_name"]
2341
+ agents = blueprint.get("agents", [])
2342
+ content = f"""# CLAUDE.md
2343
+
2344
+ This file provides guidance to Claude Code when working with {app_name}.
2345
+
2346
+ ---
2347
+
2348
+ ## Architecture: GOTCHA Framework
2349
+
2350
+ This is a 6-layer agentic system: Goals, Orchestration, Tools, Args, Context, Hard Prompts.
2351
+
2352
+ ### Key Files
2353
+ - `goals/manifest.md` — Index of all goal workflows
2354
+ - `tools/manifest.md` — Master list of all tools
2355
+ - `memory/MEMORY.md` — Long-term facts and preferences
2356
+
2357
+ ### Session Start Protocol
2358
+ 1. Read `memory/MEMORY.md`
2359
+ 2. Read today's daily log
2360
+ 3. Or run: `python tools/memory/memory_read.py --format markdown`
2361
+
2362
+ ---
2363
+
2364
+ ## {app_name} System
2365
+
2366
+ ### Agents ({len(agents)})
2367
+
2368
+ | Agent | Port | Role |
2369
+ |-------|------|------|
2370
+ """
2371
+ for a in agents:
2372
+ content += f"| {a['name']} | {a['port']} | {a.get('role', '')} |\n"
2373
+
2374
+ content += """
2375
+ ---
2376
+
2377
+ ## Guardrails
2378
+
2379
+ - Always check `tools/manifest.md` before writing a new script
2380
+ - Verify tool output format before chaining
2381
+ - **This application CANNOT generate child applications**
2382
+ - Audit trail is append-only — NEVER add UPDATE/DELETE operations
2383
+
2384
+ ---
2385
+
2386
+ ## Continuous Improvement
2387
+
2388
+ Every failure strengthens the system. Be direct. Be reliable. Get it done.
2389
+ """
2390
+ method = "fallback"
2391
+
2392
+ claude_md_path = child_root / "CLAUDE.md"
2393
+ claude_md_path.write_text(content, encoding="utf-8")
2394
+
2395
+ line_count = content.count("\n") + 1
2396
+ logger.info("Step 11: CLAUDE.md generated (%d lines, method=%s)",
2397
+ line_count, method)
2398
+ return {"claude_md_path": str(claude_md_path), "lines": line_count, "method": method}
2399
+
2400
+
2401
+ # ============================================================
2402
+ # STEP 12: Audit + Registration
2403
+ # ============================================================
2404
+
2405
+
2406
+ def step_12_audit_and_registration(
2407
+ child_root: Path, blueprint: dict, db_path: Path
2408
+ ) -> dict:
2409
+ """Step 12: Log to ICDEV audit trail and register in child_app_registry."""
2410
+ app_name = blueprint["app_name"]
2411
+ blueprint_hash = blueprint.get("blueprint_hash", "")
2412
+
2413
+ # Audit log
2414
+ audit_log_event(
2415
+ event_type="child_app_generated",
2416
+ actor="child-app-generator",
2417
+ action=f"Generated child app '{app_name}' at {child_root}",
2418
+ project_id=blueprint.get("fitness_scorecard", {}).get("project_id", ""),
2419
+ details=json.dumps({
2420
+ "app_name": app_name,
2421
+ "blueprint_hash": blueprint_hash,
2422
+ "agents": len(blueprint.get("agents", [])),
2423
+ "capabilities": sum(1 for v in blueprint.get("capabilities", {}).values() if v),
2424
+ }),
2425
+ )
2426
+
2427
+ # Register in child_app_registry table
2428
+ registered = False
2429
+ try:
2430
+ if db_path.exists():
2431
+ conn = sqlite3.connect(str(db_path))
2432
+ conn.execute(
2433
+ "INSERT OR REPLACE INTO child_app_registry "
2434
+ "(id, parent_project_id, child_name, child_path, blueprint_hash, "
2435
+ "capabilities, agent_count, cloud_provider, callback_url, classification) "
2436
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
2437
+ (
2438
+ str(uuid.uuid4()),
2439
+ blueprint.get("fitness_scorecard", {}).get("project_id", ""),
2440
+ app_name,
2441
+ str(child_root),
2442
+ blueprint_hash,
2443
+ json.dumps(blueprint.get("capabilities", {})),
2444
+ len(blueprint.get("agents", [])),
2445
+ blueprint.get("cloud_provider", {}).get("provider", "aws"),
2446
+ blueprint.get("parent_callback", {}).get("url", ""),
2447
+ blueprint.get("classification", "CUI"),
2448
+ ),
2449
+ )
2450
+ conn.commit()
2451
+ conn.close()
2452
+ registered = True
2453
+ logger.info("Step 12: Registered child app in ICDEV database")
2454
+ except Exception as e:
2455
+ logger.warning("Step 12: Failed to register in DB: %s", e)
2456
+
2457
+ # Phase 36 integration: write genome manifest to child directory
2458
+ genome_version = None
2459
+ try:
2460
+ if db_path.exists():
2461
+ gconn = sqlite3.connect(str(db_path))
2462
+ gconn.row_factory = sqlite3.Row
2463
+ row = gconn.execute(
2464
+ "SELECT version, content_hash, genome_data "
2465
+ "FROM genome_versions ORDER BY created_at DESC LIMIT 1"
2466
+ ).fetchone()
2467
+ if row:
2468
+ genome_version = row["version"]
2469
+ genome_manifest = {
2470
+ "parent_id": blueprint.get("fitness_scorecard", {}).get(
2471
+ "project_id", "icdev-parent"
2472
+ ),
2473
+ "genome_version": row["version"],
2474
+ "content_hash": row["content_hash"],
2475
+ "capabilities_baseline": json.loads(row["genome_data"])
2476
+ if row["genome_data"] else {},
2477
+ "generation_timestamp": datetime.now(tz=timezone.utc).isoformat(),
2478
+ "grandchild_prevention": True,
2479
+ }
2480
+ gm_path = child_root / "data" / "genome_manifest.json"
2481
+ gm_path.parent.mkdir(parents=True, exist_ok=True)
2482
+ gm_path.write_text(
2483
+ json.dumps(genome_manifest, indent=2), encoding="utf-8"
2484
+ )
2485
+ logger.info(
2486
+ "Step 12: Wrote genome manifest (v%s) to child",
2487
+ genome_version,
2488
+ )
2489
+ gconn.close()
2490
+ except Exception as e:
2491
+ logger.warning("Step 12: Genome manifest write failed: %s", e)
2492
+
2493
+ # Generate summary report in child app
2494
+ summary = {
2495
+ "app_name": app_name,
2496
+ "child_root": str(child_root),
2497
+ "blueprint_hash": blueprint_hash,
2498
+ "agents": len(blueprint.get("agents", [])),
2499
+ "capabilities": {k: v for k, v in blueprint.get("capabilities", {}).items() if v},
2500
+ "cloud_provider": blueprint.get("cloud_provider", {}).get("provider", "aws"),
2501
+ "classification": blueprint.get("classification", "CUI"),
2502
+ "genome_version": genome_version,
2503
+ "generated_at": datetime.now(tz=timezone.utc).isoformat(),
2504
+ "generated_by": "icdev/child_app_generator",
2505
+ }
2506
+ summary_path = child_root / "data" / "generation_summary.json"
2507
+ summary_path.parent.mkdir(parents=True, exist_ok=True)
2508
+ summary_path.write_text(json.dumps(summary, indent=2), encoding="utf-8")
2509
+
2510
+ logger.info("Step 12: Audit complete, registered=%s", registered)
2511
+ return {"registered": registered, "summary_path": str(summary_path)}
2512
+
2513
+
2514
+ # ============================================================
2515
+ # STEP 13: Production Audit
2516
+ # ============================================================
2517
+
2518
+
2519
+ def step_13_production_audit(child_root: Path, blueprint: dict) -> dict:
2520
+ """Run production audit on the generated child app.
2521
+
2522
+ Invokes ICDEV's production_audit.py as a subprocess with the child app
2523
+ as the working directory, then stores the results in the child app's
2524
+ data directory.
2525
+
2526
+ Args:
2527
+ child_root: Root directory of the child app.
2528
+ blueprint: Blueprint dict.
2529
+
2530
+ Returns:
2531
+ Dict with audit results summary.
2532
+ """
2533
+ audit_script = BASE_DIR / "tools" / "testing" / "production_audit.py"
2534
+ if not audit_script.exists():
2535
+ logger.warning("Step 13: production_audit.py not found, skipping")
2536
+ return {"skipped": True, "reason": "audit script not found"}
2537
+
2538
+ try:
2539
+ env = {**os.environ, "PYTHONDONTWRITEBYTECODE": "1"}
2540
+ result = subprocess.run(
2541
+ [sys.executable, str(audit_script), "--json"],
2542
+ capture_output=True, text=True, cwd=str(child_root),
2543
+ timeout=120, env=env,
2544
+ )
2545
+
2546
+ # Parse JSON output
2547
+ audit_data = {}
2548
+ if result.stdout.strip():
2549
+ try:
2550
+ audit_data = json.loads(result.stdout.strip())
2551
+ except json.JSONDecodeError:
2552
+ audit_data = {"raw_output": result.stdout[:2000]}
2553
+
2554
+ # Store audit results in child app
2555
+ data_dir = child_root / "data"
2556
+ data_dir.mkdir(parents=True, exist_ok=True)
2557
+ audit_path = data_dir / "production_audit.json"
2558
+ audit_path.write_text(
2559
+ json.dumps(audit_data, indent=2, default=str), encoding="utf-8"
2560
+ )
2561
+
2562
+ # Summary
2563
+ checks = audit_data.get("checks", [])
2564
+ passed = sum(1 for c in checks if c.get("status") == "pass")
2565
+ failed = sum(1 for c in checks if c.get("status") == "fail")
2566
+ total = len(checks)
2567
+
2568
+ logger.info(
2569
+ "Step 13: Production audit complete — %d/%d passed, %d failed",
2570
+ passed, total, failed
2571
+ )
2572
+ return {
2573
+ "audit_path": str(audit_path),
2574
+ "total_checks": total,
2575
+ "passed": passed,
2576
+ "failed": failed,
2577
+ "exit_code": result.returncode,
2578
+ }
2579
+
2580
+ except subprocess.TimeoutExpired:
2581
+ logger.warning("Step 13: Production audit timed out (120s)")
2582
+ return {"skipped": True, "reason": "timeout"}
2583
+ except Exception as e:
2584
+ logger.warning("Step 13: Production audit failed: %s", e)
2585
+ return {"skipped": True, "reason": str(e)}
2586
+
2587
+
2588
+ # ============================================================
2589
+ # STEP 14: GOTCHA Compliance Validation
2590
+ # ============================================================
2591
+
2592
+
2593
+ def step_14_gotcha_validation(child_root: Path, blueprint: dict) -> dict:
2594
+ """Step 14: Validate GOTCHA framework compliance of generated child app.
2595
+
2596
+ Runs the gotcha_validator to verify all 6 GOTCHA layers are populated
2597
+ and ATLAS workflow structure is present. This ensures child apps follow
2598
+ the GOTCHA framework as mandated by build_app.md.
2599
+
2600
+ BMAD-adapted: adversarial validation — assumes the build is incomplete
2601
+ until proven otherwise.
2602
+ """
2603
+ validate_fn = _import_sister("gotcha_validator", "validate")
2604
+
2605
+ if validate_fn:
2606
+ report = validate_fn(child_root)
2607
+ report_dict = report.to_dict()
2608
+
2609
+ # Store validation results in child app
2610
+ data_dir = child_root / "data"
2611
+ data_dir.mkdir(parents=True, exist_ok=True)
2612
+ report_path = data_dir / "gotcha_validation.json"
2613
+ report_path.write_text(
2614
+ json.dumps(report_dict, indent=2, default=str), encoding="utf-8"
2615
+ )
2616
+
2617
+ # Log warnings for failed checks
2618
+ for check in report_dict.get("checks", []):
2619
+ if check.get("status") == "fail":
2620
+ logger.warning(
2621
+ "GOTCHA validation FAIL: %s — %s (fix: %s)",
2622
+ check.get("check_id"), check.get("message"),
2623
+ check.get("fix_suggestion"),
2624
+ )
2625
+ elif check.get("status") == "warn":
2626
+ logger.info(
2627
+ "GOTCHA validation WARN: %s — %s",
2628
+ check.get("check_id"), check.get("message"),
2629
+ )
2630
+
2631
+ logger.info(
2632
+ "Step 14: GOTCHA validation — score %.0f%% (%d/%d passed, %d failed)",
2633
+ report_dict.get("score", 0) * 100,
2634
+ report_dict.get("passed_checks", 0),
2635
+ report_dict.get("total_checks", 0),
2636
+ report_dict.get("failed_checks", 0),
2637
+ )
2638
+ return {
2639
+ "report_path": str(report_path),
2640
+ "overall_pass": report_dict.get("overall_pass", False),
2641
+ "score": report_dict.get("score", 0),
2642
+ "passed": report_dict.get("passed_checks", 0),
2643
+ "failed": report_dict.get("failed_checks", 0),
2644
+ "warned": report_dict.get("warned_checks", 0),
2645
+ "layer_summary": report_dict.get("layer_summary", {}),
2646
+ }
2647
+
2648
+ # Fallback: basic directory existence check
2649
+ logger.warning("Step 14: gotcha_validator not available, running basic check")
2650
+ gotcha_dirs = ["goals", "tools", "args", "context", "hardprompts", "memory"]
2651
+ present = [d for d in gotcha_dirs if (child_root / d).is_dir()]
2652
+ missing = [d for d in gotcha_dirs if d not in present]
2653
+
2654
+ if missing:
2655
+ logger.warning("Step 14: Missing GOTCHA directories: %s", ", ".join(missing))
2656
+
2657
+ return {
2658
+ "method": "fallback",
2659
+ "overall_pass": len(missing) == 0,
2660
+ "present": present,
2661
+ "missing": missing,
2662
+ }
2663
+
2664
+
2665
+ # ============================================================
2666
+ # MAIN ORCHESTRATOR
2667
+ # ============================================================
2668
+
2669
+
2670
+ def generate_child_app(
2671
+ blueprint: dict,
2672
+ project_path: str,
2673
+ name: str,
2674
+ icdev_root: Optional[Path] = None,
2675
+ db_path: Optional[Path] = None,
2676
+ ) -> dict:
2677
+ """Generate a complete child application from a blueprint.
2678
+
2679
+ Executes 17 steps sequentially (12 core + 9b license + 9c claude config +
2680
+ 11b README + 13 audit + 14 GOTCHA validation), collecting results from each.
2681
+
2682
+ Args:
2683
+ blueprint: Complete blueprint dict from app_blueprint.py.
2684
+ project_path: Parent directory for the child app.
2685
+ name: Child application name.
2686
+ icdev_root: Path to ICDEV project root (auto-detected if None).
2687
+ db_path: Path to ICDEV database (auto-detected if None).
2688
+
2689
+ Returns:
2690
+ Summary dict with step results and overall status.
2691
+ """
2692
+ child_root = Path(project_path) / name
2693
+ icdev_root = icdev_root or BASE_DIR
2694
+ db_path = db_path or DB_PATH
2695
+
2696
+ logger.info("Generating child app '%s' at %s", name, child_root)
2697
+ start_time = datetime.now(tz=timezone.utc)
2698
+
2699
+ results: Dict[str, Any] = {
2700
+ "app_name": name,
2701
+ "child_root": str(child_root),
2702
+ "icdev_root": str(icdev_root),
2703
+ "steps": {},
2704
+ "status": "success",
2705
+ "errors": [],
2706
+ }
2707
+
2708
+ # Define steps with their signatures
2709
+ steps: List[Tuple[str, Any]] = [
2710
+ ("01_directory_tree", lambda: step_01_create_directory_tree(child_root, blueprint)),
2711
+ ("02_copy_adapt_tools", lambda: step_02_copy_and_adapt_tools(child_root, blueprint, icdev_root)),
2712
+ ("03_agent_infra", lambda: step_03_agent_infrastructure(child_root, blueprint, icdev_root)),
2713
+ ("04_memory_bootstrap", lambda: step_04_memory_bootstrap(child_root, blueprint)),
2714
+ ("05_db_init_script", lambda: step_05_db_init_script(child_root, blueprint)),
2715
+ ("06_goals_hardprompts", lambda: step_06_goals_and_hardprompts(child_root, blueprint, icdev_root)),
2716
+ ("07_args_context", lambda: step_07_args_and_context(child_root, blueprint, icdev_root)),
2717
+ ("08_a2a_callback", lambda: step_08_a2a_callback_client(child_root, blueprint)),
2718
+ ("09_cicd_setup", lambda: step_09_cicd_setup(child_root, blueprint, icdev_root)),
2719
+ ("09b_license", lambda: _copy_license_files(child_root, blueprint, icdev_root)),
2720
+ ("09c_claude_config", lambda: step_09c_claude_code_config(child_root, blueprint, icdev_root)),
2721
+ ("10_csp_mcp_config", lambda: step_10_csp_mcp_config(child_root, blueprint)),
2722
+ ("11_claude_md", lambda: step_11_dynamic_claude_md(child_root, blueprint)),
2723
+ ("11b_readme", lambda: _generate_readme(child_root, blueprint)),
2724
+ ("12_audit_register", lambda: step_12_audit_and_registration(child_root, blueprint, db_path)),
2725
+ ("13_production_audit", lambda: step_13_production_audit(child_root, blueprint)),
2726
+ ("14_gotcha_validation", lambda: step_14_gotcha_validation(child_root, blueprint)),
2727
+ ]
2728
+
2729
+ for step_name, step_fn in steps:
2730
+ try:
2731
+ logger.info("Running step: %s", step_name)
2732
+ step_result = step_fn()
2733
+ results["steps"][step_name] = {"status": "success", **(step_result or {})}
2734
+ except Exception as e:
2735
+ logger.error("Step %s failed: %s", step_name, e, exc_info=True)
2736
+ results["steps"][step_name] = {"status": "error", "error": str(e)}
2737
+ results["errors"].append(f"{step_name}: {e}")
2738
+
2739
+ # Compute overall status
2740
+ failed_steps = [s for s, r in results["steps"].items() if r.get("status") == "error"]
2741
+ if failed_steps:
2742
+ results["status"] = "partial" if len(failed_steps) < len(steps) else "failed"
2743
+
2744
+ elapsed = (datetime.now(tz=timezone.utc) - start_time).total_seconds()
2745
+ results["elapsed_seconds"] = round(elapsed, 2)
2746
+ results["failed_steps"] = failed_steps
2747
+
2748
+ logger.info(
2749
+ "Child app '%s' generation %s in %.1fs (%d/%d steps succeeded)",
2750
+ name, results["status"], elapsed,
2751
+ len(steps) - len(failed_steps), len(steps),
2752
+ )
2753
+ return results
2754
+
2755
+
2756
+ # ============================================================
2757
+ # CLI
2758
+ # ============================================================
2759
+
2760
+
2761
+ def main():
2762
+ """CLI entry point for child app generation."""
2763
+ parser = argparse.ArgumentParser(
2764
+ description="Generate mini-ICDEV clone child application from blueprint",
2765
+ formatter_class=argparse.RawDescriptionHelpFormatter,
2766
+ epilog="Example:\n python tools/builder/child_app_generator.py "
2767
+ "--blueprint bp.json --project-path /tmp --name my-app --json",
2768
+ )
2769
+ parser.add_argument("--blueprint", required=True,
2770
+ help="Path to blueprint JSON file")
2771
+ parser.add_argument("--project-path", required=True,
2772
+ help="Parent directory for the child app")
2773
+ parser.add_argument("--name", required=True,
2774
+ help="Child application name")
2775
+ parser.add_argument("--icdev-root",
2776
+ help="Path to ICDEV root (default: auto-detect)")
2777
+ parser.add_argument("--db-path",
2778
+ help="Path to ICDEV database (default: data/icdev.db)")
2779
+ parser.add_argument("--json", action="store_true",
2780
+ help="Output results as JSON")
2781
+ parser.add_argument("--verbose", action="store_true",
2782
+ help="Enable debug logging")
2783
+
2784
+ args = parser.parse_args()
2785
+
2786
+ level = logging.DEBUG if args.verbose else logging.INFO
2787
+ logging.basicConfig(
2788
+ level=level,
2789
+ format="%(asctime)s [%(name)s] %(levelname)s: %(message)s",
2790
+ )
2791
+
2792
+ # Load blueprint
2793
+ bp_path = Path(args.blueprint)
2794
+ if not bp_path.exists():
2795
+ logger.error("Blueprint file not found: %s", bp_path)
2796
+ sys.exit(1)
2797
+
2798
+ try:
2799
+ with open(bp_path) as f:
2800
+ blueprint = json.load(f)
2801
+ except (json.JSONDecodeError, IOError) as e:
2802
+ logger.error("Failed to load blueprint: %s", e)
2803
+ sys.exit(1)
2804
+
2805
+ # Resolve paths
2806
+ icdev_root = Path(args.icdev_root) if args.icdev_root else BASE_DIR
2807
+ db_path = Path(args.db_path) if args.db_path else DB_PATH
2808
+
2809
+ # Generate child app
2810
+ results = generate_child_app(
2811
+ blueprint=blueprint,
2812
+ project_path=args.project_path,
2813
+ name=args.name,
2814
+ icdev_root=icdev_root,
2815
+ db_path=db_path,
2816
+ )
2817
+
2818
+ if args.json:
2819
+ print(json.dumps(results, indent=2))
2820
+ else:
2821
+ status = results["status"]
2822
+ steps = results["steps"]
2823
+ succeeded = sum(1 for r in steps.values() if r.get("status") == "success")
2824
+ total = len(steps)
2825
+
2826
+ print(f"\n{'=' * 60}")
2827
+ print(f"Child App Generation: {results['app_name']}")
2828
+ print(f"{'=' * 60}")
2829
+ print(f"Status: {status.upper()}")
2830
+ print(f"Location: {results['child_root']}")
2831
+ print(f"Steps: {succeeded}/{total} succeeded")
2832
+ print(f"Elapsed: {results.get('elapsed_seconds', 0)}s")
2833
+
2834
+ if results.get("errors"):
2835
+ print("\nErrors:")
2836
+ for err in results["errors"]:
2837
+ print(f" - {err}")
2838
+
2839
+ print("\nStep Results:")
2840
+ for step_name, step_result in steps.items():
2841
+ icon = "OK" if step_result.get("status") == "success" else "FAIL"
2842
+ print(f" [{icon}] {step_name}")
2843
+
2844
+ if status == "success":
2845
+ print("\nNext steps:")
2846
+ print(f" cd {results['child_root']}")
2847
+ print(" python tools/memory/memory_read.py --format markdown")
2848
+ print(" python tools/db/init_*_db.py")
2849
+
2850
+
2851
+ if __name__ == "__main__":
2852
+ main()