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,1805 @@
1
+ # [TEMPLATE: CUI // SP-CTI]
2
+ #!/usr/bin/env python3
3
+ """Bidirectional synchronization engine between SysML models (Cameo XMI) and code.
4
+
5
+ Since Cameo Systems Modeler is a standalone desktop application with no API in
6
+ an air-gapped environment, all synchronization is file-based. Drift detection
7
+ uses SHA-256 hash comparison on both model elements (stored in sysml_elements)
8
+ and code files (tracked in model_code_mappings).
9
+
10
+ Supported workflows:
11
+ - detect-drift: Compare stored hashes with current file state
12
+ - sync-model-to-code: Push model changes into generated code
13
+ - sync-code-to-model: Parse Python AST and generate XMI fragment for Cameo import
14
+ - resolve-conflict: Resolve model/code conflicts (keep_model, keep_code, merge)
15
+ - reimport-xmi: Re-import updated XMI after Cameo edits
16
+ - reimport-reqif: Re-import updated ReqIF after DOORS edits
17
+ - report: Generate CUI-marked drift/sync report
18
+
19
+ CLI usage:
20
+ python tools/mbse/sync_engine.py --project-id proj-123 detect-drift
21
+ python tools/mbse/sync_engine.py --project-id proj-123 sync-model-to-code --language python
22
+ python tools/mbse/sync_engine.py --project-id proj-123 sync-code-to-model --output .tmp/updates.xmi
23
+ python tools/mbse/sync_engine.py --project-id proj-123 resolve-conflict --mapping-id 7 --resolution keep_model
24
+ python tools/mbse/sync_engine.py --project-id proj-123 reimport-xmi --file model_v2.xmi
25
+ python tools/mbse/sync_engine.py --project-id proj-123 reimport-reqif --file reqs_v2.reqif
26
+ python tools/mbse/sync_engine.py --project-id proj-123 report --json
27
+
28
+ CUI // SP-CTI
29
+ """
30
+
31
+ import argparse
32
+ import ast
33
+ import hashlib
34
+ import json
35
+ import sqlite3
36
+ import sys
37
+ import uuid
38
+ import xml.etree.ElementTree as ET
39
+ from datetime import datetime
40
+ from pathlib import Path
41
+ from typing import Any, Dict, List, Optional
42
+ from icdev._paths import get_project_root
43
+
44
+ # ---------------------------------------------------------------------------
45
+ # Path constants
46
+ # ---------------------------------------------------------------------------
47
+ BASE_DIR = get_project_root()
48
+ DB_PATH = BASE_DIR / "data" / "icdev.db"
49
+
50
+ # ---------------------------------------------------------------------------
51
+ # Audit logger — graceful fallback for standalone execution
52
+ # ---------------------------------------------------------------------------
53
+ try:
54
+ from icdev.tools.audit.audit_logger import log_event # type: ignore
55
+ _HAS_AUDIT = True
56
+ except ImportError:
57
+ _HAS_AUDIT = False
58
+
59
+ def log_event(**kwargs) -> int: # noqa: D103 – stub
60
+ return -1
61
+
62
+ # ---------------------------------------------------------------------------
63
+ # XMI namespace constants (match xmi_parser.py)
64
+ # ---------------------------------------------------------------------------
65
+ XMI_NS = "http://www.omg.org/spec/XMI/20131001"
66
+ UML_NS = "http://www.omg.org/spec/UML/20131001"
67
+ SYSML_NS = "http://www.omg.org/spec/SysML/20181001"
68
+
69
+ # ---------------------------------------------------------------------------
70
+ # Helpers
71
+ # ---------------------------------------------------------------------------
72
+
73
+ def _ts() -> str:
74
+ """Current ISO-8601 timestamp."""
75
+ return datetime.now().isoformat()
76
+
77
+
78
+ def _new_id(prefix: str = "sysml") -> str:
79
+ """Generate a prefixed UUID."""
80
+ return f"{prefix}-{uuid.uuid4()}"
81
+
82
+
83
+ def _get_connection(db_path: Optional[Path] = None) -> sqlite3.Connection:
84
+ """Open a connection to the ICDEV database."""
85
+ path = Path(db_path) if db_path else DB_PATH
86
+ if not path.exists():
87
+ raise FileNotFoundError(
88
+ f"Database not found: {path}\n"
89
+ "Run: python tools/db/init_icdev_db.py"
90
+ )
91
+ conn = sqlite3.connect(str(path))
92
+ conn.row_factory = sqlite3.Row
93
+ conn.execute("PRAGMA journal_mode=WAL")
94
+ conn.execute("PRAGMA foreign_keys=ON")
95
+ return conn
96
+
97
+
98
+ def _compute_file_hash(file_path: str) -> str:
99
+ """Compute SHA-256 hex digest of a file.
100
+
101
+ Reads in 64 KiB chunks to handle large files without excessive memory use.
102
+ Returns empty string if the file does not exist.
103
+ """
104
+ fpath = Path(file_path)
105
+ if not fpath.exists():
106
+ return ""
107
+ h = hashlib.sha256()
108
+ with open(fpath, "rb") as fh:
109
+ for chunk in iter(lambda: fh.read(65536), b""):
110
+ h.update(chunk)
111
+ return h.hexdigest()
112
+
113
+
114
+ def _content_hash(text: str) -> str:
115
+ """Return SHA-256 hex digest of a string."""
116
+ return hashlib.sha256(text.encode("utf-8")).hexdigest()
117
+
118
+
119
+ # ---------------------------------------------------------------------------
120
+ # Python AST parsing (code -> model direction)
121
+ # ---------------------------------------------------------------------------
122
+
123
+ def _parse_python_ast(file_path: str) -> dict:
124
+ """Parse a Python file using the ast module.
125
+
126
+ Extracts top-level classes (with bases, methods, attributes) and
127
+ top-level functions (with arguments and docstrings).
128
+
129
+ Returns::
130
+
131
+ {
132
+ "classes": [
133
+ {
134
+ "name": str,
135
+ "bases": [str, ...],
136
+ "methods": [{"name": str, "args": [str], "docstring": str}, ...],
137
+ "attributes": [str, ...]
138
+ },
139
+ ...
140
+ ],
141
+ "functions": [
142
+ {"name": str, "args": [str, ...], "docstring": str},
143
+ ...
144
+ ],
145
+ }
146
+ """
147
+ fpath = Path(file_path)
148
+ if not fpath.exists():
149
+ return {"classes": [], "functions": []}
150
+
151
+ source = fpath.read_text(encoding="utf-8", errors="replace")
152
+ try:
153
+ tree = ast.parse(source, filename=str(fpath))
154
+ except SyntaxError:
155
+ return {"classes": [], "functions": []}
156
+
157
+ classes: List[Dict[str, Any]] = []
158
+ functions: List[Dict[str, Any]] = []
159
+
160
+ for node in ast.iter_child_nodes(tree):
161
+ if isinstance(node, ast.ClassDef):
162
+ bases = []
163
+ for base in node.bases:
164
+ if isinstance(base, ast.Name):
165
+ bases.append(base.id)
166
+ elif isinstance(base, ast.Attribute):
167
+ bases.append(ast.dump(base))
168
+ else:
169
+ bases.append(ast.dump(base))
170
+
171
+ methods: List[Dict[str, Any]] = []
172
+ attributes: List[str] = []
173
+
174
+ for item in ast.iter_child_nodes(node):
175
+ if isinstance(item, ast.FunctionDef) or isinstance(item, ast.AsyncFunctionDef):
176
+ method_args = []
177
+ for arg in item.args.args:
178
+ if arg.arg != "self":
179
+ method_args.append(arg.arg)
180
+ method_doc = ast.get_docstring(item) or ""
181
+ methods.append({
182
+ "name": item.name,
183
+ "args": method_args,
184
+ "docstring": method_doc,
185
+ })
186
+ elif isinstance(item, ast.Assign):
187
+ for target in item.targets:
188
+ if isinstance(target, ast.Name):
189
+ attributes.append(target.id)
190
+ elif isinstance(item, ast.AnnAssign):
191
+ if isinstance(item.target, ast.Name):
192
+ attributes.append(item.target.id)
193
+
194
+ classes.append({
195
+ "name": node.name,
196
+ "bases": bases,
197
+ "methods": methods,
198
+ "attributes": attributes,
199
+ })
200
+
201
+ elif isinstance(node, ast.FunctionDef) or isinstance(node, ast.AsyncFunctionDef):
202
+ func_args = [arg.arg for arg in node.args.args]
203
+ func_doc = ast.get_docstring(node) or ""
204
+ functions.append({
205
+ "name": node.name,
206
+ "args": func_args,
207
+ "docstring": func_doc,
208
+ })
209
+
210
+ return {"classes": classes, "functions": functions}
211
+
212
+
213
+ # ---------------------------------------------------------------------------
214
+ # XMI fragment generation (code -> model direction)
215
+ # ---------------------------------------------------------------------------
216
+
217
+ def _generate_xmi_fragment(elements: list) -> str:
218
+ """Generate an XMI 2.5 fragment for import into Cameo Systems Modeler.
219
+
220
+ Each element dict must contain at minimum:
221
+ - name (str)
222
+ - element_type (str): 'class', 'function', or 'interface'
223
+ - properties (dict, optional): methods, attributes, args, etc.
224
+
225
+ Returns well-formed XML string.
226
+ """
227
+ root = ET.Element("xmi:XMI")
228
+ root.set("xmlns:xmi", XMI_NS)
229
+ root.set("xmlns:uml", UML_NS)
230
+ root.set("xmlns:sysml", SYSML_NS)
231
+ root.set("xmi:version", "2.5")
232
+
233
+ model = ET.SubElement(root, "uml:Model")
234
+ model.set("xmi:id", f"model-{uuid.uuid4()}")
235
+ model.set("name", "CodeSyncImport")
236
+
237
+ pkg = ET.SubElement(model, "packagedElement")
238
+ pkg.set("xmi:type", "uml:Package")
239
+ pkg.set("xmi:id", f"pkg-{uuid.uuid4()}")
240
+ pkg.set("name", "SyncedFromCode")
241
+
242
+ for elem in elements:
243
+ etype = elem.get("element_type", "class")
244
+ name = elem.get("name", "Unknown")
245
+ props = elem.get("properties", {})
246
+ xmi_id = elem.get("xmi_id", f"elem-{uuid.uuid4()}")
247
+
248
+ if etype in ("class", "block"):
249
+ pe = ET.SubElement(pkg, "packagedElement")
250
+ pe.set("xmi:type", "uml:Class")
251
+ pe.set("xmi:id", xmi_id)
252
+ pe.set("name", name)
253
+
254
+ # Add attributes as ownedAttribute
255
+ for attr_name in props.get("attributes", []):
256
+ oa = ET.SubElement(pe, "ownedAttribute")
257
+ oa.set("xmi:type", "uml:Property")
258
+ oa.set("xmi:id", f"attr-{uuid.uuid4()}")
259
+ oa.set("name", attr_name)
260
+ oa.set("visibility", "public")
261
+
262
+ # Add methods as ownedOperation
263
+ for method in props.get("methods", []):
264
+ op = ET.SubElement(pe, "ownedOperation")
265
+ op.set("xmi:type", "uml:Operation")
266
+ op.set("xmi:id", f"op-{uuid.uuid4()}")
267
+ op.set("name", method.get("name", ""))
268
+ op.set("visibility", "public")
269
+
270
+ # Parameters
271
+ for arg_name in method.get("args", []):
272
+ param = ET.SubElement(op, "ownedParameter")
273
+ param.set("xmi:id", f"param-{uuid.uuid4()}")
274
+ param.set("name", arg_name)
275
+ param.set("direction", "in")
276
+
277
+ # Docstring as ownedComment
278
+ docstring = method.get("docstring", "")
279
+ if docstring:
280
+ comment = ET.SubElement(op, "ownedComment")
281
+ comment.set("xmi:id", f"cmt-{uuid.uuid4()}")
282
+ body = ET.SubElement(comment, "body")
283
+ body.text = docstring
284
+
285
+ # Bases as generalization
286
+ for base_name in props.get("bases", []):
287
+ gen = ET.SubElement(pe, "generalization")
288
+ gen.set("xmi:type", "uml:Generalization")
289
+ gen.set("xmi:id", f"gen-{uuid.uuid4()}")
290
+ gen.set("general", base_name)
291
+
292
+ elif etype == "function":
293
+ # Top-level function as a stereotyped class with a single operation
294
+ pe = ET.SubElement(pkg, "packagedElement")
295
+ pe.set("xmi:type", "uml:Class")
296
+ pe.set("xmi:id", xmi_id)
297
+ pe.set("name", name)
298
+
299
+ op = ET.SubElement(pe, "ownedOperation")
300
+ op.set("xmi:type", "uml:Operation")
301
+ op.set("xmi:id", f"op-{uuid.uuid4()}")
302
+ op.set("name", name)
303
+ op.set("visibility", "public")
304
+
305
+ for arg_name in props.get("args", []):
306
+ param = ET.SubElement(op, "ownedParameter")
307
+ param.set("xmi:id", f"param-{uuid.uuid4()}")
308
+ param.set("name", arg_name)
309
+ param.set("direction", "in")
310
+
311
+ docstring = props.get("docstring", "")
312
+ if docstring:
313
+ comment = ET.SubElement(pe, "ownedComment")
314
+ comment.set("xmi:id", f"cmt-{uuid.uuid4()}")
315
+ body_el = ET.SubElement(comment, "body")
316
+ body_el.text = docstring
317
+
318
+ elif etype == "interface":
319
+ pe = ET.SubElement(pkg, "packagedElement")
320
+ pe.set("xmi:type", "uml:Interface")
321
+ pe.set("xmi:id", xmi_id)
322
+ pe.set("name", name)
323
+
324
+ for method in props.get("methods", []):
325
+ op = ET.SubElement(pe, "ownedOperation")
326
+ op.set("xmi:type", "uml:Operation")
327
+ op.set("xmi:id", f"op-{uuid.uuid4()}")
328
+ op.set("name", method.get("name", ""))
329
+
330
+ ET.indent(ET.ElementTree(root), space=" ")
331
+ return ET.tostring(root, encoding="unicode", xml_declaration=True)
332
+
333
+
334
+ # ---------------------------------------------------------------------------
335
+ # Drift detection
336
+ # ---------------------------------------------------------------------------
337
+
338
+ def detect_drift(project_id: str, db_path: Optional[Path] = None) -> dict:
339
+ """Compare current model_code_mappings hashes with actual file hashes.
340
+
341
+ For each mapping:
342
+ 1. Recompute SHA-256 of the code file (if it exists)
343
+ 2. Compare with stored code_hash
344
+ 3. Check if model's source_hash has changed (re-read sysml_elements.source_hash)
345
+ 4. Determine status: synced, model_ahead, code_ahead, conflict, unknown
346
+
347
+ Updates model_code_mappings.sync_status in place.
348
+
349
+ Returns::
350
+
351
+ {
352
+ "total_mappings": int,
353
+ "synced": int,
354
+ "model_ahead": int,
355
+ "code_ahead": int,
356
+ "conflict": int,
357
+ "unknown": int,
358
+ "missing_files": int,
359
+ "details": [...]
360
+ }
361
+ """
362
+ conn = _get_connection(db_path)
363
+ cursor = conn.cursor()
364
+
365
+ cursor.execute(
366
+ """SELECT mcm.id, mcm.sysml_element_id, mcm.code_path, mcm.code_type,
367
+ mcm.model_hash, mcm.code_hash, mcm.sync_status,
368
+ se.source_hash AS current_model_hash, se.name AS element_name
369
+ FROM model_code_mappings mcm
370
+ LEFT JOIN sysml_elements se ON mcm.sysml_element_id = se.id
371
+ WHERE mcm.project_id = ?""",
372
+ (project_id,),
373
+ )
374
+ rows = [dict(r) for r in cursor.fetchall()]
375
+
376
+ counts = {
377
+ "total_mappings": len(rows),
378
+ "synced": 0,
379
+ "model_ahead": 0,
380
+ "code_ahead": 0,
381
+ "conflict": 0,
382
+ "unknown": 0,
383
+ "missing_files": 0,
384
+ }
385
+ details: List[Dict[str, Any]] = []
386
+
387
+ for row in rows:
388
+ mapping_id = row["id"]
389
+ code_path = row["code_path"]
390
+ stored_code_hash = row["code_hash"] or ""
391
+ stored_model_hash = row["model_hash"] or ""
392
+ current_model_hash = row["current_model_hash"] or ""
393
+ element_name = row["element_name"] or ""
394
+
395
+ # Recompute code file hash
396
+ current_code_hash = _compute_file_hash(code_path)
397
+ file_exists = current_code_hash != ""
398
+
399
+ if not file_exists:
400
+ new_status = "unknown"
401
+ counts["missing_files"] += 1
402
+ counts["unknown"] += 1
403
+ else:
404
+ code_changed = current_code_hash != stored_code_hash
405
+ model_changed = current_model_hash != stored_model_hash
406
+
407
+ if code_changed and model_changed:
408
+ new_status = "conflict"
409
+ counts["conflict"] += 1
410
+ elif model_changed and not code_changed:
411
+ new_status = "model_ahead"
412
+ counts["model_ahead"] += 1
413
+ elif code_changed and not model_changed:
414
+ new_status = "code_ahead"
415
+ counts["code_ahead"] += 1
416
+ else:
417
+ new_status = "synced"
418
+ counts["synced"] += 1
419
+
420
+ # Update sync_status in DB
421
+ cursor.execute(
422
+ """UPDATE model_code_mappings
423
+ SET sync_status = ?, last_synced = ?
424
+ WHERE id = ?""",
425
+ (new_status, _ts(), mapping_id),
426
+ )
427
+
428
+ details.append({
429
+ "mapping_id": mapping_id,
430
+ "element_name": element_name,
431
+ "code_path": code_path,
432
+ "code_type": row["code_type"],
433
+ "previous_status": row["sync_status"],
434
+ "new_status": new_status,
435
+ "file_exists": file_exists,
436
+ "code_changed": current_code_hash != stored_code_hash if file_exists else None,
437
+ "model_changed": current_model_hash != stored_model_hash,
438
+ })
439
+
440
+ conn.commit()
441
+ conn.close()
442
+
443
+ counts["details"] = details
444
+ return counts
445
+
446
+
447
+ # ---------------------------------------------------------------------------
448
+ # Sync model -> code
449
+ # ---------------------------------------------------------------------------
450
+
451
+ def sync_model_to_code(project_id: str, language: str = "python",
452
+ db_path: Optional[Path] = None) -> dict:
453
+ """Sync model changes to code.
454
+
455
+ Steps:
456
+ 1. Re-import latest XMI if a new file is available in model_imports
457
+ 2. For each model_ahead mapping: regenerate code for that element
458
+ 3. For new elements (in model but no mapping): generate new code files
459
+ 4. For deleted elements (mapping exists but element gone): mark as orphaned
460
+ 5. Update model_code_mappings hashes and status
461
+ 6. Log audit trail
462
+
463
+ Returns::
464
+
465
+ {
466
+ "files_updated": int,
467
+ "files_created": int,
468
+ "files_orphaned": int,
469
+ "errors": int,
470
+ "error_details": [...]
471
+ }
472
+ """
473
+ conn = _get_connection(db_path)
474
+ cursor = conn.cursor()
475
+ errors: List[str] = []
476
+ files_updated = 0
477
+ files_created = 0
478
+ files_orphaned = 0
479
+
480
+ # Step 1: Check for latest XMI import and re-import if newer file exists
481
+ # (Delegated to reimport_xmi if caller has a new file; here we just check
482
+ # the most recent import hash to detect if anything changed.)
483
+
484
+ # Step 2: For each model_ahead mapping, regenerate code
485
+ cursor.execute(
486
+ """SELECT mcm.id, mcm.sysml_element_id, mcm.code_path, mcm.code_type,
487
+ se.name, se.element_type, se.properties, se.description,
488
+ se.source_hash, se.stereotype
489
+ FROM model_code_mappings mcm
490
+ JOIN sysml_elements se ON mcm.sysml_element_id = se.id
491
+ WHERE mcm.project_id = ? AND mcm.sync_status = 'model_ahead'""",
492
+ (project_id,),
493
+ )
494
+ model_ahead_rows = [dict(r) for r in cursor.fetchall()]
495
+
496
+ for row in model_ahead_rows:
497
+ try:
498
+ code_content = _generate_code_from_element(
499
+ name=row["name"],
500
+ element_type=row["element_type"],
501
+ properties=row["properties"],
502
+ description=row["description"] or "",
503
+ stereotype=row["stereotype"] or "",
504
+ language=language,
505
+ )
506
+ code_path = Path(row["code_path"])
507
+ code_path.parent.mkdir(parents=True, exist_ok=True)
508
+ code_path.write_text(code_content, encoding="utf-8")
509
+
510
+ new_code_hash = _compute_file_hash(str(code_path))
511
+ cursor.execute(
512
+ """UPDATE model_code_mappings
513
+ SET sync_status = 'synced', code_hash = ?, model_hash = ?,
514
+ last_synced = ?
515
+ WHERE id = ?""",
516
+ (new_code_hash, row["source_hash"], _ts(), row["id"]),
517
+ )
518
+ files_updated += 1
519
+ except Exception as exc:
520
+ errors.append(f"Failed to update {row['code_path']}: {exc}")
521
+
522
+ # Step 3: New elements with no mapping — generate new code files
523
+ cursor.execute(
524
+ """SELECT se.id, se.name, se.element_type, se.properties,
525
+ se.description, se.source_hash, se.stereotype
526
+ FROM sysml_elements se
527
+ WHERE se.project_id = ?
528
+ AND se.id NOT IN (
529
+ SELECT sysml_element_id FROM model_code_mappings
530
+ WHERE project_id = ?
531
+ )
532
+ AND se.element_type IN ('block', 'interface_block', 'activity')""",
533
+ (project_id, project_id),
534
+ )
535
+ new_elements = [dict(r) for r in cursor.fetchall()]
536
+
537
+ for elem in new_elements:
538
+ try:
539
+ safe_name = elem["name"].lower().replace(" ", "_").replace("-", "_")
540
+ if language == "python":
541
+ code_path = BASE_DIR / "output" / project_id / f"{safe_name}.py"
542
+ else:
543
+ code_path = BASE_DIR / "output" / project_id / f"{safe_name}.{language}"
544
+
545
+ code_content = _generate_code_from_element(
546
+ name=elem["name"],
547
+ element_type=elem["element_type"],
548
+ properties=elem["properties"],
549
+ description=elem["description"] or "",
550
+ stereotype=elem["stereotype"] or "",
551
+ language=language,
552
+ )
553
+ code_path.parent.mkdir(parents=True, exist_ok=True)
554
+ code_path.write_text(code_content, encoding="utf-8")
555
+
556
+ new_code_hash = _compute_file_hash(str(code_path))
557
+ cursor.execute(
558
+ """INSERT INTO model_code_mappings
559
+ (project_id, sysml_element_id, code_path, code_type,
560
+ mapping_direction, sync_status, model_hash, code_hash,
561
+ last_synced)
562
+ VALUES (?, ?, ?, ?, 'model_to_code', 'synced', ?, ?, ?)""",
563
+ (
564
+ project_id,
565
+ elem["id"],
566
+ str(code_path),
567
+ "class" if elem["element_type"] in ("block", "interface_block") else "module",
568
+ elem["source_hash"],
569
+ new_code_hash,
570
+ _ts(),
571
+ ),
572
+ )
573
+ files_created += 1
574
+ except Exception as exc:
575
+ errors.append(f"Failed to create code for '{elem['name']}': {exc}")
576
+
577
+ # Step 4: Orphaned mappings — element gone from sysml_elements
578
+ cursor.execute(
579
+ """SELECT mcm.id, mcm.code_path
580
+ FROM model_code_mappings mcm
581
+ WHERE mcm.project_id = ?
582
+ AND mcm.sysml_element_id NOT IN (
583
+ SELECT id FROM sysml_elements WHERE project_id = ?
584
+ )
585
+ AND mcm.sync_status != 'unknown'""",
586
+ (project_id, project_id),
587
+ )
588
+ orphaned_rows = [dict(r) for r in cursor.fetchall()]
589
+
590
+ for row in orphaned_rows:
591
+ cursor.execute(
592
+ """UPDATE model_code_mappings
593
+ SET sync_status = 'unknown', last_synced = ?
594
+ WHERE id = ?""",
595
+ (_ts(), row["id"]),
596
+ )
597
+ files_orphaned += 1
598
+
599
+ conn.commit()
600
+ conn.close()
601
+
602
+ # Step 6: Audit trail
603
+ if _HAS_AUDIT:
604
+ try:
605
+ log_event(
606
+ event_type="code_generated",
607
+ actor="icdev-sync-engine",
608
+ action=(
609
+ f"Model-to-code sync for project {project_id}: "
610
+ f"{files_updated} updated, {files_created} created, "
611
+ f"{files_orphaned} orphaned"
612
+ ),
613
+ project_id=project_id,
614
+ details={
615
+ "files_updated": files_updated,
616
+ "files_created": files_created,
617
+ "files_orphaned": files_orphaned,
618
+ "errors": len(errors),
619
+ "language": language,
620
+ },
621
+ classification="CUI",
622
+ db_path=Path(db_path) if db_path else None,
623
+ )
624
+ except Exception:
625
+ pass
626
+
627
+ return {
628
+ "files_updated": files_updated,
629
+ "files_created": files_created,
630
+ "files_orphaned": files_orphaned,
631
+ "errors": len(errors),
632
+ "error_details": errors,
633
+ }
634
+
635
+
636
+ def _generate_code_from_element(name: str, element_type: str, properties: str,
637
+ description: str, stereotype: str,
638
+ language: str) -> str:
639
+ """Generate source code from a SysML element definition.
640
+
641
+ Currently supports Python only. Produces a module with CUI markings,
642
+ a class stub with attributes and method stubs extracted from the element's
643
+ properties JSON.
644
+ """
645
+ props = {}
646
+ if properties:
647
+ try:
648
+ props = json.loads(properties) if isinstance(properties, str) else properties
649
+ except (json.JSONDecodeError, TypeError):
650
+ props = {}
651
+
652
+ if language != "python":
653
+ # Fallback: produce a commented stub
654
+ lines = [
655
+ "// CUI // SP-CTI",
656
+ f"// Auto-generated from SysML element: {name}",
657
+ f"// Element type: {element_type}",
658
+ f"// Stereotype: {stereotype}",
659
+ f"// Description: {description}",
660
+ "// CUI // SP-CTI",
661
+ ]
662
+ return "\n".join(lines)
663
+
664
+ lines = [
665
+ "# CUI // SP-CTI",
666
+ f'"""Auto-generated from SysML {element_type}: {name}.',
667
+ "",
668
+ ]
669
+ if description:
670
+ lines.append(f"{description}")
671
+ lines.append("")
672
+ lines.append(f'Stereotype: {stereotype or "N/A"}')
673
+ lines.append('"""')
674
+ lines.append("")
675
+
676
+ # Class name: PascalCase from the element name
677
+ class_name = "".join(word.capitalize() for word in name.replace("-", " ").replace("_", " ").split())
678
+
679
+ if element_type in ("block", "interface_block"):
680
+ # Extract attributes from properties
681
+ attributes = props.get("attributes", [])
682
+ ports = props.get("ports", [])
683
+ flow_props = props.get("flow_properties", [])
684
+
685
+ lines.append(f"class {class_name}:")
686
+ lines.append(f' """{description or name}"""')
687
+ lines.append("")
688
+
689
+ # __init__ with attributes
690
+ init_attrs = attributes + flow_props
691
+ if init_attrs:
692
+ init_args = ", ".join(
693
+ a.get("name", "unnamed") for a in init_attrs
694
+ if a.get("name")
695
+ )
696
+ lines.append(f" def __init__(self, {init_args}):")
697
+ for attr in init_attrs:
698
+ attr_name = attr.get("name", "")
699
+ if attr_name:
700
+ lines.append(f" self.{attr_name} = {attr_name}")
701
+ lines.append("")
702
+ else:
703
+ lines.append(" def __init__(self):")
704
+ lines.append(" pass")
705
+ lines.append("")
706
+
707
+ # Port properties as methods
708
+ for port in ports:
709
+ port_name = port.get("name", "port")
710
+ lines.append(f" def get_{port_name}(self):")
711
+ lines.append(f' """Access port: {port_name}."""')
712
+ lines.append(" raise NotImplementedError")
713
+ lines.append("")
714
+
715
+ elif element_type == "activity":
716
+ # Activity -> module with functions for each action
717
+ actions = props.get("actions", [])
718
+ if actions:
719
+ for action in actions:
720
+ action_name = action.get("name", "").lower().replace(" ", "_").replace("-", "_")
721
+ if not action_name:
722
+ continue
723
+ lines.append(f"def {action_name}():")
724
+ lines.append(f' """{action.get("name", "")} action."""')
725
+ lines.append(" raise NotImplementedError")
726
+ lines.append("")
727
+ else:
728
+ lines.append(f"def execute_{class_name.lower()}():")
729
+ lines.append(f' """{description or name}"""')
730
+ lines.append(" raise NotImplementedError")
731
+ lines.append("")
732
+
733
+ else:
734
+ # Generic stub
735
+ lines.append(f"class {class_name}:")
736
+ lines.append(f' """{description or name}"""')
737
+ lines.append("")
738
+ lines.append(" def __init__(self):")
739
+ lines.append(" pass")
740
+ lines.append("")
741
+
742
+ lines.append("# CUI // SP-CTI")
743
+ return "\n".join(lines)
744
+
745
+
746
+ # ---------------------------------------------------------------------------
747
+ # Sync code -> model
748
+ # ---------------------------------------------------------------------------
749
+
750
+ def sync_code_to_model(project_id: str, output_path: str,
751
+ db_path: Optional[Path] = None) -> dict:
752
+ """Reverse sync: analyze code and generate XMI fragment for Cameo import.
753
+
754
+ Steps:
755
+ 1. For each code_ahead mapping: parse Python AST to extract class/function info
756
+ 2. For new code files (not in any mapping): detect classes/functions
757
+ 3. Generate XMI fragment with new/modified elements
758
+ 4. Output as .xmi file for manual import into Cameo
759
+ 5. Log audit trail
760
+
761
+ Returns::
762
+
763
+ {
764
+ "xmi_file": str,
765
+ "elements_exported": int,
766
+ "new_elements": int,
767
+ "modified_elements": int,
768
+ "errors": [...]
769
+ }
770
+ """
771
+ conn = _get_connection(db_path)
772
+ cursor = conn.cursor()
773
+ errors: List[str] = []
774
+ elements_for_xmi: List[Dict[str, Any]] = []
775
+ modified_count = 0
776
+ new_count = 0
777
+
778
+ # Step 1: Process code_ahead mappings
779
+ cursor.execute(
780
+ """SELECT mcm.id, mcm.sysml_element_id, mcm.code_path, mcm.code_type,
781
+ se.name, se.xmi_id
782
+ FROM model_code_mappings mcm
783
+ LEFT JOIN sysml_elements se ON mcm.sysml_element_id = se.id
784
+ WHERE mcm.project_id = ? AND mcm.sync_status = 'code_ahead'""",
785
+ (project_id,),
786
+ )
787
+ code_ahead_rows = [dict(r) for r in cursor.fetchall()]
788
+
789
+ for row in code_ahead_rows:
790
+ code_path = row["code_path"]
791
+ try:
792
+ parsed = _parse_python_ast(code_path)
793
+
794
+ for cls in parsed["classes"]:
795
+ elements_for_xmi.append({
796
+ "name": cls["name"],
797
+ "element_type": "class",
798
+ "xmi_id": row.get("xmi_id") or f"elem-{uuid.uuid4()}",
799
+ "properties": {
800
+ "methods": cls["methods"],
801
+ "attributes": cls["attributes"],
802
+ "bases": cls["bases"],
803
+ },
804
+ })
805
+ modified_count += 1
806
+
807
+ for func in parsed["functions"]:
808
+ elements_for_xmi.append({
809
+ "name": func["name"],
810
+ "element_type": "function",
811
+ "xmi_id": f"func-{uuid.uuid4()}",
812
+ "properties": {
813
+ "args": func["args"],
814
+ "docstring": func["docstring"],
815
+ },
816
+ })
817
+ modified_count += 1
818
+
819
+ # Update mapping: store the current code hash
820
+ new_hash = _compute_file_hash(code_path)
821
+ cursor.execute(
822
+ """UPDATE model_code_mappings
823
+ SET code_hash = ?, last_synced = ?
824
+ WHERE id = ?""",
825
+ (new_hash, _ts(), row["id"]),
826
+ )
827
+ except Exception as exc:
828
+ errors.append(f"Failed to parse {code_path}: {exc}")
829
+
830
+ # Step 2: Find unmapped code files in the project output directory
831
+ project_output_dir = BASE_DIR / "output" / project_id
832
+ if project_output_dir.exists():
833
+ cursor.execute(
834
+ "SELECT code_path FROM model_code_mappings WHERE project_id = ?",
835
+ (project_id,),
836
+ )
837
+ mapped_paths = {r["code_path"] for r in cursor.fetchall()}
838
+
839
+ for py_file in project_output_dir.rglob("*.py"):
840
+ if str(py_file) in mapped_paths:
841
+ continue
842
+ try:
843
+ parsed = _parse_python_ast(str(py_file))
844
+ for cls in parsed["classes"]:
845
+ elements_for_xmi.append({
846
+ "name": cls["name"],
847
+ "element_type": "class",
848
+ "xmi_id": f"new-{uuid.uuid4()}",
849
+ "properties": {
850
+ "methods": cls["methods"],
851
+ "attributes": cls["attributes"],
852
+ "bases": cls["bases"],
853
+ },
854
+ })
855
+ new_count += 1
856
+
857
+ for func in parsed["functions"]:
858
+ elements_for_xmi.append({
859
+ "name": func["name"],
860
+ "element_type": "function",
861
+ "xmi_id": f"new-{uuid.uuid4()}",
862
+ "properties": {
863
+ "args": func["args"],
864
+ "docstring": func["docstring"],
865
+ },
866
+ })
867
+ new_count += 1
868
+ except Exception as exc:
869
+ errors.append(f"Failed to scan {py_file}: {exc}")
870
+
871
+ conn.commit()
872
+ conn.close()
873
+
874
+ # Step 3-4: Generate XMI fragment and write to file
875
+ xmi_content = _generate_xmi_fragment(elements_for_xmi)
876
+
877
+ out_path = Path(output_path)
878
+ out_path.parent.mkdir(parents=True, exist_ok=True)
879
+ out_path.write_text(xmi_content, encoding="utf-8")
880
+
881
+ # Step 5: Audit trail
882
+ if _HAS_AUDIT:
883
+ try:
884
+ log_event(
885
+ event_type="code_generated",
886
+ actor="icdev-sync-engine",
887
+ action=(
888
+ f"Code-to-model sync for project {project_id}: "
889
+ f"exported {len(elements_for_xmi)} elements to {output_path}"
890
+ ),
891
+ project_id=project_id,
892
+ details={
893
+ "xmi_file": str(out_path),
894
+ "elements_exported": len(elements_for_xmi),
895
+ "modified_elements": modified_count,
896
+ "new_elements": new_count,
897
+ },
898
+ affected_files=[str(out_path)],
899
+ classification="CUI",
900
+ db_path=Path(db_path) if db_path else None,
901
+ )
902
+ except Exception:
903
+ pass
904
+
905
+ return {
906
+ "xmi_file": str(out_path),
907
+ "elements_exported": len(elements_for_xmi),
908
+ "new_elements": new_count,
909
+ "modified_elements": modified_count,
910
+ "errors": errors,
911
+ }
912
+
913
+
914
+ # ---------------------------------------------------------------------------
915
+ # Conflict resolution
916
+ # ---------------------------------------------------------------------------
917
+
918
+ def resolve_conflict(project_id: str, mapping_id: int, resolution: str,
919
+ db_path: Optional[Path] = None) -> dict:
920
+ """Resolve a model/code conflict for a specific mapping.
921
+
922
+ Args:
923
+ resolution: One of 'keep_model', 'keep_code', or 'merge'.
924
+ - keep_model: Regenerate code from model, update code_hash.
925
+ - keep_code: Update model_hash to current value (model stale until
926
+ re-imported). Does NOT modify the model file.
927
+ - merge: Mark as bidirectional; leave both sides as-is for
928
+ manual merge.
929
+
930
+ Returns::
931
+
932
+ {"mapping_id": int, "resolution": str, "status": str}
933
+ """
934
+ conn = _get_connection(db_path)
935
+ cursor = conn.cursor()
936
+
937
+ cursor.execute(
938
+ """SELECT mcm.*, se.name, se.element_type, se.properties,
939
+ se.description, se.source_hash, se.stereotype
940
+ FROM model_code_mappings mcm
941
+ LEFT JOIN sysml_elements se ON mcm.sysml_element_id = se.id
942
+ WHERE mcm.id = ? AND mcm.project_id = ?""",
943
+ (mapping_id, project_id),
944
+ )
945
+ row = cursor.fetchone()
946
+
947
+ if not row:
948
+ conn.close()
949
+ return {
950
+ "mapping_id": mapping_id,
951
+ "resolution": resolution,
952
+ "status": "error",
953
+ "error": f"Mapping #{mapping_id} not found for project {project_id}",
954
+ }
955
+
956
+ row = dict(row)
957
+ status = "resolved"
958
+
959
+ try:
960
+ if resolution == "keep_model":
961
+ # Regenerate code from model
962
+ code_content = _generate_code_from_element(
963
+ name=row["name"] or "",
964
+ element_type=row["element_type"] or "block",
965
+ properties=row["properties"] or "{}",
966
+ description=row["description"] or "",
967
+ stereotype=row["stereotype"] or "",
968
+ language="python",
969
+ )
970
+ code_path = Path(row["code_path"])
971
+ code_path.parent.mkdir(parents=True, exist_ok=True)
972
+ code_path.write_text(code_content, encoding="utf-8")
973
+
974
+ new_code_hash = _compute_file_hash(str(code_path))
975
+ cursor.execute(
976
+ """UPDATE model_code_mappings
977
+ SET sync_status = 'synced', code_hash = ?,
978
+ model_hash = ?, mapping_direction = 'model_to_code',
979
+ last_synced = ?
980
+ WHERE id = ?""",
981
+ (new_code_hash, row["source_hash"], _ts(), mapping_id),
982
+ )
983
+
984
+ elif resolution == "keep_code":
985
+ # Update model_hash to match current source_hash so it looks synced
986
+ # The model side remains stale until manually re-imported
987
+ current_code_hash = _compute_file_hash(row["code_path"])
988
+ cursor.execute(
989
+ """UPDATE model_code_mappings
990
+ SET sync_status = 'synced', code_hash = ?,
991
+ model_hash = ?, mapping_direction = 'code_to_model',
992
+ last_synced = ?
993
+ WHERE id = ?""",
994
+ (current_code_hash, row["source_hash"], _ts(), mapping_id),
995
+ )
996
+
997
+ elif resolution == "merge":
998
+ cursor.execute(
999
+ """UPDATE model_code_mappings
1000
+ SET sync_status = 'synced', mapping_direction = 'bidirectional',
1001
+ last_synced = ?
1002
+ WHERE id = ?""",
1003
+ (_ts(), mapping_id),
1004
+ )
1005
+
1006
+ else:
1007
+ status = "error"
1008
+
1009
+ except Exception as exc:
1010
+ status = "error"
1011
+ conn.close()
1012
+ return {
1013
+ "mapping_id": mapping_id,
1014
+ "resolution": resolution,
1015
+ "status": status,
1016
+ "error": str(exc),
1017
+ }
1018
+
1019
+ conn.commit()
1020
+ conn.close()
1021
+
1022
+ # Audit trail
1023
+ if _HAS_AUDIT:
1024
+ try:
1025
+ log_event(
1026
+ event_type="decision_made",
1027
+ actor="icdev-sync-engine",
1028
+ action=(
1029
+ f"Conflict resolved for mapping #{mapping_id} in {project_id}: "
1030
+ f"{resolution}"
1031
+ ),
1032
+ project_id=project_id,
1033
+ details={
1034
+ "mapping_id": mapping_id,
1035
+ "resolution": resolution,
1036
+ "code_path": row["code_path"],
1037
+ "element_name": row.get("name", ""),
1038
+ },
1039
+ classification="CUI",
1040
+ db_path=Path(db_path) if db_path else None,
1041
+ )
1042
+ except Exception:
1043
+ pass
1044
+
1045
+ return {
1046
+ "mapping_id": mapping_id,
1047
+ "resolution": resolution,
1048
+ "status": status,
1049
+ }
1050
+
1051
+
1052
+ # ---------------------------------------------------------------------------
1053
+ # Re-import XMI
1054
+ # ---------------------------------------------------------------------------
1055
+
1056
+ def reimport_xmi(project_id: str, file_path: str,
1057
+ db_path: Optional[Path] = None) -> dict:
1058
+ """Re-import XMI after Cameo updates, merging with existing elements.
1059
+
1060
+ Steps:
1061
+ 1. Parse new XMI file
1062
+ 2. Compare with existing sysml_elements by xmi_id
1063
+ 3. Update changed elements, add new ones, mark deleted ones
1064
+ 4. Update model_code_mappings for affected elements
1065
+ 5. Log audit trail
1066
+
1067
+ Returns::
1068
+
1069
+ {"updated": int, "added": int, "deleted": int, "unchanged": int}
1070
+ """
1071
+ # Lazy import xmi_parser to avoid circular dependencies
1072
+ try:
1073
+ from icdev.tools.mbse.xmi_parser import parse_xmi, _file_hash # type: ignore
1074
+ except ImportError:
1075
+ # Fallback: use local file hash
1076
+ parse_xmi = None
1077
+ _file_hash = _compute_file_hash
1078
+
1079
+ if parse_xmi is None:
1080
+ return {
1081
+ "updated": 0, "added": 0, "deleted": 0, "unchanged": 0,
1082
+ "error": "xmi_parser not available. Ensure tools/mbse/xmi_parser.py exists.",
1083
+ }
1084
+
1085
+ # Step 1: Parse new XMI
1086
+ try:
1087
+ parsed = parse_xmi(file_path)
1088
+ except Exception as exc:
1089
+ return {
1090
+ "updated": 0, "added": 0, "deleted": 0, "unchanged": 0,
1091
+ "error": f"XMI parse error: {exc}",
1092
+ }
1093
+
1094
+ new_elements = parsed["elements"]
1095
+ new_source_hash = parsed["metadata"]["file_hash"]
1096
+ timestamp = _ts()
1097
+
1098
+ conn = _get_connection(db_path)
1099
+ cursor = conn.cursor()
1100
+
1101
+ # Step 2: Load existing elements by xmi_id
1102
+ cursor.execute(
1103
+ "SELECT id, xmi_id, source_hash FROM sysml_elements WHERE project_id = ?",
1104
+ (project_id,),
1105
+ )
1106
+ existing = {r["xmi_id"]: dict(r) for r in cursor.fetchall()}
1107
+
1108
+ updated = 0
1109
+ added = 0
1110
+ deleted = 0
1111
+ unchanged = 0
1112
+
1113
+ new_xmi_ids = set()
1114
+
1115
+ # Step 3: Process parsed elements
1116
+ for elem in new_elements:
1117
+ xmi_id = elem.get("xmi_id", "")
1118
+ new_xmi_ids.add(xmi_id)
1119
+
1120
+ if xmi_id in existing:
1121
+ # Compare source_hash to detect changes
1122
+ old_hash = existing[xmi_id].get("source_hash", "")
1123
+ if old_hash != new_source_hash:
1124
+ # Element changed — update it
1125
+ cursor.execute(
1126
+ """UPDATE sysml_elements
1127
+ SET name = ?, element_type = ?, qualified_name = ?,
1128
+ stereotype = ?, description = ?, properties = ?,
1129
+ diagram_type = ?, source_file = ?,
1130
+ source_hash = ?, updated_at = ?
1131
+ WHERE project_id = ? AND xmi_id = ?""",
1132
+ (
1133
+ elem["name"],
1134
+ elem["element_type"],
1135
+ elem.get("qualified_name", ""),
1136
+ elem.get("stereotype", ""),
1137
+ elem.get("description", ""),
1138
+ elem.get("properties", "{}"),
1139
+ elem.get("diagram_type"),
1140
+ elem.get("source_file", ""),
1141
+ new_source_hash,
1142
+ timestamp,
1143
+ project_id,
1144
+ xmi_id,
1145
+ ),
1146
+ )
1147
+ # Mark associated model_code_mappings as model_ahead
1148
+ elem_db_id = existing[xmi_id]["id"]
1149
+ cursor.execute(
1150
+ """UPDATE model_code_mappings
1151
+ SET sync_status = 'model_ahead', model_hash = ?
1152
+ WHERE project_id = ? AND sysml_element_id = ?""",
1153
+ (new_source_hash, project_id, elem_db_id),
1154
+ )
1155
+ updated += 1
1156
+ else:
1157
+ unchanged += 1
1158
+ else:
1159
+ # New element — insert
1160
+ elem_id = elem.get("id", _new_id())
1161
+ try:
1162
+ cursor.execute(
1163
+ """INSERT INTO sysml_elements
1164
+ (id, project_id, xmi_id, element_type, name,
1165
+ qualified_name, parent_id, stereotype, description,
1166
+ properties, diagram_type, source_file, source_hash,
1167
+ imported_at, updated_at)
1168
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
1169
+ (
1170
+ elem_id,
1171
+ project_id,
1172
+ xmi_id,
1173
+ elem["element_type"],
1174
+ elem["name"],
1175
+ elem.get("qualified_name", ""),
1176
+ elem.get("parent_id"),
1177
+ elem.get("stereotype", ""),
1178
+ elem.get("description", ""),
1179
+ elem.get("properties", "{}"),
1180
+ elem.get("diagram_type"),
1181
+ elem.get("source_file", ""),
1182
+ new_source_hash,
1183
+ timestamp,
1184
+ timestamp,
1185
+ ),
1186
+ )
1187
+ added += 1
1188
+ except sqlite3.IntegrityError:
1189
+ # Duplicate — treat as update
1190
+ unchanged += 1
1191
+
1192
+ # Step 3 (cont.): Mark elements missing from new XMI as deleted
1193
+ for xmi_id, existing_elem in existing.items():
1194
+ if xmi_id not in new_xmi_ids:
1195
+ # Mark as deleted by updating a description note (we do NOT delete)
1196
+ cursor.execute(
1197
+ """UPDATE sysml_elements
1198
+ SET description = description || ' [DELETED in reimport ' || ? || ']',
1199
+ updated_at = ?
1200
+ WHERE id = ?""",
1201
+ (timestamp, timestamp, existing_elem["id"]),
1202
+ )
1203
+ # Mark associated mappings as unknown
1204
+ cursor.execute(
1205
+ """UPDATE model_code_mappings
1206
+ SET sync_status = 'unknown'
1207
+ WHERE project_id = ? AND sysml_element_id = ?""",
1208
+ (project_id, existing_elem["id"]),
1209
+ )
1210
+ deleted += 1
1211
+
1212
+ # Step 4: Record in model_imports
1213
+ cursor.execute(
1214
+ """INSERT INTO model_imports
1215
+ (project_id, import_type, source_file, source_hash,
1216
+ elements_imported, relationships_imported, errors,
1217
+ error_details, status, imported_by, imported_at)
1218
+ VALUES (?, 'xmi_reimport', ?, ?, ?, 0, 0, NULL, 'completed',
1219
+ 'icdev-sync-engine', ?)""",
1220
+ (
1221
+ project_id,
1222
+ str(Path(file_path).name),
1223
+ new_source_hash,
1224
+ updated + added,
1225
+ timestamp,
1226
+ ),
1227
+ )
1228
+
1229
+ conn.commit()
1230
+ conn.close()
1231
+
1232
+ # Step 5: Audit trail
1233
+ if _HAS_AUDIT:
1234
+ try:
1235
+ log_event(
1236
+ event_type="compliance_check",
1237
+ actor="icdev-sync-engine",
1238
+ action=(
1239
+ f"XMI reimport for {project_id}: "
1240
+ f"{updated} updated, {added} added, {deleted} deleted, "
1241
+ f"{unchanged} unchanged"
1242
+ ),
1243
+ project_id=project_id,
1244
+ details={
1245
+ "file": file_path,
1246
+ "source_hash": new_source_hash,
1247
+ "updated": updated,
1248
+ "added": added,
1249
+ "deleted": deleted,
1250
+ "unchanged": unchanged,
1251
+ },
1252
+ affected_files=[file_path],
1253
+ classification="CUI",
1254
+ db_path=Path(db_path) if db_path else None,
1255
+ )
1256
+ except Exception:
1257
+ pass
1258
+
1259
+ return {
1260
+ "updated": updated,
1261
+ "added": added,
1262
+ "deleted": deleted,
1263
+ "unchanged": unchanged,
1264
+ }
1265
+
1266
+
1267
+ # ---------------------------------------------------------------------------
1268
+ # Re-import ReqIF
1269
+ # ---------------------------------------------------------------------------
1270
+
1271
+ def reimport_reqif(project_id: str, file_path: str,
1272
+ db_path: Optional[Path] = None) -> dict:
1273
+ """Re-import ReqIF after DOORS updates, merging with existing requirements.
1274
+
1275
+ Similar to reimport_xmi but operates on the doors_requirements table.
1276
+
1277
+ Steps:
1278
+ 1. Parse new ReqIF file
1279
+ 2. Compare with existing doors_requirements by doors_id
1280
+ 3. Update changed requirements, add new ones, mark deleted ones
1281
+ 4. Log audit trail
1282
+
1283
+ Returns::
1284
+
1285
+ {"updated": int, "added": int, "deleted": int, "unchanged": int}
1286
+ """
1287
+ try:
1288
+ from icdev.tools.mbse.reqif_parser import parse_reqif # type: ignore
1289
+ except ImportError:
1290
+ parse_reqif = None
1291
+
1292
+ if parse_reqif is None:
1293
+ return {
1294
+ "updated": 0, "added": 0, "deleted": 0, "unchanged": 0,
1295
+ "error": "reqif_parser not available. Ensure tools/mbse/reqif_parser.py exists.",
1296
+ }
1297
+
1298
+ # Step 1: Parse new ReqIF
1299
+ try:
1300
+ parsed = parse_reqif(file_path)
1301
+ except Exception as exc:
1302
+ return {
1303
+ "updated": 0, "added": 0, "deleted": 0, "unchanged": 0,
1304
+ "error": f"ReqIF parse error: {exc}",
1305
+ }
1306
+
1307
+ new_reqs = parsed["requirements"]
1308
+ source_hash = _compute_file_hash(file_path)
1309
+ timestamp = _ts()
1310
+
1311
+ conn = _get_connection(db_path)
1312
+ cursor = conn.cursor()
1313
+
1314
+ # Step 2: Load existing requirements by doors_id
1315
+ cursor.execute(
1316
+ "SELECT id, doors_id, title, description, priority, requirement_type "
1317
+ "FROM doors_requirements WHERE project_id = ?",
1318
+ (project_id,),
1319
+ )
1320
+ existing = {}
1321
+ for r in cursor.fetchall():
1322
+ row_dict = dict(r)
1323
+ existing[row_dict["doors_id"]] = row_dict
1324
+
1325
+ updated = 0
1326
+ added = 0
1327
+ deleted = 0
1328
+ unchanged = 0
1329
+ new_doors_ids = set()
1330
+
1331
+ # Step 3: Process parsed requirements
1332
+ for req in new_reqs:
1333
+ doors_id = req.get("doors_id", "")
1334
+ if not doors_id:
1335
+ continue
1336
+ new_doors_ids.add(doors_id)
1337
+
1338
+ # Build content fingerprint for change detection
1339
+ new_content = (
1340
+ f"{req.get('title', '')}|{req.get('description', '')}|"
1341
+ f"{req.get('priority', '')}|{req.get('requirement_type', '')}"
1342
+ )
1343
+ new_hash = _content_hash(new_content)
1344
+
1345
+ if doors_id in existing:
1346
+ ex = existing[doors_id]
1347
+ old_content = (
1348
+ f"{ex.get('title', '')}|{ex.get('description', '')}|"
1349
+ f"{ex.get('priority', '')}|{ex.get('requirement_type', '')}"
1350
+ )
1351
+ old_hash = _content_hash(old_content)
1352
+
1353
+ if new_hash != old_hash:
1354
+ cursor.execute(
1355
+ """UPDATE doors_requirements
1356
+ SET title = ?, description = ?, priority = ?,
1357
+ requirement_type = ?, source_hash = ?, updated_at = ?
1358
+ WHERE project_id = ? AND doors_id = ?""",
1359
+ (
1360
+ req.get("title", ""),
1361
+ req.get("description", ""),
1362
+ req.get("priority"),
1363
+ req.get("requirement_type"),
1364
+ source_hash,
1365
+ timestamp,
1366
+ project_id,
1367
+ doors_id,
1368
+ ),
1369
+ )
1370
+ updated += 1
1371
+ else:
1372
+ unchanged += 1
1373
+ else:
1374
+ # New requirement — insert
1375
+ req_id = f"dreq-{uuid.uuid4()}"
1376
+ try:
1377
+ cursor.execute(
1378
+ """INSERT INTO doors_requirements
1379
+ (id, project_id, doors_id, title, description,
1380
+ priority, requirement_type, status,
1381
+ source_file, source_hash, imported_at, updated_at)
1382
+ VALUES (?, ?, ?, ?, ?, ?, ?, 'active', ?, ?, ?, ?)""",
1383
+ (
1384
+ req_id,
1385
+ project_id,
1386
+ doors_id,
1387
+ req.get("title", ""),
1388
+ req.get("description", ""),
1389
+ req.get("priority"),
1390
+ req.get("requirement_type"),
1391
+ str(file_path),
1392
+ source_hash,
1393
+ timestamp,
1394
+ timestamp,
1395
+ ),
1396
+ )
1397
+ added += 1
1398
+ except sqlite3.IntegrityError:
1399
+ unchanged += 1
1400
+
1401
+ # Mark requirements not in new file as deleted (soft delete via status)
1402
+ for doors_id in existing:
1403
+ if doors_id not in new_doors_ids:
1404
+ cursor.execute(
1405
+ """UPDATE doors_requirements
1406
+ SET status = 'deleted', updated_at = ?
1407
+ WHERE project_id = ? AND doors_id = ?""",
1408
+ (timestamp, project_id, doors_id),
1409
+ )
1410
+ deleted += 1
1411
+
1412
+ # Record in model_imports
1413
+ cursor.execute(
1414
+ """INSERT INTO model_imports
1415
+ (project_id, import_type, source_file, source_hash,
1416
+ elements_imported, relationships_imported, errors,
1417
+ error_details, status, imported_by, imported_at)
1418
+ VALUES (?, 'reqif_reimport', ?, ?, ?, 0, 0, NULL, 'completed',
1419
+ 'icdev-sync-engine', ?)""",
1420
+ (
1421
+ project_id,
1422
+ str(Path(file_path).name),
1423
+ source_hash,
1424
+ updated + added,
1425
+ timestamp,
1426
+ ),
1427
+ )
1428
+
1429
+ conn.commit()
1430
+ conn.close()
1431
+
1432
+ # Audit trail
1433
+ if _HAS_AUDIT:
1434
+ try:
1435
+ log_event(
1436
+ event_type="compliance_check",
1437
+ actor="icdev-sync-engine",
1438
+ action=(
1439
+ f"ReqIF reimport for {project_id}: "
1440
+ f"{updated} updated, {added} added, {deleted} deleted, "
1441
+ f"{unchanged} unchanged"
1442
+ ),
1443
+ project_id=project_id,
1444
+ details={
1445
+ "file": file_path,
1446
+ "source_hash": source_hash,
1447
+ "updated": updated,
1448
+ "added": added,
1449
+ "deleted": deleted,
1450
+ "unchanged": unchanged,
1451
+ },
1452
+ affected_files=[file_path],
1453
+ classification="CUI",
1454
+ db_path=Path(db_path) if db_path else None,
1455
+ )
1456
+ except Exception:
1457
+ pass
1458
+
1459
+ return {
1460
+ "updated": updated,
1461
+ "added": added,
1462
+ "deleted": deleted,
1463
+ "unchanged": unchanged,
1464
+ }
1465
+
1466
+
1467
+ # ---------------------------------------------------------------------------
1468
+ # Sync report
1469
+ # ---------------------------------------------------------------------------
1470
+
1471
+ def generate_sync_report(project_id: str,
1472
+ db_path: Optional[Path] = None) -> str:
1473
+ """Generate a CUI-marked drift/sync report as markdown.
1474
+
1475
+ Includes:
1476
+ - Summary statistics (synced, model_ahead, code_ahead, conflict, unknown)
1477
+ - Per-mapping details table
1478
+ - Conflict resolution guidance
1479
+ - Timestamps
1480
+ """
1481
+ conn = _get_connection(db_path)
1482
+ cursor = conn.cursor()
1483
+
1484
+ # Fetch all mappings with element names
1485
+ cursor.execute(
1486
+ """SELECT mcm.id, mcm.sysml_element_id, mcm.code_path, mcm.code_type,
1487
+ mcm.mapping_direction, mcm.sync_status, mcm.last_synced,
1488
+ mcm.model_hash, mcm.code_hash,
1489
+ se.name AS element_name, se.element_type
1490
+ FROM model_code_mappings mcm
1491
+ LEFT JOIN sysml_elements se ON mcm.sysml_element_id = se.id
1492
+ WHERE mcm.project_id = ?
1493
+ ORDER BY mcm.sync_status, se.name""",
1494
+ (project_id,),
1495
+ )
1496
+ rows = [dict(r) for r in cursor.fetchall()]
1497
+
1498
+ # Fetch recent imports
1499
+ cursor.execute(
1500
+ """SELECT import_type, source_file, status, imported_at
1501
+ FROM model_imports
1502
+ WHERE project_id = ?
1503
+ ORDER BY imported_at DESC LIMIT 5""",
1504
+ (project_id,),
1505
+ )
1506
+ recent_imports = [dict(r) for r in cursor.fetchall()]
1507
+
1508
+ conn.close()
1509
+
1510
+ # Count statuses
1511
+ status_counts: Dict[str, int] = {
1512
+ "synced": 0, "model_ahead": 0, "code_ahead": 0,
1513
+ "conflict": 0, "unknown": 0,
1514
+ }
1515
+ for row in rows:
1516
+ s = row.get("sync_status", "unknown")
1517
+ status_counts[s] = status_counts.get(s, 0) + 1
1518
+
1519
+ # Build markdown
1520
+ lines = [
1521
+ "CUI // SP-CTI",
1522
+ "",
1523
+ f"# MBSE Sync Report: {project_id}",
1524
+ f"**Generated:** {_ts()}",
1525
+ "",
1526
+ "## Summary",
1527
+ "",
1528
+ "| Status | Count |",
1529
+ "|--------|-------|",
1530
+ f"| Synced | {status_counts['synced']} |",
1531
+ f"| Model Ahead | {status_counts['model_ahead']} |",
1532
+ f"| Code Ahead | {status_counts['code_ahead']} |",
1533
+ f"| Conflict | {status_counts['conflict']} |",
1534
+ f"| Unknown | {status_counts['unknown']} |",
1535
+ f"| **Total** | **{len(rows)}** |",
1536
+ "",
1537
+ ]
1538
+
1539
+ if status_counts["conflict"] > 0:
1540
+ lines.extend([
1541
+ "## Conflicts Requiring Resolution",
1542
+ "",
1543
+ "| ID | Element | Code Path | Direction |",
1544
+ "|----|---------|-----------|-----------|",
1545
+ ])
1546
+ for row in rows:
1547
+ if row["sync_status"] == "conflict":
1548
+ lines.append(
1549
+ f"| {row['id']} | {row.get('element_name', 'N/A')} "
1550
+ f"| `{row['code_path']}` | {row['mapping_direction']} |"
1551
+ )
1552
+ lines.append("")
1553
+ lines.extend([
1554
+ "**Resolution options:**",
1555
+ "- `--resolution keep_model` — Overwrite code with model version",
1556
+ "- `--resolution keep_code` — Accept code changes (model stale until reimport)",
1557
+ "- `--resolution merge` — Mark bidirectional for manual merge",
1558
+ "",
1559
+ ])
1560
+
1561
+ if rows:
1562
+ lines.extend([
1563
+ "## All Mappings",
1564
+ "",
1565
+ "| ID | Element | Type | Code Path | Status | Last Synced |",
1566
+ "|----|---------|------|-----------|--------|-------------|",
1567
+ ])
1568
+ for row in rows:
1569
+ lines.append(
1570
+ f"| {row['id']} | {row.get('element_name', 'N/A')} "
1571
+ f"| {row['code_type']} | `{row['code_path']}` "
1572
+ f"| {row['sync_status']} | {row.get('last_synced', 'N/A')} |"
1573
+ )
1574
+ lines.append("")
1575
+
1576
+ if recent_imports:
1577
+ lines.extend([
1578
+ "## Recent Imports",
1579
+ "",
1580
+ "| Type | File | Status | Date |",
1581
+ "|------|------|--------|------|",
1582
+ ])
1583
+ for imp in recent_imports:
1584
+ lines.append(
1585
+ f"| {imp['import_type']} | {imp['source_file']} "
1586
+ f"| {imp['status']} | {imp['imported_at']} |"
1587
+ )
1588
+ lines.append("")
1589
+
1590
+ lines.extend([
1591
+ "---",
1592
+ "CUI // SP-CTI",
1593
+ ])
1594
+
1595
+ return "\n".join(lines)
1596
+
1597
+
1598
+ # ---------------------------------------------------------------------------
1599
+ # CLI entry point
1600
+ # ---------------------------------------------------------------------------
1601
+
1602
+ def main() -> None:
1603
+ """Command-line interface for MBSE bidirectional sync engine."""
1604
+ parser = argparse.ArgumentParser(
1605
+ description="ICDEV MBSE Bidirectional Sync Engine"
1606
+ )
1607
+ parser.add_argument(
1608
+ "--project-id", required=True,
1609
+ help="ICDEV project identifier (e.g. proj-123)",
1610
+ )
1611
+
1612
+ sub = parser.add_subparsers(dest="command")
1613
+
1614
+ # detect-drift
1615
+ sub.add_parser("detect-drift", help="Detect model/code drift")
1616
+
1617
+ # sync model-to-code
1618
+ m2c = sub.add_parser("sync-model-to-code",
1619
+ help="Sync model changes to code files")
1620
+ m2c.add_argument("--language", default="python",
1621
+ help="Target language (default: python)")
1622
+
1623
+ # sync code-to-model
1624
+ c2m = sub.add_parser("sync-code-to-model",
1625
+ help="Sync code changes to XMI fragment for Cameo import")
1626
+ c2m.add_argument("--output", required=True,
1627
+ help="Output XMI file path")
1628
+
1629
+ # resolve-conflict
1630
+ rc = sub.add_parser("resolve-conflict",
1631
+ help="Resolve a model/code sync conflict")
1632
+ rc.add_argument("--mapping-id", type=int, required=True,
1633
+ help="ID from model_code_mappings table")
1634
+ rc.add_argument("--resolution", required=True,
1635
+ choices=["keep_model", "keep_code", "merge"],
1636
+ help="Conflict resolution strategy")
1637
+
1638
+ # reimport-xmi
1639
+ ri = sub.add_parser("reimport-xmi",
1640
+ help="Re-import XMI after Cameo updates")
1641
+ ri.add_argument("--file", required=True,
1642
+ help="Path to updated XMI file")
1643
+
1644
+ # reimport-reqif
1645
+ rr = sub.add_parser("reimport-reqif",
1646
+ help="Re-import ReqIF after DOORS updates")
1647
+ rr.add_argument("--file", required=True,
1648
+ help="Path to updated ReqIF file")
1649
+
1650
+ # report
1651
+ sub.add_parser("report", help="Generate drift/sync report")
1652
+
1653
+ parser.add_argument("--json", action="store_true", dest="json_output",
1654
+ help="Output results as JSON")
1655
+ parser.add_argument("--db-path", type=Path, default=None,
1656
+ help="Override database path (default: data/icdev.db)")
1657
+
1658
+ args = parser.parse_args()
1659
+ db = args.db_path
1660
+
1661
+ if not args.command:
1662
+ parser.print_help()
1663
+ sys.exit(1)
1664
+
1665
+ # ---- detect-drift ----
1666
+ if args.command == "detect-drift":
1667
+ result = detect_drift(args.project_id, db_path=db)
1668
+ if args.json_output:
1669
+ print("CUI // SP-CTI")
1670
+ print(json.dumps(result, indent=2, default=str))
1671
+ print("CUI // SP-CTI")
1672
+ else:
1673
+ print("CUI // SP-CTI")
1674
+ print(f"Drift Detection: {args.project_id}")
1675
+ print(f" Total mappings: {result['total_mappings']}")
1676
+ print(f" Synced: {result['synced']}")
1677
+ print(f" Model ahead: {result['model_ahead']}")
1678
+ print(f" Code ahead: {result['code_ahead']}")
1679
+ print(f" Conflict: {result['conflict']}")
1680
+ print(f" Unknown: {result['unknown']}")
1681
+ print(f" Missing files: {result['missing_files']}")
1682
+ if result.get("details"):
1683
+ print("\n Details:")
1684
+ for d in result["details"]:
1685
+ marker = {"synced": "=", "model_ahead": "M>",
1686
+ "code_ahead": "C>", "conflict": "!",
1687
+ "unknown": "?"}.get(d["new_status"], "?")
1688
+ print(f" [{marker}] {d['element_name']}: {d['code_path']}")
1689
+ print("CUI // SP-CTI")
1690
+
1691
+ # ---- sync-model-to-code ----
1692
+ elif args.command == "sync-model-to-code":
1693
+ result = sync_model_to_code(args.project_id, language=args.language,
1694
+ db_path=db)
1695
+ if args.json_output:
1696
+ print("CUI // SP-CTI")
1697
+ print(json.dumps(result, indent=2, default=str))
1698
+ print("CUI // SP-CTI")
1699
+ else:
1700
+ print("CUI // SP-CTI")
1701
+ print(f"Model-to-Code Sync: {args.project_id}")
1702
+ print(f" Files updated: {result['files_updated']}")
1703
+ print(f" Files created: {result['files_created']}")
1704
+ print(f" Files orphaned: {result['files_orphaned']}")
1705
+ print(f" Errors: {result['errors']}")
1706
+ if result.get("error_details"):
1707
+ for err in result["error_details"]:
1708
+ print(f" - {err}")
1709
+ print("CUI // SP-CTI")
1710
+
1711
+ # ---- sync-code-to-model ----
1712
+ elif args.command == "sync-code-to-model":
1713
+ result = sync_code_to_model(args.project_id, output_path=args.output,
1714
+ db_path=db)
1715
+ if args.json_output:
1716
+ print("CUI // SP-CTI")
1717
+ print(json.dumps(result, indent=2, default=str))
1718
+ print("CUI // SP-CTI")
1719
+ else:
1720
+ print("CUI // SP-CTI")
1721
+ print(f"Code-to-Model Sync: {args.project_id}")
1722
+ print(f" XMI file: {result['xmi_file']}")
1723
+ print(f" Elements exported: {result['elements_exported']}")
1724
+ print(f" Modified elements: {result['modified_elements']}")
1725
+ print(f" New elements: {result['new_elements']}")
1726
+ if result.get("errors"):
1727
+ print(f" Errors: {len(result['errors'])}")
1728
+ for err in result["errors"]:
1729
+ print(f" - {err}")
1730
+ print("CUI // SP-CTI")
1731
+
1732
+ # ---- resolve-conflict ----
1733
+ elif args.command == "resolve-conflict":
1734
+ result = resolve_conflict(args.project_id, mapping_id=args.mapping_id,
1735
+ resolution=args.resolution, db_path=db)
1736
+ if args.json_output:
1737
+ print("CUI // SP-CTI")
1738
+ print(json.dumps(result, indent=2, default=str))
1739
+ print("CUI // SP-CTI")
1740
+ else:
1741
+ print("CUI // SP-CTI")
1742
+ print(f"Conflict Resolution: mapping #{result['mapping_id']}")
1743
+ print(f" Resolution: {result['resolution']}")
1744
+ print(f" Status: {result['status']}")
1745
+ if result.get("error"):
1746
+ print(f" Error: {result['error']}")
1747
+ print("CUI // SP-CTI")
1748
+
1749
+ # ---- reimport-xmi ----
1750
+ elif args.command == "reimport-xmi":
1751
+ file_path = str(Path(args.file).resolve())
1752
+ result = reimport_xmi(args.project_id, file_path=file_path, db_path=db)
1753
+ if args.json_output:
1754
+ print("CUI // SP-CTI")
1755
+ print(json.dumps(result, indent=2, default=str))
1756
+ print("CUI // SP-CTI")
1757
+ else:
1758
+ print("CUI // SP-CTI")
1759
+ print(f"XMI Reimport: {args.project_id}")
1760
+ print(f" Updated: {result['updated']}")
1761
+ print(f" Added: {result['added']}")
1762
+ print(f" Deleted: {result['deleted']}")
1763
+ print(f" Unchanged: {result['unchanged']}")
1764
+ if result.get("error"):
1765
+ print(f" Error: {result['error']}")
1766
+ print("CUI // SP-CTI")
1767
+
1768
+ # ---- reimport-reqif ----
1769
+ elif args.command == "reimport-reqif":
1770
+ file_path = str(Path(args.file).resolve())
1771
+ result = reimport_reqif(args.project_id, file_path=file_path,
1772
+ db_path=db)
1773
+ if args.json_output:
1774
+ print("CUI // SP-CTI")
1775
+ print(json.dumps(result, indent=2, default=str))
1776
+ print("CUI // SP-CTI")
1777
+ else:
1778
+ print("CUI // SP-CTI")
1779
+ print(f"ReqIF Reimport: {args.project_id}")
1780
+ print(f" Updated: {result['updated']}")
1781
+ print(f" Added: {result['added']}")
1782
+ print(f" Deleted: {result['deleted']}")
1783
+ print(f" Unchanged: {result['unchanged']}")
1784
+ if result.get("error"):
1785
+ print(f" Error: {result['error']}")
1786
+ print("CUI // SP-CTI")
1787
+
1788
+ # ---- report ----
1789
+ elif args.command == "report":
1790
+ if args.json_output:
1791
+ # For JSON mode, run detect_drift and output the result
1792
+ result = detect_drift(args.project_id, db_path=db)
1793
+ print("CUI // SP-CTI")
1794
+ print(json.dumps(result, indent=2, default=str))
1795
+ print("CUI // SP-CTI")
1796
+ else:
1797
+ report = generate_sync_report(args.project_id, db_path=db)
1798
+ print(report)
1799
+
1800
+ sys.exit(0)
1801
+
1802
+
1803
+ if __name__ == "__main__":
1804
+ main()
1805
+ # [TEMPLATE: CUI // SP-CTI]