icdev 0.0.3__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 (1214) hide show
  1. args/agent_config.yaml +113 -0
  2. args/audit_regimes/cisa_sbd.json +381 -0
  3. args/audit_regimes/cmmc_l2.json +906 -0
  4. args/audit_regimes/dod_cssp.json +393 -0
  5. args/audit_regimes/dodi_5000_87.json +297 -0
  6. args/audit_regimes/fedramp_moderate.json +650 -0
  7. args/audit_regimes/ieee_1012.json +373 -0
  8. args/audit_regimes/nist_800_171.json +624 -0
  9. args/audit_regimes/nist_800_53.json +907 -0
  10. args/cloudforge_blueprints/aws_commercial.yaml +29 -0
  11. args/cloudforge_blueprints/aws_govcloud_il4.yaml +34 -0
  12. args/cloudforge_blueprints/aws_govcloud_il5.yaml +38 -0
  13. args/cloudforge_blueprints/azure_commercial.yaml +28 -0
  14. args/cloudforge_blueprints/azure_gov_il4.yaml +32 -0
  15. args/cloudforge_blueprints/azure_gov_il5.yaml +36 -0
  16. args/cloudforge_blueprints/gcp_commercial.yaml +28 -0
  17. args/cloudforge_blueprints/oci_commercial.yaml +28 -0
  18. args/cloudforge_config.yaml +231 -0
  19. args/cloudforge_runbook_templates/backup_verify.yaml +98 -0
  20. args/cloudforge_runbook_templates/dr_failover.yaml +107 -0
  21. args/cloudforge_runbook_templates/health_check.yaml +97 -0
  22. args/cloudforge_runbook_templates/incident_response.yaml +101 -0
  23. args/cloudforge_runbook_templates/migration_cutover.yaml +105 -0
  24. args/cloudforge_runbook_templates/patch_rollout.yaml +92 -0
  25. args/cloudforge_runbook_templates/zone_provision.yaml +93 -0
  26. args/code_pattern_config.yaml +151 -0
  27. args/code_quality_config.yaml +47 -0
  28. args/compliance_config.yaml +17 -0
  29. args/control_inheritance.yaml +177 -0
  30. args/csp_mcp_config.yaml +41 -0
  31. args/cui_markings.yaml +35 -0
  32. args/databridge_config.yaml +232 -0
  33. args/db_config.yaml +116 -0
  34. args/decision_tables/agent_trust_decision.yaml +143 -0
  35. args/decision_tables/ato_boundary_impact.yaml +132 -0
  36. args/decision_tables/deployment_approval.yaml +152 -0
  37. args/degradation_matrix.yaml +163 -0
  38. args/devsecops_config.yaml +286 -0
  39. args/endpoint_security_config.yaml +207 -0
  40. args/exit_criteria.yaml +102 -0
  41. args/feature_flags.yaml +235 -0
  42. args/file_access_tiers.yaml +88 -0
  43. args/forge_studio/blueprint_config.yaml +27 -0
  44. args/forge_studio/component_catalog.json +411 -0
  45. args/forge_studio/workflow_templates.yaml +103 -0
  46. args/govcon_config.yaml +41 -0
  47. args/harness_config.yaml +67 -0
  48. args/innovation_config.yaml +321 -0
  49. args/knowledge_graph_config.yaml +113 -0
  50. args/llm_config.yaml +222 -0
  51. args/marketplace_config.yaml +260 -0
  52. args/monitoring_config.yaml +127 -0
  53. args/mosa_config.yaml +190 -0
  54. args/observability_tracing_config.yaml +170 -0
  55. args/owasp_agentic_config.yaml +171 -0
  56. args/pipeline_gates.yaml +197 -0
  57. args/project_defaults.yaml +235 -0
  58. args/prompt_chains.yaml +163 -0
  59. args/rag_config.yaml +167 -0
  60. args/research_config.yaml +89 -0
  61. args/resilience_config.yaml +197 -0
  62. args/ricoas_config.yaml +191 -0
  63. args/security_gates.yaml +763 -0
  64. args/storage_config.yaml +63 -0
  65. args/writeguard_config.yaml +131 -0
  66. args/zta_config.yaml +247 -0
  67. context/__init__.py +6 -0
  68. context/agent/__init__.py +6 -0
  69. context/agent/response_schemas/__init__.py +6 -0
  70. context/agent/response_schemas/debate_position.json +46 -0
  71. context/agent/response_schemas/fitness_scorecard.json +74 -0
  72. context/agent/response_schemas/review_decision.json +39 -0
  73. context/agent/response_schemas/task_decomposition.json +82 -0
  74. context/agent/response_schemas/veto_decision.json +40 -0
  75. context/agentic/__init__.py +6 -0
  76. context/agentic/architecture_patterns.md +269 -0
  77. context/agentic/capability_registry.yaml +223 -0
  78. context/agentic/csp_integration.md +30 -0
  79. context/agentic/csp_mcp_registry.yaml +280 -0
  80. context/agentic/fitness_rubric.md +56 -0
  81. context/agentic/governance_baseline.md +205 -0
  82. context/ci/__init__.py +6 -0
  83. context/ci/worktree_templates.json +44 -0
  84. context/cloud/__init__.py +6 -0
  85. context/cloud/csp_service_registry.json +739 -0
  86. context/compliance/__init__.py +6 -0
  87. context/compliance/ai_rmf_crosswalk.yaml +226 -0
  88. context/compliance/atlas_mitigations.json +293 -0
  89. context/compliance/atlas_techniques.json +833 -0
  90. context/compliance/cisa_sbd_requirements.json +477 -0
  91. context/compliance/cjis_security_policy.json +522 -0
  92. context/compliance/cmmc_practices.json +2494 -0
  93. context/compliance/cmmc_report_template.md +142 -0
  94. context/compliance/cnssi_1253_overlay.json +109 -0
  95. context/compliance/control_crosswalk.json +1914 -0
  96. context/compliance/control_families/__init__.py +6 -0
  97. context/compliance/csp_certifications.json +251 -0
  98. context/compliance/cssp_report_template.md +193 -0
  99. context/compliance/cui_templates/__init__.py +6 -0
  100. context/compliance/cui_templates/banner_block.txt +4 -0
  101. context/compliance/cui_templates/code_header.txt +8 -0
  102. context/compliance/cui_templates/document_template.md +35 -0
  103. context/compliance/data_type_framework_map.json +321 -0
  104. context/compliance/data_type_registry.json +147 -0
  105. context/compliance/dod_cssp_8530.json +463 -0
  106. context/compliance/eu_ai_act_annex_iii.json +108 -0
  107. context/compliance/export_templates/__init__.py +6 -0
  108. context/compliance/export_templates/emass_controls.csv.j2 +4 -0
  109. context/compliance/export_templates/evidence_package.md.j2 +39 -0
  110. context/compliance/export_templates/executive_summary.md.j2 +55 -0
  111. context/compliance/export_templates/poam_tracking.csv.j2 +4 -0
  112. context/compliance/fedramp_20x_ksi_schemas.json +133 -0
  113. context/compliance/fedramp_high_baseline.json +4370 -0
  114. context/compliance/fedramp_moderate_baseline.json +2183 -0
  115. context/compliance/fedramp_report_template.md +181 -0
  116. context/compliance/fips_200_areas.json +362 -0
  117. context/compliance/gao_ai_accountability.json +262 -0
  118. context/compliance/hipaa_security_rule.json +720 -0
  119. context/compliance/hitrust_csf_v11.json +930 -0
  120. context/compliance/impact_level_profiles.json +251 -0
  121. context/compliance/incident_response_template.md +1110 -0
  122. context/compliance/iso27001_2022_controls.json +750 -0
  123. context/compliance/iso27001_nist_bridge.json +382 -0
  124. context/compliance/iso42001_controls.json +254 -0
  125. context/compliance/ivv_checklist_template.md +80 -0
  126. context/compliance/ivv_report_template.md +116 -0
  127. context/compliance/ivv_requirements.json +372 -0
  128. context/compliance/mosa_crosswalk.json +327 -0
  129. context/compliance/mosa_framework.json +250 -0
  130. context/compliance/narrative_templates/AC.md.j2 +101 -0
  131. context/compliance/narrative_templates/AU.md.j2 +106 -0
  132. context/compliance/narrative_templates/IA.md.j2 +104 -0
  133. context/compliance/narrative_templates/SC.md.j2 +102 -0
  134. context/compliance/narrative_templates/SI.md.j2 +111 -0
  135. context/compliance/narrative_templates/__init__.py +6 -0
  136. context/compliance/narrative_templates/default.md.j2 +50 -0
  137. context/compliance/narrative_templates/executive_summary.j2 +27 -0
  138. context/compliance/narrative_templates/poam_milestone.j2 +19 -0
  139. context/compliance/narrative_templates/ssp_section.j2 +11 -0
  140. context/compliance/nist_800_171_controls.json +1552 -0
  141. context/compliance/nist_800_207_crosswalk.json +399 -0
  142. context/compliance/nist_800_207_zta.json +258 -0
  143. context/compliance/nist_800_53.json +324 -0
  144. context/compliance/nist_ai_600_1_genai.json +326 -0
  145. context/compliance/nist_ai_rmf.json +206 -0
  146. context/compliance/nist_sp_800_60_types.json +1667 -0
  147. context/compliance/omb_m25_21_high_impact_ai.json +248 -0
  148. context/compliance/omb_m26_04_unbiased_ai.json +262 -0
  149. context/compliance/owasp_agentic_asi.json +133 -0
  150. context/compliance/owasp_agentic_threats.json +285 -0
  151. context/compliance/owasp_llm_top10.json +274 -0
  152. context/compliance/pci_dss_v4.json +510 -0
  153. context/compliance/poam_template.md +117 -0
  154. context/compliance/safeai_controls.json +512 -0
  155. context/compliance/sbd_report_template.md +77 -0
  156. context/compliance/siem_config_templates/__init__.py +6 -0
  157. context/compliance/siem_config_templates/filebeat.yml +213 -0
  158. context/compliance/siem_config_templates/log_sources.json +208 -0
  159. context/compliance/soc2_trust_criteria.json +661 -0
  160. context/compliance/ssp_template.md +432 -0
  161. context/compliance/stig_templates/__init__.py +6 -0
  162. context/compliance/stig_templates/webapp_stig.json +139 -0
  163. context/compliance/xai_requirements.json +108 -0
  164. context/dashboard/__init__.py +6 -0
  165. context/dashboard/nlq_examples.json +50 -0
  166. context/dashboard/schema_descriptions.json +23 -0
  167. context/icdev_methodology.md +100 -0
  168. context/integration/__init__.py +6 -0
  169. context/integration/approval_workflows.json +32 -0
  170. context/integration/gitlab_field_mappings.json +33 -0
  171. context/integration/jira_field_mappings.json +32 -0
  172. context/integration/reqif_export_schema.json +23 -0
  173. context/integration/servicenow_field_mappings.json +22 -0
  174. context/languages/__init__.py +6 -0
  175. context/languages/framework_patterns.json +205 -0
  176. context/languages/language_registry.json +279 -0
  177. context/llm/__init__.py +6 -0
  178. context/llm/example_provider.py +89 -0
  179. context/marketplace/assets/writeguard-core.yaml +100 -0
  180. context/marketplace/assets/writeguard-govcon.yaml +45 -0
  181. context/marketplace/assets/writeguard-style-guides.yaml +44 -0
  182. context/mbse/__init__.py +6 -0
  183. context/mbse/des_report_template.md +162 -0
  184. context/mbse/des_requirements.json +411 -0
  185. context/mbse/digital_thread_patterns.json +403 -0
  186. context/mbse/reqif_schema.json +280 -0
  187. context/mbse/sysml_element_types.json +432 -0
  188. context/oscal/NIST_SP-800-53_rev5_catalog.json +254987 -0
  189. context/oscal/README.md +43 -0
  190. context/patterns/__init__.py +6 -0
  191. context/profiles/__init__.py +6 -0
  192. context/profiles/dod_baseline_v1.yaml +145 -0
  193. context/profiles/fedramp_baseline_v1.yaml +143 -0
  194. context/profiles/financial_baseline_v1.yaml +142 -0
  195. context/profiles/healthcare_baseline_v1.yaml +135 -0
  196. context/profiles/law_enforcement_v1.yaml +129 -0
  197. context/profiles/startup_v1.yaml +134 -0
  198. context/rag/source_mappings.json +42 -0
  199. context/requirements/__init__.py +6 -0
  200. context/requirements/ambiguity_patterns.json +97 -0
  201. context/requirements/boundary_impact_rules.json +123 -0
  202. context/requirements/default_constitutions.json +67 -0
  203. context/requirements/document_extraction_rules.json +58 -0
  204. context/requirements/gap_patterns.json +108 -0
  205. context/requirements/readiness_rubric.json +78 -0
  206. context/requirements/red_alternative_patterns.json +210 -0
  207. context/requirements/safe_templates.json +72 -0
  208. context/requirements/spec_quality_checklist.json +122 -0
  209. context/research/regulatory_registry.json +114 -0
  210. context/research/verticals/cybersecurity.json +127 -0
  211. context/research/verticals/defense.json +104 -0
  212. context/research/verticals/fintech.json +125 -0
  213. context/research/verticals/healthcare.json +118 -0
  214. context/research/verticals/logistics.json +117 -0
  215. context/research/verticals/trading.json +145 -0
  216. context/simulation/__init__.py +6 -0
  217. context/simulation/architecture_patterns.json +36 -0
  218. context/simulation/coa_templates.json +38 -0
  219. context/simulation/cost_models.json +23 -0
  220. context/simulation/risk_categories.json +46 -0
  221. context/supply_chain/__init__.py +6 -0
  222. context/supply_chain/isa_templates.json +129 -0
  223. context/supply_chain/nist_800_161_controls.json +247 -0
  224. context/supply_chain/scrm_risk_matrix.json +147 -0
  225. context/templates/__init__.py +6 -0
  226. context/templates/ansible/__init__.py +6 -0
  227. context/templates/ansible/playbooks/__init__.py +6 -0
  228. context/templates/ansible/roles/__init__.py +6 -0
  229. context/templates/gitlab_ci/__init__.py +6 -0
  230. context/templates/grafana/__init__.py +6 -0
  231. context/templates/kubernetes/__init__.py +6 -0
  232. context/templates/project/__init__.py +6 -0
  233. context/templates/project/api/__init__.py +6 -0
  234. context/templates/project/cli/__init__.py +6 -0
  235. context/templates/project/data_pipeline/__init__.py +6 -0
  236. context/templates/project/iac/__init__.py +6 -0
  237. context/templates/project/javascript_frontend/__init__.py +6 -0
  238. context/templates/project/javascript_frontend/src/__init__.py +6 -0
  239. context/templates/project/javascript_frontend/tests/__init__.py +6 -0
  240. context/templates/project/microservice/__init__.py +6 -0
  241. context/templates/project/python_backend/__init__.py +6 -0
  242. context/templates/project/python_backend/src/__init__.py +6 -0
  243. context/templates/project/python_backend/tests/__init__.py +6 -0
  244. context/templates/project/python_backend/tests/features/__init__.py +6 -0
  245. context/templates/project/python_backend/tests/steps/__init__.py +6 -0
  246. context/templates/terraform/__init__.py +6 -0
  247. context/templates/terraform/govcloud_base/__init__.py +6 -0
  248. context/templates/terraform/modules/__init__.py +6 -0
  249. context/tone/__init__.py +6 -0
  250. context/writing/grammar_rules/common_errors.json +306 -0
  251. context/writing/grammar_rules/govcon_vocabulary.json +113 -0
  252. context/writing/style_guides/academic.yaml +43 -0
  253. context/writing/style_guides/business.yaml +42 -0
  254. context/writing/style_guides/government.yaml +59 -0
  255. context/writing/style_guides/proposal.yaml +58 -0
  256. context/writing/style_guides/technical.yaml +43 -0
  257. docs/adr/README.md +66 -0
  258. docs/adr/connector-forge-decisions.md +318 -0
  259. docs/adr/core-decisions.md +289 -0
  260. docs/adr/db-decisions.md +94 -0
  261. docs/adr/harness-decisions.md +122 -0
  262. docs/adr/innovation-decisions.md +262 -0
  263. docs/adr/marketplace-decisions.md +109 -0
  264. docs/adr/sbd-decisions.md +109 -0
  265. docs/adr/scale-engine-decisions.md +108 -0
  266. docs/adr/writeguard-decisions.md +136 -0
  267. docs/architecture/bounded-contexts.md +1032 -0
  268. docs/features/phase-65-writeguard.md +139 -0
  269. docs/features/phase-66-marketplace-commerce.md +79 -0
  270. docs/features/phase-67-knowledge-ingestion-rag-autodraft.md +97 -0
  271. docs/features/phase-68-enhanced-autodraft-pipeline.md +109 -0
  272. docs/features/phase-69-proposalai-marketplace-module.md +131 -0
  273. docs/features/phase-70-databridge.md +214 -0
  274. docs/features/phase-71-databridge-messaging.md +102 -0
  275. docs/implementation-plan-architecture-evolution.md +614 -0
  276. docs/marketplace/CONTRIBUTING.md +124 -0
  277. docs/marketplace/module_manifest_schema.yaml +83 -0
  278. docs/research/ai-architecture-patterns-2024-2026.md +1236 -0
  279. docs/research/app-builder-platform-analysis.md +582 -0
  280. docs/research/architecture-patterns-c4-ddd-agentic.md +871 -0
  281. docs/research/flowable-boat-competitive-analysis.md +426 -0
  282. docs/research/modern-dev-practices-2024-2026.md +1615 -0
  283. docs/research/secure-by-design-cloudyrion-adaptation.md +270 -0
  284. goals/agent_management.md +144 -0
  285. goals/ai_accountability.md +90 -0
  286. goals/ai_narratives.md +79 -0
  287. goals/ai_transparency.md +76 -0
  288. goals/ato_simulator.md +78 -0
  289. goals/audit_engine.md +177 -0
  290. goals/bite_sized_plans.md +225 -0
  291. goals/boundary_supply_chain.md +206 -0
  292. goals/brainstorming_gate.md +186 -0
  293. goals/build_app.md +604 -0
  294. goals/cato_live_evidence.md +77 -0
  295. goals/cloudforge.md +106 -0
  296. goals/code_intelligence.md +197 -0
  297. goals/compliance_workflow.md +858 -0
  298. goals/connector_forge.md +133 -0
  299. goals/databridge.md +128 -0
  300. goals/deploy_workflow.md +390 -0
  301. goals/developer_scorecard.md +78 -0
  302. goals/devsecops_workflow.md +408 -0
  303. goals/firmware_sbom.md +79 -0
  304. goals/forge_hub.md +78 -0
  305. goals/golden_path.md +77 -0
  306. goals/harness_engineering.md +91 -0
  307. goals/integration_testing.md +189 -0
  308. goals/knowledge_graph.md +128 -0
  309. goals/maintenance_audit.md +196 -0
  310. goals/manifest.md +50 -0
  311. goals/monitoring.md +126 -0
  312. goals/mosa_workflow.md +463 -0
  313. goals/multi_agent_orchestration.md +68 -0
  314. goals/observability_traceability_xai.md +154 -0
  315. goals/owasp_agentic_security.md +395 -0
  316. goals/pr_intelligence.md +78 -0
  317. goals/requirements_intake.md +213 -0
  318. goals/secure_by_design.md +135 -0
  319. goals/security_scan.md +381 -0
  320. goals/self_healing.md +120 -0
  321. goals/simulation_engine.md +111 -0
  322. goals/subagent_review.md +205 -0
  323. goals/systematic_debugging.md +257 -0
  324. goals/tdd_workflow.md +403 -0
  325. goals/template_exchange.md +77 -0
  326. goals/thread_heatmap.md +77 -0
  327. goals/threat_modeler.md +77 -0
  328. goals/verification_iron_law.md +192 -0
  329. goals/vsm_dashboard.md +76 -0
  330. goals/writeguard.md +89 -0
  331. goals/zero_trust_architecture.md +403 -0
  332. hardprompts/__init__.py +6 -0
  333. hardprompts/agent/__init__.py +6 -0
  334. hardprompts/agent/agentic_architect.md +100 -0
  335. hardprompts/agent/debate_prompt.md +32 -0
  336. hardprompts/agent/fitness_evaluation.md +48 -0
  337. hardprompts/agent/governance_review.md +214 -0
  338. hardprompts/agent/reviewer_prompt.md +34 -0
  339. hardprompts/agent/skill_design.md +172 -0
  340. hardprompts/agent/task_decomposition.md +275 -0
  341. hardprompts/agent/veto_check_prompt.md +33 -0
  342. hardprompts/architect/__init__.py +6 -0
  343. hardprompts/architect/api_design.md +283 -0
  344. hardprompts/architect/data_model.md +277 -0
  345. hardprompts/architect/system_design.md +180 -0
  346. hardprompts/builder/__init__.py +6 -0
  347. hardprompts/builder/code_generation.md +59 -0
  348. hardprompts/builder/refactor.md +58 -0
  349. hardprompts/builder/scaffold_project.md +69 -0
  350. hardprompts/builder/test_generation.md +87 -0
  351. hardprompts/ci/__init__.py +6 -0
  352. hardprompts/ci/worktree_setup.md +35 -0
  353. hardprompts/compliance/__init__.py +6 -0
  354. hardprompts/compliance/cmmc_assessment.md +63 -0
  355. hardprompts/compliance/cssp_assessment.md +75 -0
  356. hardprompts/compliance/cui_marking.md +86 -0
  357. hardprompts/compliance/fedramp_assessment.md +55 -0
  358. hardprompts/compliance/ivv_assessment.md +96 -0
  359. hardprompts/compliance/poam_generation.md +57 -0
  360. hardprompts/compliance/sbd_assessment.md +101 -0
  361. hardprompts/compliance/security_categorization.md +74 -0
  362. hardprompts/compliance/ssp_generation.md +56 -0
  363. hardprompts/compliance/stig_evaluation.md +63 -0
  364. hardprompts/dashboard/__init__.py +6 -0
  365. hardprompts/dashboard/nlq_system_prompt.md +26 -0
  366. hardprompts/infra/__init__.py +6 -0
  367. hardprompts/infra/k8s_manifests.md +118 -0
  368. hardprompts/infra/pipeline_generation.md +160 -0
  369. hardprompts/infra/terraform_generation.md +92 -0
  370. hardprompts/integration/__init__.py +6 -0
  371. hardprompts/integration/approval_review.md +17 -0
  372. hardprompts/integration/jira_mapping.md +25 -0
  373. hardprompts/integration/servicenow_mapping.md +14 -0
  374. hardprompts/knowledge/__init__.py +6 -0
  375. hardprompts/knowledge/pattern_detection.md +73 -0
  376. hardprompts/knowledge/recommendation_engine.md +90 -0
  377. hardprompts/knowledge/root_cause_analysis.md +91 -0
  378. hardprompts/maintenance/__init__.py +6 -0
  379. hardprompts/maintenance/maintenance_assessment.md +82 -0
  380. hardprompts/mbse/__init__.py +6 -0
  381. hardprompts/mbse/digital_thread.md +67 -0
  382. hardprompts/mbse/model_import.md +62 -0
  383. hardprompts/mbse/model_to_code.md +65 -0
  384. hardprompts/modernization/__init__.py +6 -0
  385. hardprompts/modernization/legacy_analysis.md +93 -0
  386. hardprompts/modernization/migration_planning.md +150 -0
  387. hardprompts/modernization/seven_r_assessment.md +107 -0
  388. hardprompts/proposal_draft.md +53 -0
  389. hardprompts/rag_citation.md +12 -0
  390. hardprompts/rag_rerank.md +31 -0
  391. hardprompts/requirements/__init__.py +6 -0
  392. hardprompts/requirements/bdd_generation.md +35 -0
  393. hardprompts/requirements/clarification_prioritization.md +29 -0
  394. hardprompts/requirements/decomposition.md +60 -0
  395. hardprompts/requirements/document_extraction.md +45 -0
  396. hardprompts/requirements/gap_detection.md +70 -0
  397. hardprompts/requirements/intake_conversation.md +101 -0
  398. hardprompts/requirements/readiness_assessment.md +39 -0
  399. hardprompts/requirements/spec_quality.md +33 -0
  400. hardprompts/requirements/traceability_analysis.md +23 -0
  401. hardprompts/security/__init__.py +6 -0
  402. hardprompts/security/endpoint_security.md +78 -0
  403. hardprompts/security/threat_model.md +70 -0
  404. hardprompts/security/vulnerability_assessment.md +81 -0
  405. hardprompts/simulation/__init__.py +6 -0
  406. hardprompts/simulation/architecture_impact.md +27 -0
  407. hardprompts/simulation/coa_alternative.md +27 -0
  408. hardprompts/simulation/coa_generation.md +25 -0
  409. hardprompts/simulation/compliance_impact.md +28 -0
  410. hardprompts/simulation/cost_estimation.md +33 -0
  411. hardprompts/simulation/risk_assessment.md +28 -0
  412. hardprompts/translation/code_translation.md +68 -0
  413. hardprompts/translation/dependency_suggestion.md +44 -0
  414. hardprompts/translation/test_translation.md +64 -0
  415. hardprompts/translation/translation_repair.md +59 -0
  416. icdev-0.0.3.dist-info/METADATA +909 -0
  417. icdev-0.0.3.dist-info/RECORD +1214 -0
  418. icdev-0.0.3.dist-info/WHEEL +5 -0
  419. icdev-0.0.3.dist-info/entry_points.txt +9 -0
  420. icdev-0.0.3.dist-info/licenses/LICENSE +201 -0
  421. icdev-0.0.3.dist-info/licenses/NOTICE +11 -0
  422. icdev-0.0.3.dist-info/top_level.txt +7 -0
  423. memory/MEMORY.md +52 -0
  424. memory/logs/2026-02-14.md +17 -0
  425. memory/logs/2026-03-03.md +2 -0
  426. memory/logs/__init__.py +1 -0
  427. tools/a2a/icdev_callback_client.py +210 -0
  428. tools/agent/cards/architect_card.json +29 -0
  429. tools/agent/cards/builder_card.json +34 -0
  430. tools/agent/cards/compliance_card.json +29 -0
  431. tools/agent/cards/connector_forge_card.json +49 -0
  432. tools/agent/cards/devsecops_zta_card.json +24 -0
  433. tools/agent/cards/knowledge_card.json +29 -0
  434. tools/agent/cards/monitor_card.json +29 -0
  435. tools/agent/cards/orchestrator_card.json +29 -0
  436. tools/agent/cards/requirements_analyst_card.json +24 -0
  437. tools/agent/cards/security_card.json +29 -0
  438. tools/agent/cards/simulation_card.json +24 -0
  439. tools/agent/cards/supply_chain_card.json +24 -0
  440. tools/analysis/__init__.py +1 -0
  441. tools/analysis/code_analyzer.py +770 -0
  442. tools/analysis/runtime_feedback.py +379 -0
  443. tools/analytics/__init__.py +2 -0
  444. tools/analytics/scorecard.py +538 -0
  445. tools/analytics/vsm_engine.py +612 -0
  446. tools/architecture/__init__.py +2 -0
  447. tools/architecture/adr_extractor.py +393 -0
  448. tools/audit/__init__.py +1 -0
  449. tools/audit/audit_logger.py +199 -0
  450. tools/audit/audit_query.py +153 -0
  451. tools/audit/decision_recorder.py +73 -0
  452. tools/audit_engine/__init__.py +12 -0
  453. tools/audit_engine/ai_advisor.py +906 -0
  454. tools/audit_engine/cli.py +286 -0
  455. tools/audit_engine/comparator.py +305 -0
  456. tools/audit_engine/eject_scaffolder.py +399 -0
  457. tools/audit_engine/engine.py +614 -0
  458. tools/audit_engine/git_fetcher.py +341 -0
  459. tools/audit_engine/regime_loader.py +200 -0
  460. tools/audit_engine/regime_updater.py +325 -0
  461. tools/audit_engine/report_card.py +289 -0
  462. tools/audit_engine/scanner.py +684 -0
  463. tools/audit_engine/self_heal.py +1042 -0
  464. tools/ci/__init__.py +2 -0
  465. tools/ci/connectors/__init__.py +2 -0
  466. tools/ci/connectors/base_connector.py +80 -0
  467. tools/ci/connectors/connector_registry.py +188 -0
  468. tools/ci/connectors/mattermost_connector.py +159 -0
  469. tools/ci/connectors/slack_connector.py +197 -0
  470. tools/ci/core/__init__.py +2 -0
  471. tools/ci/core/air_gap_detector.py +115 -0
  472. tools/ci/core/comment_handler.py +192 -0
  473. tools/ci/core/conversation_manager.py +480 -0
  474. tools/ci/core/event_envelope.py +500 -0
  475. tools/ci/core/event_router.py +444 -0
  476. tools/ci/core/failure_parser.py +397 -0
  477. tools/ci/core/recovery_engine.py +527 -0
  478. tools/ci/gate_enforcer.py +361 -0
  479. tools/ci/modules/__init__.py +2 -0
  480. tools/ci/modules/agent.py +271 -0
  481. tools/ci/modules/git_ops.py +175 -0
  482. tools/ci/modules/state.py +117 -0
  483. tools/ci/modules/vcs.py +303 -0
  484. tools/ci/modules/workflow_ops.py +295 -0
  485. tools/ci/modules/worktree.py +337 -0
  486. tools/ci/pipeline_config_generator.py +558 -0
  487. tools/ci/pr_intelligence.py +485 -0
  488. tools/ci/triggers/__init__.py +2 -0
  489. tools/ci/triggers/gitlab_task_monitor.py +327 -0
  490. tools/ci/triggers/poll_trigger.py +237 -0
  491. tools/ci/triggers/webhook_server.py +356 -0
  492. tools/ci/workflows/__init__.py +2 -0
  493. tools/ci/workflows/icdev_build.py +140 -0
  494. tools/ci/workflows/icdev_comply.py +284 -0
  495. tools/ci/workflows/icdev_document.py +152 -0
  496. tools/ci/workflows/icdev_e2e.py +188 -0
  497. tools/ci/workflows/icdev_patch.py +186 -0
  498. tools/ci/workflows/icdev_plan.py +202 -0
  499. tools/ci/workflows/icdev_plan_build.py +41 -0
  500. tools/ci/workflows/icdev_plan_build_test.py +46 -0
  501. tools/ci/workflows/icdev_plan_build_test_review.py +47 -0
  502. tools/ci/workflows/icdev_review.py +126 -0
  503. tools/ci/workflows/icdev_sdlc.py +261 -0
  504. tools/ci/workflows/icdev_test.py +240 -0
  505. tools/cli/__init__.py +1 -0
  506. tools/cli/output_formatter.py +756 -0
  507. tools/cloudforge/__init__.py +12 -0
  508. tools/cloudforge/airgap/__init__.py +2 -0
  509. tools/cloudforge/airgap/il_classifier.py +70 -0
  510. tools/cloudforge/airgap/offline_validator.py +42 -0
  511. tools/cloudforge/airgap/shift_emulator.py +155 -0
  512. tools/cloudforge/airgap/sneakernet.py +91 -0
  513. tools/cloudforge/cd_hub/__init__.py +2 -0
  514. tools/cloudforge/cd_hub/canary_deployer.py +88 -0
  515. tools/cloudforge/cd_hub/gitops_renderer.py +123 -0
  516. tools/cloudforge/cd_hub/hub_controller.py +143 -0
  517. tools/cloudforge/cd_hub/pipeline_bridge.py +30 -0
  518. tools/cloudforge/cd_hub/rollback_engine.py +29 -0
  519. tools/cloudforge/cd_hub/spoke_agent.py +51 -0
  520. tools/cloudforge/compliance/__init__.py +2 -0
  521. tools/cloudforge/compliance/ato_accelerator.py +272 -0
  522. tools/cloudforge/compliance/control_inheritor.py +127 -0
  523. tools/cloudforge/compliance/evidence_generator.py +129 -0
  524. tools/cloudforge/compliance/poam_bridge.py +41 -0
  525. tools/cloudforge/compliance/ssp_bridge.py +52 -0
  526. tools/cloudforge/compliance/stig_bridge.py +41 -0
  527. tools/cloudforge/container_forge/__init__.py +2 -0
  528. tools/cloudforge/container_forge/bigbang_renderer.py +85 -0
  529. tools/cloudforge/container_forge/hardener.py +169 -0
  530. tools/cloudforge/container_forge/image_scanner_bridge.py +33 -0
  531. tools/cloudforge/container_forge/runtime_policy.py +87 -0
  532. tools/cloudforge/container_forge/sbom_bridge.py +42 -0
  533. tools/cloudforge/finops/__init__.py +2 -0
  534. tools/cloudforge/finops/anomaly_detector.py +78 -0
  535. tools/cloudforge/finops/budget_tracker.py +96 -0
  536. tools/cloudforge/finops/chargeback.py +69 -0
  537. tools/cloudforge/finops/cost_collector.py +141 -0
  538. tools/cloudforge/finops/optimizer.py +55 -0
  539. tools/cloudforge/hybrid/__init__.py +2 -0
  540. tools/cloudforge/hybrid/connection_manager.py +141 -0
  541. tools/cloudforge/hybrid/dns_federator.py +56 -0
  542. tools/cloudforge/hybrid/health_monitor.py +108 -0
  543. tools/cloudforge/hybrid/identity_federator.py +53 -0
  544. tools/cloudforge/hybrid/network_bridge.py +68 -0
  545. tools/cloudforge/hybrid/topology_manager.py +147 -0
  546. tools/cloudforge/hybrid/workload_abstractor.py +92 -0
  547. tools/cloudforge/iac/__init__.py +2 -0
  548. tools/cloudforge/iac/drift_detector.py +154 -0
  549. tools/cloudforge/iac/module_library.py +265 -0
  550. tools/cloudforge/iac/opentofu_adapter.py +89 -0
  551. tools/cloudforge/iac/pulumi_renderer.py +292 -0
  552. tools/cloudforge/iac/state_backend.py +146 -0
  553. tools/cloudforge/iac/terraform_renderer.py +626 -0
  554. tools/cloudforge/landing_zone/__init__.py +2 -0
  555. tools/cloudforge/landing_zone/blueprint_loader.py +98 -0
  556. tools/cloudforge/landing_zone/blueprint_validator.py +113 -0
  557. tools/cloudforge/landing_zone/zone_provisioner.py +306 -0
  558. tools/cloudforge/landing_zone/zone_state.py +143 -0
  559. tools/cloudforge/mbse_thread/__init__.py +2 -0
  560. tools/cloudforge/mbse_thread/ato_thread_weaver.py +111 -0
  561. tools/cloudforge/mbse_thread/control_tracer.py +68 -0
  562. tools/cloudforge/mbse_thread/system_boundary.py +83 -0
  563. tools/cloudforge/metastore/__init__.py +2 -0
  564. tools/cloudforge/metastore/dependency_graph.py +202 -0
  565. tools/cloudforge/metastore/discovery.py +192 -0
  566. tools/cloudforge/metastore/registry.py +185 -0
  567. tools/cloudforge/metastore/rto_tracker.py +92 -0
  568. tools/cloudforge/metastore/runbook_linker.py +82 -0
  569. tools/cloudforge/migration/__init__.py +2 -0
  570. tools/cloudforge/migration/assessor.py +187 -0
  571. tools/cloudforge/migration/cutover_orchestrator.py +117 -0
  572. tools/cloudforge/migration/databridge_bridge.py +92 -0
  573. tools/cloudforge/migration/planner.py +98 -0
  574. tools/cloudforge/migration/risk_scorer.py +97 -0
  575. tools/cloudforge/migration/validation_runner.py +45 -0
  576. tools/cloudforge/migration/workload_inventory.py +107 -0
  577. tools/cloudforge/provider.py +319 -0
  578. tools/cloudforge/providers/__init__.py +2 -0
  579. tools/cloudforge/providers/aws_commercial.py +92 -0
  580. tools/cloudforge/providers/aws_govcloud.py +229 -0
  581. tools/cloudforge/providers/aws_secret.py +83 -0
  582. tools/cloudforge/providers/azure_commercial.py +80 -0
  583. tools/cloudforge/providers/azure_gov.py +91 -0
  584. tools/cloudforge/providers/azure_secret.py +71 -0
  585. tools/cloudforge/providers/gcp.py +102 -0
  586. tools/cloudforge/providers/oci.py +102 -0
  587. tools/cloudforge/registry.py +140 -0
  588. tools/cloudforge/runbooks/__init__.py +2 -0
  589. tools/cloudforge/runbooks/ai_generator.py +119 -0
  590. tools/cloudforge/runbooks/dag_validator.py +219 -0
  591. tools/cloudforge/runbooks/engine.py +470 -0
  592. tools/cloudforge/runbooks/models.py +99 -0
  593. tools/cloudforge/runbooks/snippet_library.py +158 -0
  594. tools/cloudforge/runbooks/template_loader.py +122 -0
  595. tools/cloudforge/runbooks/visualization.py +108 -0
  596. tools/cloudforge/siem/__init__.py +2 -0
  597. tools/cloudforge/siem/alert_rules.py +86 -0
  598. tools/cloudforge/siem/correlation_engine.py +61 -0
  599. tools/cloudforge/siem/log_aggregator.py +113 -0
  600. tools/cloudforge/siem/siem_dashboard_data.py +28 -0
  601. tools/cloudforge/supply_chain/__init__.py +2 -0
  602. tools/cloudforge/supply_chain/bridge.py +33 -0
  603. tools/cloudforge/supply_chain/iac_dependency_scanner.py +36 -0
  604. tools/cloudforge/supply_chain/provider_trust_scorer.py +54 -0
  605. tools/compat/__init__.py +21 -0
  606. tools/compat/cli_harmonizer.py +251 -0
  607. tools/compat/datetime_utils.py +18 -0
  608. tools/compat/db_utils.py +190 -0
  609. tools/compat/platform_utils.py +123 -0
  610. tools/compliance/__init__.py +1 -0
  611. tools/compliance/accountability_manager.py +391 -0
  612. tools/compliance/ai_accountability_audit.py +287 -0
  613. tools/compliance/ai_impact_assessor.py +267 -0
  614. tools/compliance/ai_incident_response.py +295 -0
  615. tools/compliance/ai_inventory_manager.py +233 -0
  616. tools/compliance/ai_reassessment_scheduler.py +250 -0
  617. tools/compliance/ai_transparency_audit.py +247 -0
  618. tools/compliance/atlas_assessor.py +276 -0
  619. tools/compliance/atlas_report_generator.py +1199 -0
  620. tools/compliance/base_assessor.py +591 -0
  621. tools/compliance/cato_live_engine.py +607 -0
  622. tools/compliance/cato_monitor.py +1371 -0
  623. tools/compliance/cato_scheduler.py +698 -0
  624. tools/compliance/cjis_assessor.py +76 -0
  625. tools/compliance/classification_manager.py +1340 -0
  626. tools/compliance/cmmc_assessor.py +1478 -0
  627. tools/compliance/cmmc_report_generator.py +1087 -0
  628. tools/compliance/compliance_detector.py +452 -0
  629. tools/compliance/compliance_exporter.py +418 -0
  630. tools/compliance/compliance_status.py +810 -0
  631. tools/compliance/control_mapper.py +488 -0
  632. tools/compliance/crosswalk_engine.py +1208 -0
  633. tools/compliance/cssp_assessor.py +1032 -0
  634. tools/compliance/cssp_evidence_collector.py +716 -0
  635. tools/compliance/cssp_report_generator.py +1103 -0
  636. tools/compliance/cui_marker.py +387 -0
  637. tools/compliance/diagram_validator.py +599 -0
  638. tools/compliance/emass/__init__.py +2 -0
  639. tools/compliance/emass/emass_client.py +822 -0
  640. tools/compliance/emass/emass_export.py +758 -0
  641. tools/compliance/emass/emass_sync.py +807 -0
  642. tools/compliance/eu_ai_act_classifier.py +193 -0
  643. tools/compliance/evidence_collector.py +459 -0
  644. tools/compliance/fairness_assessor.py +310 -0
  645. tools/compliance/fedramp_20x_ksi_emitter.py +692 -0
  646. tools/compliance/fedramp_assessor.py +1795 -0
  647. tools/compliance/fedramp_authorization_packager.py +137 -0
  648. tools/compliance/fedramp_ksi_generator.py +349 -0
  649. tools/compliance/fedramp_report_generator.py +1115 -0
  650. tools/compliance/fips199_categorizer.py +869 -0
  651. tools/compliance/fips200_validator.py +304 -0
  652. tools/compliance/firmware_sbom.py +646 -0
  653. tools/compliance/gao_ai_assessor.py +228 -0
  654. tools/compliance/gao_evidence_builder.py +302 -0
  655. tools/compliance/hipaa_assessor.py +78 -0
  656. tools/compliance/hitrust_assessor.py +49 -0
  657. tools/compliance/incident_response_plan.py +705 -0
  658. tools/compliance/inheritance_engine.py +693 -0
  659. tools/compliance/iso27001_assessor.py +92 -0
  660. tools/compliance/iso42001_assessor.py +114 -0
  661. tools/compliance/ivv_assessor.py +2314 -0
  662. tools/compliance/ivv_report_generator.py +1649 -0
  663. tools/compliance/model_card_generator.py +291 -0
  664. tools/compliance/mosa_assessor.py +117 -0
  665. tools/compliance/multi_regime_assessor.py +441 -0
  666. tools/compliance/narrative_generator.py +1012 -0
  667. tools/compliance/narrative_quality_gate.py +701 -0
  668. tools/compliance/narrative_workflow.py +814 -0
  669. tools/compliance/nist_800_207_assessor.py +191 -0
  670. tools/compliance/nist_ai_600_1_assessor.py +185 -0
  671. tools/compliance/nist_ai_rmf_assessor.py +110 -0
  672. tools/compliance/nist_lookup.py +244 -0
  673. tools/compliance/omb_m25_21_assessor.py +225 -0
  674. tools/compliance/omb_m26_04_assessor.py +185 -0
  675. tools/compliance/oscal_catalog_adapter.py +395 -0
  676. tools/compliance/oscal_generator.py +2157 -0
  677. tools/compliance/oscal_tools.py +1182 -0
  678. tools/compliance/oscal_validator.py +692 -0
  679. tools/compliance/owasp_agentic_assessor.py +227 -0
  680. tools/compliance/owasp_asi_assessor.py +197 -0
  681. tools/compliance/owasp_llm_assessor.py +245 -0
  682. tools/compliance/pci_dss_assessor.py +80 -0
  683. tools/compliance/pi_compliance_tracker.py +1447 -0
  684. tools/compliance/poam_generator.py +388 -0
  685. tools/compliance/resolve_marking.py +272 -0
  686. tools/compliance/sbd_assessor.py +2070 -0
  687. tools/compliance/sbd_report_generator.py +1223 -0
  688. tools/compliance/sbom_generator.py +993 -0
  689. tools/compliance/siem_config_generator.py +661 -0
  690. tools/compliance/slsa_attestation_generator.py +479 -0
  691. tools/compliance/soc2_assessor.py +77 -0
  692. tools/compliance/ssp_generator.py +556 -0
  693. tools/compliance/stig_checker.py +712 -0
  694. tools/compliance/swft_evidence_bundler.py +326 -0
  695. tools/compliance/system_card_generator.py +303 -0
  696. tools/compliance/template_exchange.py +513 -0
  697. tools/compliance/traceability_matrix.py +1268 -0
  698. tools/compliance/universal_classification_manager.py +1159 -0
  699. tools/compliance/xacta/__init__.py +2 -0
  700. tools/compliance/xacta/xacta_client.py +438 -0
  701. tools/compliance/xacta/xacta_export.py +546 -0
  702. tools/compliance/xacta/xacta_sync.py +322 -0
  703. tools/compliance/xai_assessor.py +231 -0
  704. tools/core/__init__.py +2 -0
  705. tools/core/circuit_breaker.py +353 -0
  706. tools/core/compliance_sidecar.py +344 -0
  707. tools/core/container.py +110 -0
  708. tools/core/errors.py +256 -0
  709. tools/core/feature_flags.py +311 -0
  710. tools/core/task_dlq.py +350 -0
  711. tools/dashboard/__init__.py +2 -0
  712. tools/dashboard/app.py +6288 -0
  713. tools/dashboard/templates/agent_evolution.html +287 -0
  714. tools/dashboard/templates/agents/list.html +71 -0
  715. tools/dashboard/templates/agents.html +132 -0
  716. tools/dashboard/templates/architecture.html +289 -0
  717. tools/dashboard/templates/ato_simulator.html +170 -0
  718. tools/dashboard/templates/audit_engine.html +844 -0
  719. tools/dashboard/templates/base.html +236 -0
  720. tools/dashboard/templates/cato_live.html +116 -0
  721. tools/dashboard/templates/cloudforge.html +195 -0
  722. tools/dashboard/templates/cloudforge_finops.html +111 -0
  723. tools/dashboard/templates/cloudforge_hybrid.html +122 -0
  724. tools/dashboard/templates/cloudforge_metastore.html +234 -0
  725. tools/dashboard/templates/cloudforge_migration.html +87 -0
  726. tools/dashboard/templates/cloudforge_runbooks.html +201 -0
  727. tools/dashboard/templates/cloudforge_siem.html +94 -0
  728. tools/dashboard/templates/compliance_accel.html +292 -0
  729. tools/dashboard/templates/crashes.html +122 -0
  730. tools/dashboard/templates/databridge.html +305 -0
  731. tools/dashboard/templates/databridge_analytics.html +195 -0
  732. tools/dashboard/templates/databridge_mapping.html +345 -0
  733. tools/dashboard/templates/databridge_messaging.html +321 -0
  734. tools/dashboard/templates/decisions.html +258 -0
  735. tools/dashboard/templates/devices.html +151 -0
  736. tools/dashboard/templates/devsecops_maturity.html +278 -0
  737. tools/dashboard/templates/edge_ai.html +128 -0
  738. tools/dashboard/templates/firmware.html +120 -0
  739. tools/dashboard/templates/firmware_sbom.html +193 -0
  740. tools/dashboard/templates/forge_hub.html +196 -0
  741. tools/dashboard/templates/forge_studio.html +379 -0
  742. tools/dashboard/templates/forge_studio_analytics.html +360 -0
  743. tools/dashboard/templates/forge_studio_builder.html +1637 -0
  744. tools/dashboard/templates/forge_studio_compliance.html +310 -0
  745. tools/dashboard/templates/forge_studio_deploy.html +573 -0
  746. tools/dashboard/templates/forge_studio_enterprise.html +888 -0
  747. tools/dashboard/templates/forge_studio_marketplace.html +502 -0
  748. tools/dashboard/templates/forge_studio_workflow.html +696 -0
  749. tools/dashboard/templates/golden_path.html +175 -0
  750. tools/dashboard/templates/govcon.html +280 -0
  751. tools/dashboard/templates/harness.html +148 -0
  752. tools/dashboard/templates/index.html +207 -0
  753. tools/dashboard/templates/intelligence.html +336 -0
  754. tools/dashboard/templates/knowledge/index.html +190 -0
  755. tools/dashboard/templates/knowledge_graph.html +739 -0
  756. tools/dashboard/templates/login.html +51 -0
  757. tools/dashboard/templates/marketplace.html +336 -0
  758. tools/dashboard/templates/marketplace_admin.html +247 -0
  759. tools/dashboard/templates/missions.html +403 -0
  760. tools/dashboard/templates/narratives.html +154 -0
  761. tools/dashboard/templates/pr_intelligence.html +151 -0
  762. tools/dashboard/templates/proposals/detail.html +300 -0
  763. tools/dashboard/templates/proposals/list.html +52 -0
  764. tools/dashboard/templates/proposals/sam_detail.html +132 -0
  765. tools/dashboard/templates/proposals/section_detail.html +375 -0
  766. tools/dashboard/templates/research.html +222 -0
  767. tools/dashboard/templates/resilience.html +300 -0
  768. tools/dashboard/templates/scorecard.html +162 -0
  769. tools/dashboard/templates/simulator.html +131 -0
  770. tools/dashboard/templates/template_exchange.html +147 -0
  771. tools/dashboard/templates/thread_heatmap.html +151 -0
  772. tools/dashboard/templates/threat_model.html +195 -0
  773. tools/dashboard/templates/vsm.html +141 -0
  774. tools/dashboard/templates/writeguard.html +277 -0
  775. tools/databridge/__init__.py +5 -0
  776. tools/databridge/agent/__init__.py +2 -0
  777. tools/databridge/agent/daemon.py +227 -0
  778. tools/databridge/agent/tunnel.py +101 -0
  779. tools/databridge/agent/ws_relay.py +91 -0
  780. tools/databridge/analytics.py +167 -0
  781. tools/databridge/arrow_pipeline.py +327 -0
  782. tools/databridge/connection_manager.py +424 -0
  783. tools/databridge/connector.py +331 -0
  784. tools/databridge/connectors/__init__.py +2 -0
  785. tools/databridge/connectors/argocd_connector.py +160 -0
  786. tools/databridge/connectors/avro_connector.py +203 -0
  787. tools/databridge/connectors/azure_blob.py +63 -0
  788. tools/databridge/connectors/cdc_connector.py +205 -0
  789. tools/databridge/connectors/csv_connector.py +172 -0
  790. tools/databridge/connectors/datadog_connector.py +153 -0
  791. tools/databridge/connectors/discord_messaging.py +215 -0
  792. tools/databridge/connectors/dynamics365.py +151 -0
  793. tools/databridge/connectors/elasticsearch_connector.py +145 -0
  794. tools/databridge/connectors/email_base.py +114 -0
  795. tools/databridge/connectors/excel_connector.py +175 -0
  796. tools/databridge/connectors/fsspec_base.py +300 -0
  797. tools/databridge/connectors/gcs.py +53 -0
  798. tools/databridge/connectors/github_connector.py +138 -0
  799. tools/databridge/connectors/gitlab_connector.py +132 -0
  800. tools/databridge/connectors/gmail_connector.py +182 -0
  801. tools/databridge/connectors/hdfs.py +57 -0
  802. tools/databridge/connectors/health_base.py +401 -0
  803. tools/databridge/connectors/hubspot.py +124 -0
  804. tools/databridge/connectors/imap_connector.py +171 -0
  805. tools/databridge/connectors/jenkins_connector.py +138 -0
  806. tools/databridge/connectors/jira_connector.py +86 -0
  807. tools/databridge/connectors/json_connector.py +184 -0
  808. tools/databridge/connectors/kafka_connector.py +246 -0
  809. tools/databridge/connectors/kinesis_connector.py +238 -0
  810. tools/databridge/connectors/local_fs.py +30 -0
  811. tools/databridge/connectors/matrix.py +197 -0
  812. tools/databridge/connectors/mattermost_messaging.py +184 -0
  813. tools/databridge/connectors/messaging_base.py +172 -0
  814. tools/databridge/connectors/mssql.py +63 -0
  815. tools/databridge/connectors/mysql.py +57 -0
  816. tools/databridge/connectors/netsuite.py +170 -0
  817. tools/databridge/connectors/o365_mail.py +196 -0
  818. tools/databridge/connectors/oracle.py +65 -0
  819. tools/databridge/connectors/pagerduty_connector.py +162 -0
  820. tools/databridge/connectors/parquet_connector.py +131 -0
  821. tools/databridge/connectors/postgresql.py +58 -0
  822. tools/databridge/connectors/s3.py +65 -0
  823. tools/databridge/connectors/saas_base.py +198 -0
  824. tools/databridge/connectors/salesforce.py +126 -0
  825. tools/databridge/connectors/sap.py +89 -0
  826. tools/databridge/connectors/servicenow.py +60 -0
  827. tools/databridge/connectors/signal_messaging.py +150 -0
  828. tools/databridge/connectors/slack_messaging.py +203 -0
  829. tools/databridge/connectors/smtp_connector.py +126 -0
  830. tools/databridge/connectors/soap_base.py +258 -0
  831. tools/databridge/connectors/splunk_connector.py +171 -0
  832. tools/databridge/connectors/sql_base.py +310 -0
  833. tools/databridge/connectors/sqlite_connector.py +76 -0
  834. tools/databridge/connectors/teams.py +148 -0
  835. tools/databridge/connectors/telegram.py +192 -0
  836. tools/databridge/connectors/whatsapp.py +137 -0
  837. tools/databridge/data_profiler.py +99 -0
  838. tools/databridge/forge/__init__.py +6 -0
  839. tools/databridge/forge/base_selector.py +150 -0
  840. tools/databridge/forge/code_generator.py +206 -0
  841. tools/databridge/forge/community_hub.py +539 -0
  842. tools/databridge/forge/forge_agent.py +306 -0
  843. tools/databridge/forge/import_handler.py +133 -0
  844. tools/databridge/forge/integration_tester.py +127 -0
  845. tools/databridge/forge/marketplace_publisher.py +164 -0
  846. tools/databridge/forge/promoter.py +159 -0
  847. tools/databridge/forge/sandbox_manager.py +257 -0
  848. tools/databridge/forge/spec_parser.py +358 -0
  849. tools/databridge/forge/static_validator.py +363 -0
  850. tools/databridge/forge/templates/__init__.py +591 -0
  851. tools/databridge/format_converter.py +188 -0
  852. tools/databridge/mapping_engine.py +348 -0
  853. tools/databridge/messaging/__init__.py +5 -0
  854. tools/databridge/messaging/agent_bridge.py +254 -0
  855. tools/databridge/messaging/message_envelope.py +111 -0
  856. tools/databridge/messaging/message_logger.py +204 -0
  857. tools/databridge/messaging/messaging_daemon.py +326 -0
  858. tools/databridge/messaging/oauth2_manager.py +411 -0
  859. tools/databridge/pii_detector.py +221 -0
  860. tools/databridge/registry.py +352 -0
  861. tools/databridge/relay_server.py +105 -0
  862. tools/databridge/scale/__init__.py +16 -0
  863. tools/databridge/scale/backpressure.py +134 -0
  864. tools/databridge/scale/chunked_pipeline.py +169 -0
  865. tools/databridge/scale/connection_pool.py +293 -0
  866. tools/databridge/scale/engine.py +492 -0
  867. tools/databridge/scale/worker_pool.py +140 -0
  868. tools/databridge/scale/write_batcher.py +250 -0
  869. tools/databridge/schema_engine.py +324 -0
  870. tools/databridge/stream_manager.py +225 -0
  871. tools/databridge/sync_engine.py +411 -0
  872. tools/databridge/transforms.py +302 -0
  873. tools/db/__init__.py +1 -0
  874. tools/db/backup.py +312 -0
  875. tools/db/backup_manager.py +832 -0
  876. tools/db/init_icdev_db.py +7753 -0
  877. tools/db/init_sparkpilot_db.py +431 -0
  878. tools/db/migrate.py +177 -0
  879. tools/db/migrate_innovation_audit.py +165 -0
  880. tools/db/migration_runner.py +548 -0
  881. tools/db/migrations/001_baseline/meta.json +9 -0
  882. tools/db/migrations/001_baseline/up.py +67 -0
  883. tools/db/migrations/002_memory_enhancements/down.sql +8 -0
  884. tools/db/migrations/002_memory_enhancements/meta.json +9 -0
  885. tools/db/migrations/002_memory_enhancements/up.py +119 -0
  886. tools/db/migrations/003_dev_profiles/meta.json +8 -0
  887. tools/db/migrations/003_dev_profiles/up.py +93 -0
  888. tools/db/migrations/004_innovation_engine/down.py +19 -0
  889. tools/db/migrations/004_innovation_engine/up.py +227 -0
  890. tools/db/migrations/005_phase_37_ai_security/down.py +19 -0
  891. tools/db/migrations/005_phase_37_ai_security/up.py +257 -0
  892. tools/db/migrations/006_phase_36_evolution/down.py +21 -0
  893. tools/db/migrations/006_phase_36_evolution/up.py +323 -0
  894. tools/db/migrations/007_phase_38_cloud/down.py +14 -0
  895. tools/db/migrations/007_phase_38_cloud/up.py +110 -0
  896. tools/db/migrations/008_phase36_37_integration/up.py +55 -0
  897. tools/db/migrations/__init__.py +2 -0
  898. tools/db/pg_migrate.py +642 -0
  899. tools/db/storage.py +1080 -0
  900. tools/decisions/__init__.py +2 -0
  901. tools/decisions/dmn_engine.py +695 -0
  902. tools/devsecops/__init__.py +2 -0
  903. tools/devsecops/attestation_manager.py +449 -0
  904. tools/devsecops/network_segmentation_generator.py +604 -0
  905. tools/devsecops/pdp_config_generator.py +1246 -0
  906. tools/devsecops/pipeline_security_generator.py +475 -0
  907. tools/devsecops/policy_generator.py +644 -0
  908. tools/devsecops/profile_manager.py +374 -0
  909. tools/devsecops/service_mesh_generator.py +1063 -0
  910. tools/devsecops/zta_maturity_scorer.py +355 -0
  911. tools/devsecops/zta_terraform_generator.py +1301 -0
  912. tools/edge_ai/__init__.py +2 -0
  913. tools/edge_ai/model_manager.py +200 -0
  914. tools/embedded/__init__.py +2 -0
  915. tools/embedded/cmake_generator.py +318 -0
  916. tools/embedded/crash_analyzer.py +191 -0
  917. tools/embedded/nl_to_firmware.py +277 -0
  918. tools/events/__init__.py +1 -0
  919. tools/events/event_bus.py +199 -0
  920. tools/finetune/pair_generator.py +832 -0
  921. tools/fleet/__init__.py +2 -0
  922. tools/fleet/device_registry.py +148 -0
  923. tools/fleet/ota_manager.py +153 -0
  924. tools/forge_studio/__init__.py +13 -0
  925. tools/forge_studio/analytics/__init__.py +0 -0
  926. tools/forge_studio/analytics/process_miner.py +383 -0
  927. tools/forge_studio/audit.py +183 -0
  928. tools/forge_studio/blueprint/__init__.py +2 -0
  929. tools/forge_studio/blueprint/build_tracker.py +317 -0
  930. tools/forge_studio/blueprint/export_engine.py +441 -0
  931. tools/forge_studio/blueprint/parent_client.py +335 -0
  932. tools/forge_studio/catalog/__init__.py +2 -0
  933. tools/forge_studio/catalog/component_registry.py +176 -0
  934. tools/forge_studio/catalog/schema_validator.py +193 -0
  935. tools/forge_studio/compliance/__init__.py +1 -0
  936. tools/forge_studio/compliance/compliance_wiring.py +554 -0
  937. tools/forge_studio/deploy/__init__.py +1 -0
  938. tools/forge_studio/deploy/airgap_packager.py +466 -0
  939. tools/forge_studio/deploy/deploy_engine.py +1792 -0
  940. tools/forge_studio/deploy/env_manager.py +431 -0
  941. tools/forge_studio/eject/__init__.py +2 -0
  942. tools/forge_studio/eject/docker_compose_generator.py +237 -0
  943. tools/forge_studio/eject/eject_engine.py +230 -0
  944. tools/forge_studio/eject/expo_scaffolder.py +303 -0
  945. tools/forge_studio/eject/nextjs_scaffolder.py +338 -0
  946. tools/forge_studio/enterprise/__init__.py +0 -0
  947. tools/forge_studio/enterprise/custom_frameworks.py +826 -0
  948. tools/forge_studio/enterprise/hardening_engine.py +1530 -0
  949. tools/forge_studio/enterprise/sso_manager.py +718 -0
  950. tools/forge_studio/enterprise/whitelabel_engine.py +887 -0
  951. tools/forge_studio/formula/__init__.py +0 -0
  952. tools/forge_studio/formula/expression_engine.py +562 -0
  953. tools/forge_studio/formula/formula_registry.py +265 -0
  954. tools/forge_studio/generator/__init__.py +2 -0
  955. tools/forge_studio/generator/app_generator.py +584 -0
  956. tools/forge_studio/generator/complexity_detector.py +368 -0
  957. tools/forge_studio/generator/prompt_templates.py +104 -0
  958. tools/forge_studio/generator/spec_builder.py +192 -0
  959. tools/forge_studio/intake_bridge.py +898 -0
  960. tools/forge_studio/marketplace/__init__.py +0 -0
  961. tools/forge_studio/marketplace/component_hub.py +428 -0
  962. tools/forge_studio/models.py +369 -0
  963. tools/forge_studio/renderer/__init__.py +2 -0
  964. tools/forge_studio/renderer/json_render_engine.py +623 -0
  965. tools/forge_studio/renderer/layout_engine.py +214 -0
  966. tools/forge_studio/renderer/rn_component_map.py +182 -0
  967. tools/forge_studio/supabase/__init__.py +2 -0
  968. tools/forge_studio/supabase/auth_generator.py +283 -0
  969. tools/forge_studio/supabase/migration_generator.py +93 -0
  970. tools/forge_studio/supabase/schema_generator.py +281 -0
  971. tools/forge_studio/tenant_manager.py +387 -0
  972. tools/forge_studio/workflow/__init__.py +2 -0
  973. tools/forge_studio/workflow/bpmn_adapter.py +489 -0
  974. tools/govcon/draft_orchestrator.py +1151 -0
  975. tools/govcon/engine_enrichment.py +373 -0
  976. tools/govcon/knowledge_base.py +487 -0
  977. tools/govcon/knowledge_ingestion.py +510 -0
  978. tools/govcon/sam_scanner.py +754 -0
  979. tools/harness/__init__.py +6 -0
  980. tools/harness/exit_criteria_evaluator.py +231 -0
  981. tools/harness/maturity_assessor.py +347 -0
  982. tools/harness/scaffold_harness.py +416 -0
  983. tools/harness/trace_analyzer.py +281 -0
  984. tools/infra/__init__.py +1 -0
  985. tools/infra/ansible_generator.py +867 -0
  986. tools/infra/dockerfile_generator.py +359 -0
  987. tools/infra/infra_status.py +384 -0
  988. tools/infra/ironbank_metadata_generator.py +403 -0
  989. tools/infra/k8s_generator.py +1000 -0
  990. tools/infra/pipeline_generator.py +830 -0
  991. tools/infra/rollback.py +389 -0
  992. tools/infra/terraform_generator.py +1140 -0
  993. tools/infra/terraform_generator_azure.py +1252 -0
  994. tools/infra/terraform_generator_gcp.py +951 -0
  995. tools/infra/terraform_generator_ibm.py +359 -0
  996. tools/infra/terraform_generator_oci.py +918 -0
  997. tools/infra/terraform_generator_onprem.py +318 -0
  998. tools/knowledge/__init__.py +1 -0
  999. tools/knowledge/knowledge_ingest.py +281 -0
  1000. tools/knowledge/pattern_detector.py +681 -0
  1001. tools/knowledge/recommendation_engine.py +449 -0
  1002. tools/knowledge/self_heal_analyzer.py +492 -0
  1003. tools/knowledge_graph/__init__.py +2 -0
  1004. tools/knowledge_graph/graph_rag.py +498 -0
  1005. tools/knowledge_graph/ingester.py +406 -0
  1006. tools/knowledge_graph/insight_generator.py +369 -0
  1007. tools/knowledge_graph/text_network.py +832 -0
  1008. tools/llm/__init__.py +72 -0
  1009. tools/llm/anthropic_provider.py +170 -0
  1010. tools/llm/azure_openai_provider.py +338 -0
  1011. tools/llm/bedrock_provider.py +315 -0
  1012. tools/llm/embedding_provider.py +438 -0
  1013. tools/llm/gemini_provider.py +381 -0
  1014. tools/llm/ibm_watsonx_provider.py +231 -0
  1015. tools/llm/oci_genai_provider.py +462 -0
  1016. tools/llm/ollama_provider.py +350 -0
  1017. tools/llm/openai_provider.py +225 -0
  1018. tools/llm/prompt_registry.py +447 -0
  1019. tools/llm/provider.py +355 -0
  1020. tools/llm/provider_sdk.py +175 -0
  1021. tools/llm/router.py +1124 -0
  1022. tools/llm/semantic_cache.py +394 -0
  1023. tools/llm/vertex_ai_provider.py +374 -0
  1024. tools/maintenance/__init__.py +2 -0
  1025. tools/maintenance/dependency_scanner.py +1016 -0
  1026. tools/maintenance/maintenance_auditor.py +804 -0
  1027. tools/maintenance/remediation_engine.py +957 -0
  1028. tools/maintenance/vulnerability_checker.py +978 -0
  1029. tools/manifest.md +1066 -0
  1030. tools/marketplace/asset_installer.py +639 -0
  1031. tools/marketplace/feedback_validator.py +359 -0
  1032. tools/marketplace/license_client.py +458 -0
  1033. tools/marketplace/module_crypto.py +544 -0
  1034. tools/marketplace/module_runtime.py +236 -0
  1035. tools/marketplace/token_store.py +264 -0
  1036. tools/mbse/__init__.py +3 -0
  1037. tools/mbse/des_assessor.py +1173 -0
  1038. tools/mbse/des_report_generator.py +787 -0
  1039. tools/mbse/diagram_extractor.py +792 -0
  1040. tools/mbse/digital_thread.py +1650 -0
  1041. tools/mbse/model_code_generator.py +1115 -0
  1042. tools/mbse/model_control_mapper.py +410 -0
  1043. tools/mbse/pi_model_tracker.py +1079 -0
  1044. tools/mbse/reqif_parser.py +1468 -0
  1045. tools/mbse/sync_engine.py +1789 -0
  1046. tools/mbse/thread_heatmap.py +445 -0
  1047. tools/mbse/xmi_parser.py +1558 -0
  1048. tools/mcp/builder_server.py +64 -0
  1049. tools/mcp/compliance_server.py +64 -0
  1050. tools/mcp/connector_forge_server.py +155 -0
  1051. tools/mcp/core_server.py +64 -0
  1052. tools/mcp/devsecops_server.py +11 -0
  1053. tools/mcp/devsecops_zta_server.py +64 -0
  1054. tools/mcp/knowledge_server.py +64 -0
  1055. tools/mcp/monitor_server.py +64 -0
  1056. tools/mcp/ops_server.py +300 -0
  1057. tools/mcp/requirements_analyst_server.py +64 -0
  1058. tools/mcp/requirements_server.py +11 -0
  1059. tools/mcp/security_server.py +64 -0
  1060. tools/mcp/simulation_server.py +64 -0
  1061. tools/mcp/supply_chain_server.py +64 -0
  1062. tools/mcp/tool_registry.py +299 -0
  1063. tools/memory/__init__.py +2 -0
  1064. tools/memory/auto_capture.py +346 -0
  1065. tools/memory/embed_memory.py +157 -0
  1066. tools/memory/history_compressor.py +334 -0
  1067. tools/memory/hybrid_search.py +235 -0
  1068. tools/memory/maintenance_cron.py +288 -0
  1069. tools/memory/memory_consolidation.py +439 -0
  1070. tools/memory/memory_db.py +132 -0
  1071. tools/memory/memory_read.py +101 -0
  1072. tools/memory/memory_write.py +221 -0
  1073. tools/memory/semantic_search.py +138 -0
  1074. tools/memory/time_decay.py +434 -0
  1075. tools/missions/__init__.py +2 -0
  1076. tools/missions/mission_engine.py +459 -0
  1077. tools/monitor/__init__.py +1 -0
  1078. tools/monitor/alert_correlator.py +486 -0
  1079. tools/monitor/auto_resolver.py +603 -0
  1080. tools/monitor/health_checker.py +507 -0
  1081. tools/monitor/heartbeat_daemon.py +779 -0
  1082. tools/monitor/log_analyzer.py +507 -0
  1083. tools/monitor/metric_collector.py +484 -0
  1084. tools/mosa/__init__.py +10 -0
  1085. tools/mosa/icd_generator.py +358 -0
  1086. tools/mosa/modular_design_analyzer.py +682 -0
  1087. tools/mosa/mosa_code_enforcer.py +348 -0
  1088. tools/mosa/tsp_generator.py +265 -0
  1089. tools/observability/__init__.py +100 -0
  1090. tools/observability/genai_attributes.py +88 -0
  1091. tools/observability/instrumentation.py +140 -0
  1092. tools/observability/mlflow_exporter.py +193 -0
  1093. tools/observability/otel_tracer.py +168 -0
  1094. tools/observability/provenance/__init__.py +3 -0
  1095. tools/observability/provenance/prov_recorder.py +322 -0
  1096. tools/observability/shap/__init__.py +3 -0
  1097. tools/observability/shap/agent_shap.py +274 -0
  1098. tools/observability/sqlite_tracer.py +360 -0
  1099. tools/observability/trace_context.py +205 -0
  1100. tools/observability/tracer.py +230 -0
  1101. tools/orchestration/__init__.py +1 -0
  1102. tools/orchestration/peer_channels.py +254 -0
  1103. tools/orchestration/saga_coordinator.py +390 -0
  1104. tools/project/__init__.py +1 -0
  1105. tools/project/manifest_loader.py +418 -0
  1106. tools/project/project_create.py +350 -0
  1107. tools/project/project_list.py +171 -0
  1108. tools/project/project_scaffold.py +1715 -0
  1109. tools/project/project_status.py +478 -0
  1110. tools/project/session_context_builder.py +752 -0
  1111. tools/project/validate_manifest.py +54 -0
  1112. tools/rag/corrective_rag.py +582 -0
  1113. tools/rag/source_registry.py +482 -0
  1114. tools/requirements/__init__.py +1 -0
  1115. tools/requirements/ai_governance_scorer.py +207 -0
  1116. tools/requirements/boundary_analyzer.py +1281 -0
  1117. tools/requirements/clarification_engine.py +605 -0
  1118. tools/requirements/complexity_scorer.py +369 -0
  1119. tools/requirements/consistency_analyzer.py +789 -0
  1120. tools/requirements/constitution_manager.py +592 -0
  1121. tools/requirements/decomposition_engine.py +764 -0
  1122. tools/requirements/document_extractor.py +1002 -0
  1123. tools/requirements/elicitation_techniques.py +508 -0
  1124. tools/requirements/gap_detector.py +260 -0
  1125. tools/requirements/intake_engine.py +2175 -0
  1126. tools/requirements/prd_generator.py +839 -0
  1127. tools/requirements/prd_validator.py +584 -0
  1128. tools/requirements/readiness_scorer.py +302 -0
  1129. tools/requirements/spec_organizer.py +1015 -0
  1130. tools/requirements/spec_quality_checker.py +1083 -0
  1131. tools/requirements/traceability_builder.py +566 -0
  1132. tools/research/__init__.py +3 -0
  1133. tools/research/academic_scanner.py +130 -0
  1134. tools/research/build_buy_analyzer.py +229 -0
  1135. tools/research/challenge_scorer.py +280 -0
  1136. tools/research/community_scanner.py +174 -0
  1137. tools/research/cross_engine_bridge.py +124 -0
  1138. tools/research/dossier_generator.py +305 -0
  1139. tools/research/landscape_scanner.py +315 -0
  1140. tools/research/regulatory_scanner.py +248 -0
  1141. tools/research/research_manager.py +469 -0
  1142. tools/research/source_scanner.py +150 -0
  1143. tools/research/vertical_loader.py +118 -0
  1144. tools/saas/__init__.py +0 -0
  1145. tools/saas/licensing/__init__.py +0 -0
  1146. tools/saas/licensing/license_validator.py +345 -0
  1147. tools/scaffold/__init__.py +2 -0
  1148. tools/scaffold/golden_path.py +504 -0
  1149. tools/security/__init__.py +1 -0
  1150. tools/security/agent_output_validator.py +330 -0
  1151. tools/security/agent_trust_scorer.py +652 -0
  1152. tools/security/ai_bom_generator.py +718 -0
  1153. tools/security/ai_telemetry_logger.py +469 -0
  1154. tools/security/atlas_red_team.py +541 -0
  1155. tools/security/code_pattern_scanner.py +382 -0
  1156. tools/security/confabulation_detector.py +265 -0
  1157. tools/security/container_scanner.py +489 -0
  1158. tools/security/dependency_auditor.py +942 -0
  1159. tools/security/endpoint_security_scanner.py +626 -0
  1160. tools/security/mcp_tool_authorizer.py +242 -0
  1161. tools/security/output_verifier.py +427 -0
  1162. tools/security/prompt_injection_detector.py +737 -0
  1163. tools/security/sast_runner.py +946 -0
  1164. tools/security/secret_detector.py +376 -0
  1165. tools/security/threat_modeler.py +678 -0
  1166. tools/security/tool_chain_validator.py +357 -0
  1167. tools/security/vuln_scanner.py +536 -0
  1168. tools/simulation/__init__.py +2 -0
  1169. tools/simulation/ato_simulator.py +517 -0
  1170. tools/simulation/coa_generator.py +1539 -0
  1171. tools/simulation/monte_carlo.py +745 -0
  1172. tools/simulation/scenario_manager.py +1060 -0
  1173. tools/simulation/simulation_engine.py +1091 -0
  1174. tools/simulator/__init__.py +2 -0
  1175. tools/simulator/sim_runner.py +272 -0
  1176. tools/supply_chain/__init__.py +2 -0
  1177. tools/supply_chain/cve_triager.py +690 -0
  1178. tools/supply_chain/dependency_graph.py +630 -0
  1179. tools/supply_chain/isa_manager.py +526 -0
  1180. tools/supply_chain/scrm_assessor.py +531 -0
  1181. tools/supply_chain/slsa_verifier.py +473 -0
  1182. tools/testing/__init__.py +2 -0
  1183. tools/testing/acceptance_validator.py +411 -0
  1184. tools/testing/api_surface_extractor.py +749 -0
  1185. tools/testing/claude_dir_validator.py +831 -0
  1186. tools/testing/data_types.py +199 -0
  1187. tools/testing/e2e_runner.py +715 -0
  1188. tools/testing/fuzz_cli.py +306 -0
  1189. tools/testing/health_check.py +483 -0
  1190. tools/testing/platform_check.py +143 -0
  1191. tools/testing/production_audit.py +1836 -0
  1192. tools/testing/production_remediate.py +803 -0
  1193. tools/testing/screenshot_validator.py +538 -0
  1194. tools/testing/smoke_test.py +283 -0
  1195. tools/testing/test_agent_models.py +117 -0
  1196. tools/testing/test_orchestrator.py +957 -0
  1197. tools/testing/utils.py +229 -0
  1198. tools/writeguard/__init__.py +1 -0
  1199. tools/writeguard/main.py +1 -0
  1200. tools/writing/__init__.py +7 -0
  1201. tools/writing/ai_content_detector.py +316 -0
  1202. tools/writing/analysis_engine.py +454 -0
  1203. tools/writing/batch_analyzer.py +276 -0
  1204. tools/writing/coherence_analyzer.py +221 -0
  1205. tools/writing/govcon_bridge.py +509 -0
  1206. tools/writing/grammar_checker.py +270 -0
  1207. tools/writing/plagiarism_detector.py +106 -0
  1208. tools/writing/readability_scorer.py +201 -0
  1209. tools/writing/rewriter.py +96 -0
  1210. tools/writing/signal_registrar.py +167 -0
  1211. tools/writing/snippet_manager.py +276 -0
  1212. tools/writing/style_enforcer.py +220 -0
  1213. tools/writing/style_guide_manager.py +438 -0
  1214. tools/writing/tone_profiler.py +168 -0
@@ -0,0 +1,1789 @@
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 tools.db.storage import get_connection
43
+
44
+ # ---------------------------------------------------------------------------
45
+ # Path constants
46
+ # ---------------------------------------------------------------------------
47
+ BASE_DIR = Path(__file__).resolve().parent.parent.parent
48
+
49
+ # ---------------------------------------------------------------------------
50
+ # Audit logger — graceful fallback for standalone execution
51
+ # ---------------------------------------------------------------------------
52
+ try:
53
+ from tools.audit.audit_logger import log_event # type: ignore
54
+ _HAS_AUDIT = True
55
+ except ImportError:
56
+ _HAS_AUDIT = False
57
+
58
+ def log_event(**kwargs) -> int: # noqa: D103 – stub
59
+ return -1
60
+
61
+ # ---------------------------------------------------------------------------
62
+ # XMI namespace constants (match xmi_parser.py)
63
+ # ---------------------------------------------------------------------------
64
+ XMI_NS = "http://www.omg.org/spec/XMI/20131001"
65
+ UML_NS = "http://www.omg.org/spec/UML/20131001"
66
+ SYSML_NS = "http://www.omg.org/spec/SysML/20181001"
67
+
68
+ # ---------------------------------------------------------------------------
69
+ # Helpers
70
+ # ---------------------------------------------------------------------------
71
+
72
+ def _ts() -> str:
73
+ """Current ISO-8601 timestamp."""
74
+ return datetime.now().isoformat()
75
+
76
+
77
+ def _new_id(prefix: str = "sysml") -> str:
78
+ """Generate a prefixed UUID."""
79
+ return f"{prefix}-{uuid.uuid4()}"
80
+
81
+
82
+ def _compute_file_hash(file_path: str) -> str:
83
+ """Compute SHA-256 hex digest of a file.
84
+
85
+ Reads in 64 KiB chunks to handle large files without excessive memory use.
86
+ Returns empty string if the file does not exist.
87
+ """
88
+ fpath = Path(file_path)
89
+ if not fpath.exists():
90
+ return ""
91
+ h = hashlib.sha256()
92
+ with open(fpath, "rb") as fh:
93
+ for chunk in iter(lambda: fh.read(65536), b""):
94
+ h.update(chunk)
95
+ return h.hexdigest()
96
+
97
+
98
+ def _content_hash(text: str) -> str:
99
+ """Return SHA-256 hex digest of a string."""
100
+ return hashlib.sha256(text.encode("utf-8")).hexdigest()
101
+
102
+
103
+ # ---------------------------------------------------------------------------
104
+ # Python AST parsing (code -> model direction)
105
+ # ---------------------------------------------------------------------------
106
+
107
+ def _parse_python_ast(file_path: str) -> dict:
108
+ """Parse a Python file using the ast module.
109
+
110
+ Extracts top-level classes (with bases, methods, attributes) and
111
+ top-level functions (with arguments and docstrings).
112
+
113
+ Returns::
114
+
115
+ {
116
+ "classes": [
117
+ {
118
+ "name": str,
119
+ "bases": [str, ...],
120
+ "methods": [{"name": str, "args": [str], "docstring": str}, ...],
121
+ "attributes": [str, ...]
122
+ },
123
+ ...
124
+ ],
125
+ "functions": [
126
+ {"name": str, "args": [str, ...], "docstring": str},
127
+ ...
128
+ ],
129
+ }
130
+ """
131
+ fpath = Path(file_path)
132
+ if not fpath.exists():
133
+ return {"classes": [], "functions": []}
134
+
135
+ source = fpath.read_text(encoding="utf-8", errors="replace")
136
+ try:
137
+ tree = ast.parse(source, filename=str(fpath))
138
+ except SyntaxError:
139
+ return {"classes": [], "functions": []}
140
+
141
+ classes: List[Dict[str, Any]] = []
142
+ functions: List[Dict[str, Any]] = []
143
+
144
+ for node in ast.iter_child_nodes(tree):
145
+ if isinstance(node, ast.ClassDef):
146
+ bases = []
147
+ for base in node.bases:
148
+ if isinstance(base, ast.Name):
149
+ bases.append(base.id)
150
+ elif isinstance(base, ast.Attribute):
151
+ bases.append(ast.dump(base))
152
+ else:
153
+ bases.append(ast.dump(base))
154
+
155
+ methods: List[Dict[str, Any]] = []
156
+ attributes: List[str] = []
157
+
158
+ for item in ast.iter_child_nodes(node):
159
+ if isinstance(item, ast.FunctionDef) or isinstance(item, ast.AsyncFunctionDef):
160
+ method_args = []
161
+ for arg in item.args.args:
162
+ if arg.arg != "self":
163
+ method_args.append(arg.arg)
164
+ method_doc = ast.get_docstring(item) or ""
165
+ methods.append({
166
+ "name": item.name,
167
+ "args": method_args,
168
+ "docstring": method_doc,
169
+ })
170
+ elif isinstance(item, ast.Assign):
171
+ for target in item.targets:
172
+ if isinstance(target, ast.Name):
173
+ attributes.append(target.id)
174
+ elif isinstance(item, ast.AnnAssign):
175
+ if isinstance(item.target, ast.Name):
176
+ attributes.append(item.target.id)
177
+
178
+ classes.append({
179
+ "name": node.name,
180
+ "bases": bases,
181
+ "methods": methods,
182
+ "attributes": attributes,
183
+ })
184
+
185
+ elif isinstance(node, ast.FunctionDef) or isinstance(node, ast.AsyncFunctionDef):
186
+ func_args = [arg.arg for arg in node.args.args]
187
+ func_doc = ast.get_docstring(node) or ""
188
+ functions.append({
189
+ "name": node.name,
190
+ "args": func_args,
191
+ "docstring": func_doc,
192
+ })
193
+
194
+ return {"classes": classes, "functions": functions}
195
+
196
+
197
+ # ---------------------------------------------------------------------------
198
+ # XMI fragment generation (code -> model direction)
199
+ # ---------------------------------------------------------------------------
200
+
201
+ def _generate_xmi_fragment(elements: list) -> str:
202
+ """Generate an XMI 2.5 fragment for import into Cameo Systems Modeler.
203
+
204
+ Each element dict must contain at minimum:
205
+ - name (str)
206
+ - element_type (str): 'class', 'function', or 'interface'
207
+ - properties (dict, optional): methods, attributes, args, etc.
208
+
209
+ Returns well-formed XML string.
210
+ """
211
+ root = ET.Element("xmi:XMI")
212
+ root.set("xmlns:xmi", XMI_NS)
213
+ root.set("xmlns:uml", UML_NS)
214
+ root.set("xmlns:sysml", SYSML_NS)
215
+ root.set("xmi:version", "2.5")
216
+
217
+ model = ET.SubElement(root, "uml:Model")
218
+ model.set("xmi:id", f"model-{uuid.uuid4()}")
219
+ model.set("name", "CodeSyncImport")
220
+
221
+ pkg = ET.SubElement(model, "packagedElement")
222
+ pkg.set("xmi:type", "uml:Package")
223
+ pkg.set("xmi:id", f"pkg-{uuid.uuid4()}")
224
+ pkg.set("name", "SyncedFromCode")
225
+
226
+ for elem in elements:
227
+ etype = elem.get("element_type", "class")
228
+ name = elem.get("name", "Unknown")
229
+ props = elem.get("properties", {})
230
+ xmi_id = elem.get("xmi_id", f"elem-{uuid.uuid4()}")
231
+
232
+ if etype in ("class", "block"):
233
+ pe = ET.SubElement(pkg, "packagedElement")
234
+ pe.set("xmi:type", "uml:Class")
235
+ pe.set("xmi:id", xmi_id)
236
+ pe.set("name", name)
237
+
238
+ # Add attributes as ownedAttribute
239
+ for attr_name in props.get("attributes", []):
240
+ oa = ET.SubElement(pe, "ownedAttribute")
241
+ oa.set("xmi:type", "uml:Property")
242
+ oa.set("xmi:id", f"attr-{uuid.uuid4()}")
243
+ oa.set("name", attr_name)
244
+ oa.set("visibility", "public")
245
+
246
+ # Add methods as ownedOperation
247
+ for method in props.get("methods", []):
248
+ op = ET.SubElement(pe, "ownedOperation")
249
+ op.set("xmi:type", "uml:Operation")
250
+ op.set("xmi:id", f"op-{uuid.uuid4()}")
251
+ op.set("name", method.get("name", ""))
252
+ op.set("visibility", "public")
253
+
254
+ # Parameters
255
+ for arg_name in method.get("args", []):
256
+ param = ET.SubElement(op, "ownedParameter")
257
+ param.set("xmi:id", f"param-{uuid.uuid4()}")
258
+ param.set("name", arg_name)
259
+ param.set("direction", "in")
260
+
261
+ # Docstring as ownedComment
262
+ docstring = method.get("docstring", "")
263
+ if docstring:
264
+ comment = ET.SubElement(op, "ownedComment")
265
+ comment.set("xmi:id", f"cmt-{uuid.uuid4()}")
266
+ body = ET.SubElement(comment, "body")
267
+ body.text = docstring
268
+
269
+ # Bases as generalization
270
+ for base_name in props.get("bases", []):
271
+ gen = ET.SubElement(pe, "generalization")
272
+ gen.set("xmi:type", "uml:Generalization")
273
+ gen.set("xmi:id", f"gen-{uuid.uuid4()}")
274
+ gen.set("general", base_name)
275
+
276
+ elif etype == "function":
277
+ # Top-level function as a stereotyped class with a single operation
278
+ pe = ET.SubElement(pkg, "packagedElement")
279
+ pe.set("xmi:type", "uml:Class")
280
+ pe.set("xmi:id", xmi_id)
281
+ pe.set("name", name)
282
+
283
+ op = ET.SubElement(pe, "ownedOperation")
284
+ op.set("xmi:type", "uml:Operation")
285
+ op.set("xmi:id", f"op-{uuid.uuid4()}")
286
+ op.set("name", name)
287
+ op.set("visibility", "public")
288
+
289
+ for arg_name in props.get("args", []):
290
+ param = ET.SubElement(op, "ownedParameter")
291
+ param.set("xmi:id", f"param-{uuid.uuid4()}")
292
+ param.set("name", arg_name)
293
+ param.set("direction", "in")
294
+
295
+ docstring = props.get("docstring", "")
296
+ if docstring:
297
+ comment = ET.SubElement(pe, "ownedComment")
298
+ comment.set("xmi:id", f"cmt-{uuid.uuid4()}")
299
+ body_el = ET.SubElement(comment, "body")
300
+ body_el.text = docstring
301
+
302
+ elif etype == "interface":
303
+ pe = ET.SubElement(pkg, "packagedElement")
304
+ pe.set("xmi:type", "uml:Interface")
305
+ pe.set("xmi:id", xmi_id)
306
+ pe.set("name", name)
307
+
308
+ for method in props.get("methods", []):
309
+ op = ET.SubElement(pe, "ownedOperation")
310
+ op.set("xmi:type", "uml:Operation")
311
+ op.set("xmi:id", f"op-{uuid.uuid4()}")
312
+ op.set("name", method.get("name", ""))
313
+
314
+ ET.indent(ET.ElementTree(root), space=" ")
315
+ return ET.tostring(root, encoding="unicode", xml_declaration=True)
316
+
317
+
318
+ # ---------------------------------------------------------------------------
319
+ # Drift detection
320
+ # ---------------------------------------------------------------------------
321
+
322
+ def detect_drift(project_id: str, db_path: Optional[Path] = None) -> dict:
323
+ """Compare current model_code_mappings hashes with actual file hashes.
324
+
325
+ For each mapping:
326
+ 1. Recompute SHA-256 of the code file (if it exists)
327
+ 2. Compare with stored code_hash
328
+ 3. Check if model's source_hash has changed (re-read sysml_elements.source_hash)
329
+ 4. Determine status: synced, model_ahead, code_ahead, conflict, unknown
330
+
331
+ Updates model_code_mappings.sync_status in place.
332
+
333
+ Returns::
334
+
335
+ {
336
+ "total_mappings": int,
337
+ "synced": int,
338
+ "model_ahead": int,
339
+ "code_ahead": int,
340
+ "conflict": int,
341
+ "unknown": int,
342
+ "missing_files": int,
343
+ "details": [...]
344
+ }
345
+ """
346
+ conn = get_connection(db_path=db_path)
347
+ cursor = conn.cursor()
348
+
349
+ cursor.execute(
350
+ """SELECT mcm.id, mcm.sysml_element_id, mcm.code_path, mcm.code_type,
351
+ mcm.model_hash, mcm.code_hash, mcm.sync_status,
352
+ se.source_hash AS current_model_hash, se.name AS element_name
353
+ FROM model_code_mappings mcm
354
+ LEFT JOIN sysml_elements se ON mcm.sysml_element_id = se.id
355
+ WHERE mcm.project_id = ?""",
356
+ (project_id,),
357
+ )
358
+ rows = [dict(r) for r in cursor.fetchall()]
359
+
360
+ counts = {
361
+ "total_mappings": len(rows),
362
+ "synced": 0,
363
+ "model_ahead": 0,
364
+ "code_ahead": 0,
365
+ "conflict": 0,
366
+ "unknown": 0,
367
+ "missing_files": 0,
368
+ }
369
+ details: List[Dict[str, Any]] = []
370
+
371
+ for row in rows:
372
+ mapping_id = row["id"]
373
+ code_path = row["code_path"]
374
+ stored_code_hash = row["code_hash"] or ""
375
+ stored_model_hash = row["model_hash"] or ""
376
+ current_model_hash = row["current_model_hash"] or ""
377
+ element_name = row["element_name"] or ""
378
+
379
+ # Recompute code file hash
380
+ current_code_hash = _compute_file_hash(code_path)
381
+ file_exists = current_code_hash != ""
382
+
383
+ if not file_exists:
384
+ new_status = "unknown"
385
+ counts["missing_files"] += 1
386
+ counts["unknown"] += 1
387
+ else:
388
+ code_changed = current_code_hash != stored_code_hash
389
+ model_changed = current_model_hash != stored_model_hash
390
+
391
+ if code_changed and model_changed:
392
+ new_status = "conflict"
393
+ counts["conflict"] += 1
394
+ elif model_changed and not code_changed:
395
+ new_status = "model_ahead"
396
+ counts["model_ahead"] += 1
397
+ elif code_changed and not model_changed:
398
+ new_status = "code_ahead"
399
+ counts["code_ahead"] += 1
400
+ else:
401
+ new_status = "synced"
402
+ counts["synced"] += 1
403
+
404
+ # Update sync_status in DB
405
+ cursor.execute(
406
+ """UPDATE model_code_mappings
407
+ SET sync_status = ?, last_synced = ?
408
+ WHERE id = ?""",
409
+ (new_status, _ts(), mapping_id),
410
+ )
411
+
412
+ details.append({
413
+ "mapping_id": mapping_id,
414
+ "element_name": element_name,
415
+ "code_path": code_path,
416
+ "code_type": row["code_type"],
417
+ "previous_status": row["sync_status"],
418
+ "new_status": new_status,
419
+ "file_exists": file_exists,
420
+ "code_changed": current_code_hash != stored_code_hash if file_exists else None,
421
+ "model_changed": current_model_hash != stored_model_hash,
422
+ })
423
+
424
+ conn.commit()
425
+ conn.close()
426
+
427
+ counts["details"] = details
428
+ return counts
429
+
430
+
431
+ # ---------------------------------------------------------------------------
432
+ # Sync model -> code
433
+ # ---------------------------------------------------------------------------
434
+
435
+ def sync_model_to_code(project_id: str, language: str = "python",
436
+ db_path: Optional[Path] = None) -> dict:
437
+ """Sync model changes to code.
438
+
439
+ Steps:
440
+ 1. Re-import latest XMI if a new file is available in model_imports
441
+ 2. For each model_ahead mapping: regenerate code for that element
442
+ 3. For new elements (in model but no mapping): generate new code files
443
+ 4. For deleted elements (mapping exists but element gone): mark as orphaned
444
+ 5. Update model_code_mappings hashes and status
445
+ 6. Log audit trail
446
+
447
+ Returns::
448
+
449
+ {
450
+ "files_updated": int,
451
+ "files_created": int,
452
+ "files_orphaned": int,
453
+ "errors": int,
454
+ "error_details": [...]
455
+ }
456
+ """
457
+ conn = get_connection(db_path=db_path)
458
+ cursor = conn.cursor()
459
+ errors: List[str] = []
460
+ files_updated = 0
461
+ files_created = 0
462
+ files_orphaned = 0
463
+
464
+ # Step 1: Check for latest XMI import and re-import if newer file exists
465
+ # (Delegated to reimport_xmi if caller has a new file; here we just check
466
+ # the most recent import hash to detect if anything changed.)
467
+
468
+ # Step 2: For each model_ahead mapping, regenerate code
469
+ cursor.execute(
470
+ """SELECT mcm.id, mcm.sysml_element_id, mcm.code_path, mcm.code_type,
471
+ se.name, se.element_type, se.properties, se.description,
472
+ se.source_hash, se.stereotype
473
+ FROM model_code_mappings mcm
474
+ JOIN sysml_elements se ON mcm.sysml_element_id = se.id
475
+ WHERE mcm.project_id = ? AND mcm.sync_status = 'model_ahead'""",
476
+ (project_id,),
477
+ )
478
+ model_ahead_rows = [dict(r) for r in cursor.fetchall()]
479
+
480
+ for row in model_ahead_rows:
481
+ try:
482
+ code_content = _generate_code_from_element(
483
+ name=row["name"],
484
+ element_type=row["element_type"],
485
+ properties=row["properties"],
486
+ description=row["description"] or "",
487
+ stereotype=row["stereotype"] or "",
488
+ language=language,
489
+ )
490
+ code_path = Path(row["code_path"])
491
+ code_path.parent.mkdir(parents=True, exist_ok=True)
492
+ code_path.write_text(code_content, encoding="utf-8")
493
+
494
+ new_code_hash = _compute_file_hash(str(code_path))
495
+ cursor.execute(
496
+ """UPDATE model_code_mappings
497
+ SET sync_status = 'synced', code_hash = ?, model_hash = ?,
498
+ last_synced = ?
499
+ WHERE id = ?""",
500
+ (new_code_hash, row["source_hash"], _ts(), row["id"]),
501
+ )
502
+ files_updated += 1
503
+ except Exception as exc:
504
+ errors.append(f"Failed to update {row['code_path']}: {exc}")
505
+
506
+ # Step 3: New elements with no mapping — generate new code files
507
+ cursor.execute(
508
+ """SELECT se.id, se.name, se.element_type, se.properties,
509
+ se.description, se.source_hash, se.stereotype
510
+ FROM sysml_elements se
511
+ WHERE se.project_id = ?
512
+ AND se.id NOT IN (
513
+ SELECT sysml_element_id FROM model_code_mappings
514
+ WHERE project_id = ?
515
+ )
516
+ AND se.element_type IN ('block', 'interface_block', 'activity')""",
517
+ (project_id, project_id),
518
+ )
519
+ new_elements = [dict(r) for r in cursor.fetchall()]
520
+
521
+ for elem in new_elements:
522
+ try:
523
+ safe_name = elem["name"].lower().replace(" ", "_").replace("-", "_")
524
+ if language == "python":
525
+ code_path = BASE_DIR / "output" / project_id / f"{safe_name}.py"
526
+ else:
527
+ code_path = BASE_DIR / "output" / project_id / f"{safe_name}.{language}"
528
+
529
+ code_content = _generate_code_from_element(
530
+ name=elem["name"],
531
+ element_type=elem["element_type"],
532
+ properties=elem["properties"],
533
+ description=elem["description"] or "",
534
+ stereotype=elem["stereotype"] or "",
535
+ language=language,
536
+ )
537
+ code_path.parent.mkdir(parents=True, exist_ok=True)
538
+ code_path.write_text(code_content, encoding="utf-8")
539
+
540
+ new_code_hash = _compute_file_hash(str(code_path))
541
+ cursor.execute(
542
+ """INSERT INTO model_code_mappings
543
+ (project_id, sysml_element_id, code_path, code_type,
544
+ mapping_direction, sync_status, model_hash, code_hash,
545
+ last_synced)
546
+ VALUES (?, ?, ?, ?, 'model_to_code', 'synced', ?, ?, ?)""",
547
+ (
548
+ project_id,
549
+ elem["id"],
550
+ str(code_path),
551
+ "class" if elem["element_type"] in ("block", "interface_block") else "module",
552
+ elem["source_hash"],
553
+ new_code_hash,
554
+ _ts(),
555
+ ),
556
+ )
557
+ files_created += 1
558
+ except Exception as exc:
559
+ errors.append(f"Failed to create code for '{elem['name']}': {exc}")
560
+
561
+ # Step 4: Orphaned mappings — element gone from sysml_elements
562
+ cursor.execute(
563
+ """SELECT mcm.id, mcm.code_path
564
+ FROM model_code_mappings mcm
565
+ WHERE mcm.project_id = ?
566
+ AND mcm.sysml_element_id NOT IN (
567
+ SELECT id FROM sysml_elements WHERE project_id = ?
568
+ )
569
+ AND mcm.sync_status != 'unknown'""",
570
+ (project_id, project_id),
571
+ )
572
+ orphaned_rows = [dict(r) for r in cursor.fetchall()]
573
+
574
+ for row in orphaned_rows:
575
+ cursor.execute(
576
+ """UPDATE model_code_mappings
577
+ SET sync_status = 'unknown', last_synced = ?
578
+ WHERE id = ?""",
579
+ (_ts(), row["id"]),
580
+ )
581
+ files_orphaned += 1
582
+
583
+ conn.commit()
584
+ conn.close()
585
+
586
+ # Step 6: Audit trail
587
+ if _HAS_AUDIT:
588
+ try:
589
+ log_event(
590
+ event_type="code_generated",
591
+ actor="icdev-sync-engine",
592
+ action=(
593
+ f"Model-to-code sync for project {project_id}: "
594
+ f"{files_updated} updated, {files_created} created, "
595
+ f"{files_orphaned} orphaned"
596
+ ),
597
+ project_id=project_id,
598
+ details={
599
+ "files_updated": files_updated,
600
+ "files_created": files_created,
601
+ "files_orphaned": files_orphaned,
602
+ "errors": len(errors),
603
+ "language": language,
604
+ },
605
+ classification="CUI",
606
+ db_path=Path(db_path) if db_path else None,
607
+ )
608
+ except Exception:
609
+ pass
610
+
611
+ return {
612
+ "files_updated": files_updated,
613
+ "files_created": files_created,
614
+ "files_orphaned": files_orphaned,
615
+ "errors": len(errors),
616
+ "error_details": errors,
617
+ }
618
+
619
+
620
+ def _generate_code_from_element(name: str, element_type: str, properties: str,
621
+ description: str, stereotype: str,
622
+ language: str) -> str:
623
+ """Generate source code from a SysML element definition.
624
+
625
+ Currently supports Python only. Produces a module with CUI markings,
626
+ a class stub with attributes and method stubs extracted from the element's
627
+ properties JSON.
628
+ """
629
+ props = {}
630
+ if properties:
631
+ try:
632
+ props = json.loads(properties) if isinstance(properties, str) else properties
633
+ except (json.JSONDecodeError, TypeError):
634
+ props = {}
635
+
636
+ if language != "python":
637
+ # Fallback: produce a commented stub
638
+ lines = [
639
+ "// CUI // SP-CTI",
640
+ f"// Auto-generated from SysML element: {name}",
641
+ f"// Element type: {element_type}",
642
+ f"// Stereotype: {stereotype}",
643
+ f"// Description: {description}",
644
+ "// CUI // SP-CTI",
645
+ ]
646
+ return "\n".join(lines)
647
+
648
+ lines = [
649
+ "# CUI // SP-CTI",
650
+ f'"""Auto-generated from SysML {element_type}: {name}.',
651
+ "",
652
+ ]
653
+ if description:
654
+ lines.append(f"{description}")
655
+ lines.append("")
656
+ lines.append(f'Stereotype: {stereotype or "N/A"}')
657
+ lines.append('"""')
658
+ lines.append("")
659
+
660
+ # Class name: PascalCase from the element name
661
+ class_name = "".join(word.capitalize() for word in name.replace("-", " ").replace("_", " ").split())
662
+
663
+ if element_type in ("block", "interface_block"):
664
+ # Extract attributes from properties
665
+ attributes = props.get("attributes", [])
666
+ ports = props.get("ports", [])
667
+ flow_props = props.get("flow_properties", [])
668
+
669
+ lines.append(f"class {class_name}:")
670
+ lines.append(f' """{description or name}"""')
671
+ lines.append("")
672
+
673
+ # __init__ with attributes
674
+ init_attrs = attributes + flow_props
675
+ if init_attrs:
676
+ init_args = ", ".join(
677
+ a.get("name", "unnamed") for a in init_attrs
678
+ if a.get("name")
679
+ )
680
+ lines.append(f" def __init__(self, {init_args}):")
681
+ for attr in init_attrs:
682
+ attr_name = attr.get("name", "")
683
+ if attr_name:
684
+ lines.append(f" self.{attr_name} = {attr_name}")
685
+ lines.append("")
686
+ else:
687
+ lines.append(" def __init__(self):")
688
+ lines.append(" pass")
689
+ lines.append("")
690
+
691
+ # Port properties as methods
692
+ for port in ports:
693
+ port_name = port.get("name", "port")
694
+ lines.append(f" def get_{port_name}(self):")
695
+ lines.append(f' """Access port: {port_name}."""')
696
+ lines.append(" raise NotImplementedError")
697
+ lines.append("")
698
+
699
+ elif element_type == "activity":
700
+ # Activity -> module with functions for each action
701
+ actions = props.get("actions", [])
702
+ if actions:
703
+ for action in actions:
704
+ action_name = action.get("name", "").lower().replace(" ", "_").replace("-", "_")
705
+ if not action_name:
706
+ continue
707
+ lines.append(f"def {action_name}():")
708
+ lines.append(f' """{action.get("name", "")} action."""')
709
+ lines.append(" raise NotImplementedError")
710
+ lines.append("")
711
+ else:
712
+ lines.append(f"def execute_{class_name.lower()}():")
713
+ lines.append(f' """{description or name}"""')
714
+ lines.append(" raise NotImplementedError")
715
+ lines.append("")
716
+
717
+ else:
718
+ # Generic stub
719
+ lines.append(f"class {class_name}:")
720
+ lines.append(f' """{description or name}"""')
721
+ lines.append("")
722
+ lines.append(" def __init__(self):")
723
+ lines.append(" pass")
724
+ lines.append("")
725
+
726
+ lines.append("# CUI // SP-CTI")
727
+ return "\n".join(lines)
728
+
729
+
730
+ # ---------------------------------------------------------------------------
731
+ # Sync code -> model
732
+ # ---------------------------------------------------------------------------
733
+
734
+ def sync_code_to_model(project_id: str, output_path: str,
735
+ db_path: Optional[Path] = None) -> dict:
736
+ """Reverse sync: analyze code and generate XMI fragment for Cameo import.
737
+
738
+ Steps:
739
+ 1. For each code_ahead mapping: parse Python AST to extract class/function info
740
+ 2. For new code files (not in any mapping): detect classes/functions
741
+ 3. Generate XMI fragment with new/modified elements
742
+ 4. Output as .xmi file for manual import into Cameo
743
+ 5. Log audit trail
744
+
745
+ Returns::
746
+
747
+ {
748
+ "xmi_file": str,
749
+ "elements_exported": int,
750
+ "new_elements": int,
751
+ "modified_elements": int,
752
+ "errors": [...]
753
+ }
754
+ """
755
+ conn = get_connection(db_path=db_path)
756
+ cursor = conn.cursor()
757
+ errors: List[str] = []
758
+ elements_for_xmi: List[Dict[str, Any]] = []
759
+ modified_count = 0
760
+ new_count = 0
761
+
762
+ # Step 1: Process code_ahead mappings
763
+ cursor.execute(
764
+ """SELECT mcm.id, mcm.sysml_element_id, mcm.code_path, mcm.code_type,
765
+ se.name, se.xmi_id
766
+ FROM model_code_mappings mcm
767
+ LEFT JOIN sysml_elements se ON mcm.sysml_element_id = se.id
768
+ WHERE mcm.project_id = ? AND mcm.sync_status = 'code_ahead'""",
769
+ (project_id,),
770
+ )
771
+ code_ahead_rows = [dict(r) for r in cursor.fetchall()]
772
+
773
+ for row in code_ahead_rows:
774
+ code_path = row["code_path"]
775
+ try:
776
+ parsed = _parse_python_ast(code_path)
777
+
778
+ for cls in parsed["classes"]:
779
+ elements_for_xmi.append({
780
+ "name": cls["name"],
781
+ "element_type": "class",
782
+ "xmi_id": row.get("xmi_id") or f"elem-{uuid.uuid4()}",
783
+ "properties": {
784
+ "methods": cls["methods"],
785
+ "attributes": cls["attributes"],
786
+ "bases": cls["bases"],
787
+ },
788
+ })
789
+ modified_count += 1
790
+
791
+ for func in parsed["functions"]:
792
+ elements_for_xmi.append({
793
+ "name": func["name"],
794
+ "element_type": "function",
795
+ "xmi_id": f"func-{uuid.uuid4()}",
796
+ "properties": {
797
+ "args": func["args"],
798
+ "docstring": func["docstring"],
799
+ },
800
+ })
801
+ modified_count += 1
802
+
803
+ # Update mapping: store the current code hash
804
+ new_hash = _compute_file_hash(code_path)
805
+ cursor.execute(
806
+ """UPDATE model_code_mappings
807
+ SET code_hash = ?, last_synced = ?
808
+ WHERE id = ?""",
809
+ (new_hash, _ts(), row["id"]),
810
+ )
811
+ except Exception as exc:
812
+ errors.append(f"Failed to parse {code_path}: {exc}")
813
+
814
+ # Step 2: Find unmapped code files in the project output directory
815
+ project_output_dir = BASE_DIR / "output" / project_id
816
+ if project_output_dir.exists():
817
+ cursor.execute(
818
+ "SELECT code_path FROM model_code_mappings WHERE project_id = ?",
819
+ (project_id,),
820
+ )
821
+ mapped_paths = {r["code_path"] for r in cursor.fetchall()}
822
+
823
+ for py_file in project_output_dir.rglob("*.py"):
824
+ if str(py_file) in mapped_paths:
825
+ continue
826
+ try:
827
+ parsed = _parse_python_ast(str(py_file))
828
+ for cls in parsed["classes"]:
829
+ elements_for_xmi.append({
830
+ "name": cls["name"],
831
+ "element_type": "class",
832
+ "xmi_id": f"new-{uuid.uuid4()}",
833
+ "properties": {
834
+ "methods": cls["methods"],
835
+ "attributes": cls["attributes"],
836
+ "bases": cls["bases"],
837
+ },
838
+ })
839
+ new_count += 1
840
+
841
+ for func in parsed["functions"]:
842
+ elements_for_xmi.append({
843
+ "name": func["name"],
844
+ "element_type": "function",
845
+ "xmi_id": f"new-{uuid.uuid4()}",
846
+ "properties": {
847
+ "args": func["args"],
848
+ "docstring": func["docstring"],
849
+ },
850
+ })
851
+ new_count += 1
852
+ except Exception as exc:
853
+ errors.append(f"Failed to scan {py_file}: {exc}")
854
+
855
+ conn.commit()
856
+ conn.close()
857
+
858
+ # Step 3-4: Generate XMI fragment and write to file
859
+ xmi_content = _generate_xmi_fragment(elements_for_xmi)
860
+
861
+ out_path = Path(output_path)
862
+ out_path.parent.mkdir(parents=True, exist_ok=True)
863
+ out_path.write_text(xmi_content, encoding="utf-8")
864
+
865
+ # Step 5: Audit trail
866
+ if _HAS_AUDIT:
867
+ try:
868
+ log_event(
869
+ event_type="code_generated",
870
+ actor="icdev-sync-engine",
871
+ action=(
872
+ f"Code-to-model sync for project {project_id}: "
873
+ f"exported {len(elements_for_xmi)} elements to {output_path}"
874
+ ),
875
+ project_id=project_id,
876
+ details={
877
+ "xmi_file": str(out_path),
878
+ "elements_exported": len(elements_for_xmi),
879
+ "modified_elements": modified_count,
880
+ "new_elements": new_count,
881
+ },
882
+ affected_files=[str(out_path)],
883
+ classification="CUI",
884
+ db_path=Path(db_path) if db_path else None,
885
+ )
886
+ except Exception:
887
+ pass
888
+
889
+ return {
890
+ "xmi_file": str(out_path),
891
+ "elements_exported": len(elements_for_xmi),
892
+ "new_elements": new_count,
893
+ "modified_elements": modified_count,
894
+ "errors": errors,
895
+ }
896
+
897
+
898
+ # ---------------------------------------------------------------------------
899
+ # Conflict resolution
900
+ # ---------------------------------------------------------------------------
901
+
902
+ def resolve_conflict(project_id: str, mapping_id: int, resolution: str,
903
+ db_path: Optional[Path] = None) -> dict:
904
+ """Resolve a model/code conflict for a specific mapping.
905
+
906
+ Args:
907
+ resolution: One of 'keep_model', 'keep_code', or 'merge'.
908
+ - keep_model: Regenerate code from model, update code_hash.
909
+ - keep_code: Update model_hash to current value (model stale until
910
+ re-imported). Does NOT modify the model file.
911
+ - merge: Mark as bidirectional; leave both sides as-is for
912
+ manual merge.
913
+
914
+ Returns::
915
+
916
+ {"mapping_id": int, "resolution": str, "status": str}
917
+ """
918
+ conn = get_connection(db_path=db_path)
919
+ cursor = conn.cursor()
920
+
921
+ cursor.execute(
922
+ """SELECT mcm.*, se.name, se.element_type, se.properties,
923
+ se.description, se.source_hash, se.stereotype
924
+ FROM model_code_mappings mcm
925
+ LEFT JOIN sysml_elements se ON mcm.sysml_element_id = se.id
926
+ WHERE mcm.id = ? AND mcm.project_id = ?""",
927
+ (mapping_id, project_id),
928
+ )
929
+ row = cursor.fetchone()
930
+
931
+ if not row:
932
+ conn.close()
933
+ return {
934
+ "mapping_id": mapping_id,
935
+ "resolution": resolution,
936
+ "status": "error",
937
+ "error": f"Mapping #{mapping_id} not found for project {project_id}",
938
+ }
939
+
940
+ row = dict(row)
941
+ status = "resolved"
942
+
943
+ try:
944
+ if resolution == "keep_model":
945
+ # Regenerate code from model
946
+ code_content = _generate_code_from_element(
947
+ name=row["name"] or "",
948
+ element_type=row["element_type"] or "block",
949
+ properties=row["properties"] or "{}",
950
+ description=row["description"] or "",
951
+ stereotype=row["stereotype"] or "",
952
+ language="python",
953
+ )
954
+ code_path = Path(row["code_path"])
955
+ code_path.parent.mkdir(parents=True, exist_ok=True)
956
+ code_path.write_text(code_content, encoding="utf-8")
957
+
958
+ new_code_hash = _compute_file_hash(str(code_path))
959
+ cursor.execute(
960
+ """UPDATE model_code_mappings
961
+ SET sync_status = 'synced', code_hash = ?,
962
+ model_hash = ?, mapping_direction = 'model_to_code',
963
+ last_synced = ?
964
+ WHERE id = ?""",
965
+ (new_code_hash, row["source_hash"], _ts(), mapping_id),
966
+ )
967
+
968
+ elif resolution == "keep_code":
969
+ # Update model_hash to match current source_hash so it looks synced
970
+ # The model side remains stale until manually re-imported
971
+ current_code_hash = _compute_file_hash(row["code_path"])
972
+ cursor.execute(
973
+ """UPDATE model_code_mappings
974
+ SET sync_status = 'synced', code_hash = ?,
975
+ model_hash = ?, mapping_direction = 'code_to_model',
976
+ last_synced = ?
977
+ WHERE id = ?""",
978
+ (current_code_hash, row["source_hash"], _ts(), mapping_id),
979
+ )
980
+
981
+ elif resolution == "merge":
982
+ cursor.execute(
983
+ """UPDATE model_code_mappings
984
+ SET sync_status = 'synced', mapping_direction = 'bidirectional',
985
+ last_synced = ?
986
+ WHERE id = ?""",
987
+ (_ts(), mapping_id),
988
+ )
989
+
990
+ else:
991
+ status = "error"
992
+
993
+ except Exception as exc:
994
+ status = "error"
995
+ conn.close()
996
+ return {
997
+ "mapping_id": mapping_id,
998
+ "resolution": resolution,
999
+ "status": status,
1000
+ "error": str(exc),
1001
+ }
1002
+
1003
+ conn.commit()
1004
+ conn.close()
1005
+
1006
+ # Audit trail
1007
+ if _HAS_AUDIT:
1008
+ try:
1009
+ log_event(
1010
+ event_type="decision_made",
1011
+ actor="icdev-sync-engine",
1012
+ action=(
1013
+ f"Conflict resolved for mapping #{mapping_id} in {project_id}: "
1014
+ f"{resolution}"
1015
+ ),
1016
+ project_id=project_id,
1017
+ details={
1018
+ "mapping_id": mapping_id,
1019
+ "resolution": resolution,
1020
+ "code_path": row["code_path"],
1021
+ "element_name": row.get("name", ""),
1022
+ },
1023
+ classification="CUI",
1024
+ db_path=Path(db_path) if db_path else None,
1025
+ )
1026
+ except Exception:
1027
+ pass
1028
+
1029
+ return {
1030
+ "mapping_id": mapping_id,
1031
+ "resolution": resolution,
1032
+ "status": status,
1033
+ }
1034
+
1035
+
1036
+ # ---------------------------------------------------------------------------
1037
+ # Re-import XMI
1038
+ # ---------------------------------------------------------------------------
1039
+
1040
+ def reimport_xmi(project_id: str, file_path: str,
1041
+ db_path: Optional[Path] = None) -> dict:
1042
+ """Re-import XMI after Cameo updates, merging with existing elements.
1043
+
1044
+ Steps:
1045
+ 1. Parse new XMI file
1046
+ 2. Compare with existing sysml_elements by xmi_id
1047
+ 3. Update changed elements, add new ones, mark deleted ones
1048
+ 4. Update model_code_mappings for affected elements
1049
+ 5. Log audit trail
1050
+
1051
+ Returns::
1052
+
1053
+ {"updated": int, "added": int, "deleted": int, "unchanged": int}
1054
+ """
1055
+ # Lazy import xmi_parser to avoid circular dependencies
1056
+ try:
1057
+ from tools.mbse.xmi_parser import parse_xmi, _file_hash # type: ignore
1058
+ except ImportError:
1059
+ # Fallback: use local file hash
1060
+ parse_xmi = None
1061
+ _file_hash = _compute_file_hash
1062
+
1063
+ if parse_xmi is None:
1064
+ return {
1065
+ "updated": 0, "added": 0, "deleted": 0, "unchanged": 0,
1066
+ "error": "xmi_parser not available. Ensure tools/mbse/xmi_parser.py exists.",
1067
+ }
1068
+
1069
+ # Step 1: Parse new XMI
1070
+ try:
1071
+ parsed = parse_xmi(file_path)
1072
+ except Exception as exc:
1073
+ return {
1074
+ "updated": 0, "added": 0, "deleted": 0, "unchanged": 0,
1075
+ "error": f"XMI parse error: {exc}",
1076
+ }
1077
+
1078
+ new_elements = parsed["elements"]
1079
+ new_source_hash = parsed["metadata"]["file_hash"]
1080
+ timestamp = _ts()
1081
+
1082
+ conn = get_connection(db_path=db_path)
1083
+ cursor = conn.cursor()
1084
+
1085
+ # Step 2: Load existing elements by xmi_id
1086
+ cursor.execute(
1087
+ "SELECT id, xmi_id, source_hash FROM sysml_elements WHERE project_id = ?",
1088
+ (project_id,),
1089
+ )
1090
+ existing = {r["xmi_id"]: dict(r) for r in cursor.fetchall()}
1091
+
1092
+ updated = 0
1093
+ added = 0
1094
+ deleted = 0
1095
+ unchanged = 0
1096
+
1097
+ new_xmi_ids = set()
1098
+
1099
+ # Step 3: Process parsed elements
1100
+ for elem in new_elements:
1101
+ xmi_id = elem.get("xmi_id", "")
1102
+ new_xmi_ids.add(xmi_id)
1103
+
1104
+ if xmi_id in existing:
1105
+ # Compare source_hash to detect changes
1106
+ old_hash = existing[xmi_id].get("source_hash", "")
1107
+ if old_hash != new_source_hash:
1108
+ # Element changed — update it
1109
+ cursor.execute(
1110
+ """UPDATE sysml_elements
1111
+ SET name = ?, element_type = ?, qualified_name = ?,
1112
+ stereotype = ?, description = ?, properties = ?,
1113
+ diagram_type = ?, source_file = ?,
1114
+ source_hash = ?, updated_at = ?
1115
+ WHERE project_id = ? AND xmi_id = ?""",
1116
+ (
1117
+ elem["name"],
1118
+ elem["element_type"],
1119
+ elem.get("qualified_name", ""),
1120
+ elem.get("stereotype", ""),
1121
+ elem.get("description", ""),
1122
+ elem.get("properties", "{}"),
1123
+ elem.get("diagram_type"),
1124
+ elem.get("source_file", ""),
1125
+ new_source_hash,
1126
+ timestamp,
1127
+ project_id,
1128
+ xmi_id,
1129
+ ),
1130
+ )
1131
+ # Mark associated model_code_mappings as model_ahead
1132
+ elem_db_id = existing[xmi_id]["id"]
1133
+ cursor.execute(
1134
+ """UPDATE model_code_mappings
1135
+ SET sync_status = 'model_ahead', model_hash = ?
1136
+ WHERE project_id = ? AND sysml_element_id = ?""",
1137
+ (new_source_hash, project_id, elem_db_id),
1138
+ )
1139
+ updated += 1
1140
+ else:
1141
+ unchanged += 1
1142
+ else:
1143
+ # New element — insert
1144
+ elem_id = elem.get("id", _new_id())
1145
+ try:
1146
+ cursor.execute(
1147
+ """INSERT INTO sysml_elements
1148
+ (id, project_id, xmi_id, element_type, name,
1149
+ qualified_name, parent_id, stereotype, description,
1150
+ properties, diagram_type, source_file, source_hash,
1151
+ imported_at, updated_at)
1152
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
1153
+ (
1154
+ elem_id,
1155
+ project_id,
1156
+ xmi_id,
1157
+ elem["element_type"],
1158
+ elem["name"],
1159
+ elem.get("qualified_name", ""),
1160
+ elem.get("parent_id"),
1161
+ elem.get("stereotype", ""),
1162
+ elem.get("description", ""),
1163
+ elem.get("properties", "{}"),
1164
+ elem.get("diagram_type"),
1165
+ elem.get("source_file", ""),
1166
+ new_source_hash,
1167
+ timestamp,
1168
+ timestamp,
1169
+ ),
1170
+ )
1171
+ added += 1
1172
+ except sqlite3.IntegrityError:
1173
+ # Duplicate — treat as update
1174
+ unchanged += 1
1175
+
1176
+ # Step 3 (cont.): Mark elements missing from new XMI as deleted
1177
+ for xmi_id, existing_elem in existing.items():
1178
+ if xmi_id not in new_xmi_ids:
1179
+ # Mark as deleted by updating a description note (we do NOT delete)
1180
+ cursor.execute(
1181
+ """UPDATE sysml_elements
1182
+ SET description = description || ' [DELETED in reimport ' || ? || ']',
1183
+ updated_at = ?
1184
+ WHERE id = ?""",
1185
+ (timestamp, timestamp, existing_elem["id"]),
1186
+ )
1187
+ # Mark associated mappings as unknown
1188
+ cursor.execute(
1189
+ """UPDATE model_code_mappings
1190
+ SET sync_status = 'unknown'
1191
+ WHERE project_id = ? AND sysml_element_id = ?""",
1192
+ (project_id, existing_elem["id"]),
1193
+ )
1194
+ deleted += 1
1195
+
1196
+ # Step 4: Record in model_imports
1197
+ cursor.execute(
1198
+ """INSERT INTO model_imports
1199
+ (project_id, import_type, source_file, source_hash,
1200
+ elements_imported, relationships_imported, errors,
1201
+ error_details, status, imported_by, imported_at)
1202
+ VALUES (?, 'xmi_reimport', ?, ?, ?, 0, 0, NULL, 'completed',
1203
+ 'icdev-sync-engine', ?)""",
1204
+ (
1205
+ project_id,
1206
+ str(Path(file_path).name),
1207
+ new_source_hash,
1208
+ updated + added,
1209
+ timestamp,
1210
+ ),
1211
+ )
1212
+
1213
+ conn.commit()
1214
+ conn.close()
1215
+
1216
+ # Step 5: Audit trail
1217
+ if _HAS_AUDIT:
1218
+ try:
1219
+ log_event(
1220
+ event_type="compliance_check",
1221
+ actor="icdev-sync-engine",
1222
+ action=(
1223
+ f"XMI reimport for {project_id}: "
1224
+ f"{updated} updated, {added} added, {deleted} deleted, "
1225
+ f"{unchanged} unchanged"
1226
+ ),
1227
+ project_id=project_id,
1228
+ details={
1229
+ "file": file_path,
1230
+ "source_hash": new_source_hash,
1231
+ "updated": updated,
1232
+ "added": added,
1233
+ "deleted": deleted,
1234
+ "unchanged": unchanged,
1235
+ },
1236
+ affected_files=[file_path],
1237
+ classification="CUI",
1238
+ db_path=Path(db_path) if db_path else None,
1239
+ )
1240
+ except Exception:
1241
+ pass
1242
+
1243
+ return {
1244
+ "updated": updated,
1245
+ "added": added,
1246
+ "deleted": deleted,
1247
+ "unchanged": unchanged,
1248
+ }
1249
+
1250
+
1251
+ # ---------------------------------------------------------------------------
1252
+ # Re-import ReqIF
1253
+ # ---------------------------------------------------------------------------
1254
+
1255
+ def reimport_reqif(project_id: str, file_path: str,
1256
+ db_path: Optional[Path] = None) -> dict:
1257
+ """Re-import ReqIF after DOORS updates, merging with existing requirements.
1258
+
1259
+ Similar to reimport_xmi but operates on the doors_requirements table.
1260
+
1261
+ Steps:
1262
+ 1. Parse new ReqIF file
1263
+ 2. Compare with existing doors_requirements by doors_id
1264
+ 3. Update changed requirements, add new ones, mark deleted ones
1265
+ 4. Log audit trail
1266
+
1267
+ Returns::
1268
+
1269
+ {"updated": int, "added": int, "deleted": int, "unchanged": int}
1270
+ """
1271
+ try:
1272
+ from tools.mbse.reqif_parser import parse_reqif # type: ignore
1273
+ except ImportError:
1274
+ parse_reqif = None
1275
+
1276
+ if parse_reqif is None:
1277
+ return {
1278
+ "updated": 0, "added": 0, "deleted": 0, "unchanged": 0,
1279
+ "error": "reqif_parser not available. Ensure tools/mbse/reqif_parser.py exists.",
1280
+ }
1281
+
1282
+ # Step 1: Parse new ReqIF
1283
+ try:
1284
+ parsed = parse_reqif(file_path)
1285
+ except Exception as exc:
1286
+ return {
1287
+ "updated": 0, "added": 0, "deleted": 0, "unchanged": 0,
1288
+ "error": f"ReqIF parse error: {exc}",
1289
+ }
1290
+
1291
+ new_reqs = parsed["requirements"]
1292
+ source_hash = _compute_file_hash(file_path)
1293
+ timestamp = _ts()
1294
+
1295
+ conn = get_connection(db_path=db_path)
1296
+ cursor = conn.cursor()
1297
+
1298
+ # Step 2: Load existing requirements by doors_id
1299
+ cursor.execute(
1300
+ "SELECT id, doors_id, title, description, priority, requirement_type "
1301
+ "FROM doors_requirements WHERE project_id = ?",
1302
+ (project_id,),
1303
+ )
1304
+ existing = {}
1305
+ for r in cursor.fetchall():
1306
+ row_dict = dict(r)
1307
+ existing[row_dict["doors_id"]] = row_dict
1308
+
1309
+ updated = 0
1310
+ added = 0
1311
+ deleted = 0
1312
+ unchanged = 0
1313
+ new_doors_ids = set()
1314
+
1315
+ # Step 3: Process parsed requirements
1316
+ for req in new_reqs:
1317
+ doors_id = req.get("doors_id", "")
1318
+ if not doors_id:
1319
+ continue
1320
+ new_doors_ids.add(doors_id)
1321
+
1322
+ # Build content fingerprint for change detection
1323
+ new_content = (
1324
+ f"{req.get('title', '')}|{req.get('description', '')}|"
1325
+ f"{req.get('priority', '')}|{req.get('requirement_type', '')}"
1326
+ )
1327
+ new_hash = _content_hash(new_content)
1328
+
1329
+ if doors_id in existing:
1330
+ ex = existing[doors_id]
1331
+ old_content = (
1332
+ f"{ex.get('title', '')}|{ex.get('description', '')}|"
1333
+ f"{ex.get('priority', '')}|{ex.get('requirement_type', '')}"
1334
+ )
1335
+ old_hash = _content_hash(old_content)
1336
+
1337
+ if new_hash != old_hash:
1338
+ cursor.execute(
1339
+ """UPDATE doors_requirements
1340
+ SET title = ?, description = ?, priority = ?,
1341
+ requirement_type = ?, source_hash = ?, updated_at = ?
1342
+ WHERE project_id = ? AND doors_id = ?""",
1343
+ (
1344
+ req.get("title", ""),
1345
+ req.get("description", ""),
1346
+ req.get("priority"),
1347
+ req.get("requirement_type"),
1348
+ source_hash,
1349
+ timestamp,
1350
+ project_id,
1351
+ doors_id,
1352
+ ),
1353
+ )
1354
+ updated += 1
1355
+ else:
1356
+ unchanged += 1
1357
+ else:
1358
+ # New requirement — insert
1359
+ req_id = f"dreq-{uuid.uuid4()}"
1360
+ try:
1361
+ cursor.execute(
1362
+ """INSERT INTO doors_requirements
1363
+ (id, project_id, doors_id, title, description,
1364
+ priority, requirement_type, status,
1365
+ source_file, source_hash, imported_at, updated_at)
1366
+ VALUES (?, ?, ?, ?, ?, ?, ?, 'active', ?, ?, ?, ?)""",
1367
+ (
1368
+ req_id,
1369
+ project_id,
1370
+ doors_id,
1371
+ req.get("title", ""),
1372
+ req.get("description", ""),
1373
+ req.get("priority"),
1374
+ req.get("requirement_type"),
1375
+ str(file_path),
1376
+ source_hash,
1377
+ timestamp,
1378
+ timestamp,
1379
+ ),
1380
+ )
1381
+ added += 1
1382
+ except sqlite3.IntegrityError:
1383
+ unchanged += 1
1384
+
1385
+ # Mark requirements not in new file as deleted (soft delete via status)
1386
+ for doors_id in existing:
1387
+ if doors_id not in new_doors_ids:
1388
+ cursor.execute(
1389
+ """UPDATE doors_requirements
1390
+ SET status = 'deleted', updated_at = ?
1391
+ WHERE project_id = ? AND doors_id = ?""",
1392
+ (timestamp, project_id, doors_id),
1393
+ )
1394
+ deleted += 1
1395
+
1396
+ # Record in model_imports
1397
+ cursor.execute(
1398
+ """INSERT INTO model_imports
1399
+ (project_id, import_type, source_file, source_hash,
1400
+ elements_imported, relationships_imported, errors,
1401
+ error_details, status, imported_by, imported_at)
1402
+ VALUES (?, 'reqif_reimport', ?, ?, ?, 0, 0, NULL, 'completed',
1403
+ 'icdev-sync-engine', ?)""",
1404
+ (
1405
+ project_id,
1406
+ str(Path(file_path).name),
1407
+ source_hash,
1408
+ updated + added,
1409
+ timestamp,
1410
+ ),
1411
+ )
1412
+
1413
+ conn.commit()
1414
+ conn.close()
1415
+
1416
+ # Audit trail
1417
+ if _HAS_AUDIT:
1418
+ try:
1419
+ log_event(
1420
+ event_type="compliance_check",
1421
+ actor="icdev-sync-engine",
1422
+ action=(
1423
+ f"ReqIF reimport for {project_id}: "
1424
+ f"{updated} updated, {added} added, {deleted} deleted, "
1425
+ f"{unchanged} unchanged"
1426
+ ),
1427
+ project_id=project_id,
1428
+ details={
1429
+ "file": file_path,
1430
+ "source_hash": source_hash,
1431
+ "updated": updated,
1432
+ "added": added,
1433
+ "deleted": deleted,
1434
+ "unchanged": unchanged,
1435
+ },
1436
+ affected_files=[file_path],
1437
+ classification="CUI",
1438
+ db_path=Path(db_path) if db_path else None,
1439
+ )
1440
+ except Exception:
1441
+ pass
1442
+
1443
+ return {
1444
+ "updated": updated,
1445
+ "added": added,
1446
+ "deleted": deleted,
1447
+ "unchanged": unchanged,
1448
+ }
1449
+
1450
+
1451
+ # ---------------------------------------------------------------------------
1452
+ # Sync report
1453
+ # ---------------------------------------------------------------------------
1454
+
1455
+ def generate_sync_report(project_id: str,
1456
+ db_path: Optional[Path] = None) -> str:
1457
+ """Generate a CUI-marked drift/sync report as markdown.
1458
+
1459
+ Includes:
1460
+ - Summary statistics (synced, model_ahead, code_ahead, conflict, unknown)
1461
+ - Per-mapping details table
1462
+ - Conflict resolution guidance
1463
+ - Timestamps
1464
+ """
1465
+ conn = get_connection(db_path=db_path)
1466
+ cursor = conn.cursor()
1467
+
1468
+ # Fetch all mappings with element names
1469
+ cursor.execute(
1470
+ """SELECT mcm.id, mcm.sysml_element_id, mcm.code_path, mcm.code_type,
1471
+ mcm.mapping_direction, mcm.sync_status, mcm.last_synced,
1472
+ mcm.model_hash, mcm.code_hash,
1473
+ se.name AS element_name, se.element_type
1474
+ FROM model_code_mappings mcm
1475
+ LEFT JOIN sysml_elements se ON mcm.sysml_element_id = se.id
1476
+ WHERE mcm.project_id = ?
1477
+ ORDER BY mcm.sync_status, se.name""",
1478
+ (project_id,),
1479
+ )
1480
+ rows = [dict(r) for r in cursor.fetchall()]
1481
+
1482
+ # Fetch recent imports
1483
+ cursor.execute(
1484
+ """SELECT import_type, source_file, status, imported_at
1485
+ FROM model_imports
1486
+ WHERE project_id = ?
1487
+ ORDER BY imported_at DESC LIMIT 5""",
1488
+ (project_id,),
1489
+ )
1490
+ recent_imports = [dict(r) for r in cursor.fetchall()]
1491
+
1492
+ conn.close()
1493
+
1494
+ # Count statuses
1495
+ status_counts: Dict[str, int] = {
1496
+ "synced": 0, "model_ahead": 0, "code_ahead": 0,
1497
+ "conflict": 0, "unknown": 0,
1498
+ }
1499
+ for row in rows:
1500
+ s = row.get("sync_status", "unknown")
1501
+ status_counts[s] = status_counts.get(s, 0) + 1
1502
+
1503
+ # Build markdown
1504
+ lines = [
1505
+ "CUI // SP-CTI",
1506
+ "",
1507
+ f"# MBSE Sync Report: {project_id}",
1508
+ f"**Generated:** {_ts()}",
1509
+ "",
1510
+ "## Summary",
1511
+ "",
1512
+ "| Status | Count |",
1513
+ "|--------|-------|",
1514
+ f"| Synced | {status_counts['synced']} |",
1515
+ f"| Model Ahead | {status_counts['model_ahead']} |",
1516
+ f"| Code Ahead | {status_counts['code_ahead']} |",
1517
+ f"| Conflict | {status_counts['conflict']} |",
1518
+ f"| Unknown | {status_counts['unknown']} |",
1519
+ f"| **Total** | **{len(rows)}** |",
1520
+ "",
1521
+ ]
1522
+
1523
+ if status_counts["conflict"] > 0:
1524
+ lines.extend([
1525
+ "## Conflicts Requiring Resolution",
1526
+ "",
1527
+ "| ID | Element | Code Path | Direction |",
1528
+ "|----|---------|-----------|-----------|",
1529
+ ])
1530
+ for row in rows:
1531
+ if row["sync_status"] == "conflict":
1532
+ lines.append(
1533
+ f"| {row['id']} | {row.get('element_name', 'N/A')} "
1534
+ f"| `{row['code_path']}` | {row['mapping_direction']} |"
1535
+ )
1536
+ lines.append("")
1537
+ lines.extend([
1538
+ "**Resolution options:**",
1539
+ "- `--resolution keep_model` — Overwrite code with model version",
1540
+ "- `--resolution keep_code` — Accept code changes (model stale until reimport)",
1541
+ "- `--resolution merge` — Mark bidirectional for manual merge",
1542
+ "",
1543
+ ])
1544
+
1545
+ if rows:
1546
+ lines.extend([
1547
+ "## All Mappings",
1548
+ "",
1549
+ "| ID | Element | Type | Code Path | Status | Last Synced |",
1550
+ "|----|---------|------|-----------|--------|-------------|",
1551
+ ])
1552
+ for row in rows:
1553
+ lines.append(
1554
+ f"| {row['id']} | {row.get('element_name', 'N/A')} "
1555
+ f"| {row['code_type']} | `{row['code_path']}` "
1556
+ f"| {row['sync_status']} | {row.get('last_synced', 'N/A')} |"
1557
+ )
1558
+ lines.append("")
1559
+
1560
+ if recent_imports:
1561
+ lines.extend([
1562
+ "## Recent Imports",
1563
+ "",
1564
+ "| Type | File | Status | Date |",
1565
+ "|------|------|--------|------|",
1566
+ ])
1567
+ for imp in recent_imports:
1568
+ lines.append(
1569
+ f"| {imp['import_type']} | {imp['source_file']} "
1570
+ f"| {imp['status']} | {imp['imported_at']} |"
1571
+ )
1572
+ lines.append("")
1573
+
1574
+ lines.extend([
1575
+ "---",
1576
+ "CUI // SP-CTI",
1577
+ ])
1578
+
1579
+ return "\n".join(lines)
1580
+
1581
+
1582
+ # ---------------------------------------------------------------------------
1583
+ # CLI entry point
1584
+ # ---------------------------------------------------------------------------
1585
+
1586
+ def main() -> None:
1587
+ """Command-line interface for MBSE bidirectional sync engine."""
1588
+ parser = argparse.ArgumentParser(
1589
+ description="ICDEV MBSE Bidirectional Sync Engine"
1590
+ )
1591
+ parser.add_argument(
1592
+ "--project-id", required=True,
1593
+ help="ICDEV project identifier (e.g. proj-123)",
1594
+ )
1595
+
1596
+ sub = parser.add_subparsers(dest="command")
1597
+
1598
+ # detect-drift
1599
+ sub.add_parser("detect-drift", help="Detect model/code drift")
1600
+
1601
+ # sync model-to-code
1602
+ m2c = sub.add_parser("sync-model-to-code",
1603
+ help="Sync model changes to code files")
1604
+ m2c.add_argument("--language", default="python",
1605
+ help="Target language (default: python)")
1606
+
1607
+ # sync code-to-model
1608
+ c2m = sub.add_parser("sync-code-to-model",
1609
+ help="Sync code changes to XMI fragment for Cameo import")
1610
+ c2m.add_argument("--output", required=True,
1611
+ help="Output XMI file path")
1612
+
1613
+ # resolve-conflict
1614
+ rc = sub.add_parser("resolve-conflict",
1615
+ help="Resolve a model/code sync conflict")
1616
+ rc.add_argument("--mapping-id", type=int, required=True,
1617
+ help="ID from model_code_mappings table")
1618
+ rc.add_argument("--resolution", required=True,
1619
+ choices=["keep_model", "keep_code", "merge"],
1620
+ help="Conflict resolution strategy")
1621
+
1622
+ # reimport-xmi
1623
+ ri = sub.add_parser("reimport-xmi",
1624
+ help="Re-import XMI after Cameo updates")
1625
+ ri.add_argument("--file", required=True,
1626
+ help="Path to updated XMI file")
1627
+
1628
+ # reimport-reqif
1629
+ rr = sub.add_parser("reimport-reqif",
1630
+ help="Re-import ReqIF after DOORS updates")
1631
+ rr.add_argument("--file", required=True,
1632
+ help="Path to updated ReqIF file")
1633
+
1634
+ # report
1635
+ sub.add_parser("report", help="Generate drift/sync report")
1636
+
1637
+ parser.add_argument("--json", action="store_true", dest="json_output",
1638
+ help="Output results as JSON")
1639
+ parser.add_argument("--db-path", type=Path, default=None,
1640
+ help="Override database path (default: data/icdev.db)")
1641
+
1642
+ args = parser.parse_args()
1643
+ db = args.db_path
1644
+
1645
+ if not args.command:
1646
+ parser.print_help()
1647
+ sys.exit(1)
1648
+
1649
+ # ---- detect-drift ----
1650
+ if args.command == "detect-drift":
1651
+ result = detect_drift(args.project_id, db_path=db)
1652
+ if args.json_output:
1653
+ print("CUI // SP-CTI")
1654
+ print(json.dumps(result, indent=2, default=str))
1655
+ print("CUI // SP-CTI")
1656
+ else:
1657
+ print("CUI // SP-CTI")
1658
+ print(f"Drift Detection: {args.project_id}")
1659
+ print(f" Total mappings: {result['total_mappings']}")
1660
+ print(f" Synced: {result['synced']}")
1661
+ print(f" Model ahead: {result['model_ahead']}")
1662
+ print(f" Code ahead: {result['code_ahead']}")
1663
+ print(f" Conflict: {result['conflict']}")
1664
+ print(f" Unknown: {result['unknown']}")
1665
+ print(f" Missing files: {result['missing_files']}")
1666
+ if result.get("details"):
1667
+ print("\n Details:")
1668
+ for d in result["details"]:
1669
+ marker = {"synced": "=", "model_ahead": "M>",
1670
+ "code_ahead": "C>", "conflict": "!",
1671
+ "unknown": "?"}.get(d["new_status"], "?")
1672
+ print(f" [{marker}] {d['element_name']}: {d['code_path']}")
1673
+ print("CUI // SP-CTI")
1674
+
1675
+ # ---- sync-model-to-code ----
1676
+ elif args.command == "sync-model-to-code":
1677
+ result = sync_model_to_code(args.project_id, language=args.language,
1678
+ db_path=db)
1679
+ if args.json_output:
1680
+ print("CUI // SP-CTI")
1681
+ print(json.dumps(result, indent=2, default=str))
1682
+ print("CUI // SP-CTI")
1683
+ else:
1684
+ print("CUI // SP-CTI")
1685
+ print(f"Model-to-Code Sync: {args.project_id}")
1686
+ print(f" Files updated: {result['files_updated']}")
1687
+ print(f" Files created: {result['files_created']}")
1688
+ print(f" Files orphaned: {result['files_orphaned']}")
1689
+ print(f" Errors: {result['errors']}")
1690
+ if result.get("error_details"):
1691
+ for err in result["error_details"]:
1692
+ print(f" - {err}")
1693
+ print("CUI // SP-CTI")
1694
+
1695
+ # ---- sync-code-to-model ----
1696
+ elif args.command == "sync-code-to-model":
1697
+ result = sync_code_to_model(args.project_id, output_path=args.output,
1698
+ db_path=db)
1699
+ if args.json_output:
1700
+ print("CUI // SP-CTI")
1701
+ print(json.dumps(result, indent=2, default=str))
1702
+ print("CUI // SP-CTI")
1703
+ else:
1704
+ print("CUI // SP-CTI")
1705
+ print(f"Code-to-Model Sync: {args.project_id}")
1706
+ print(f" XMI file: {result['xmi_file']}")
1707
+ print(f" Elements exported: {result['elements_exported']}")
1708
+ print(f" Modified elements: {result['modified_elements']}")
1709
+ print(f" New elements: {result['new_elements']}")
1710
+ if result.get("errors"):
1711
+ print(f" Errors: {len(result['errors'])}")
1712
+ for err in result["errors"]:
1713
+ print(f" - {err}")
1714
+ print("CUI // SP-CTI")
1715
+
1716
+ # ---- resolve-conflict ----
1717
+ elif args.command == "resolve-conflict":
1718
+ result = resolve_conflict(args.project_id, mapping_id=args.mapping_id,
1719
+ resolution=args.resolution, db_path=db)
1720
+ if args.json_output:
1721
+ print("CUI // SP-CTI")
1722
+ print(json.dumps(result, indent=2, default=str))
1723
+ print("CUI // SP-CTI")
1724
+ else:
1725
+ print("CUI // SP-CTI")
1726
+ print(f"Conflict Resolution: mapping #{result['mapping_id']}")
1727
+ print(f" Resolution: {result['resolution']}")
1728
+ print(f" Status: {result['status']}")
1729
+ if result.get("error"):
1730
+ print(f" Error: {result['error']}")
1731
+ print("CUI // SP-CTI")
1732
+
1733
+ # ---- reimport-xmi ----
1734
+ elif args.command == "reimport-xmi":
1735
+ file_path = str(Path(args.file).resolve())
1736
+ result = reimport_xmi(args.project_id, file_path=file_path, db_path=db)
1737
+ if args.json_output:
1738
+ print("CUI // SP-CTI")
1739
+ print(json.dumps(result, indent=2, default=str))
1740
+ print("CUI // SP-CTI")
1741
+ else:
1742
+ print("CUI // SP-CTI")
1743
+ print(f"XMI Reimport: {args.project_id}")
1744
+ print(f" Updated: {result['updated']}")
1745
+ print(f" Added: {result['added']}")
1746
+ print(f" Deleted: {result['deleted']}")
1747
+ print(f" Unchanged: {result['unchanged']}")
1748
+ if result.get("error"):
1749
+ print(f" Error: {result['error']}")
1750
+ print("CUI // SP-CTI")
1751
+
1752
+ # ---- reimport-reqif ----
1753
+ elif args.command == "reimport-reqif":
1754
+ file_path = str(Path(args.file).resolve())
1755
+ result = reimport_reqif(args.project_id, file_path=file_path,
1756
+ db_path=db)
1757
+ if args.json_output:
1758
+ print("CUI // SP-CTI")
1759
+ print(json.dumps(result, indent=2, default=str))
1760
+ print("CUI // SP-CTI")
1761
+ else:
1762
+ print("CUI // SP-CTI")
1763
+ print(f"ReqIF Reimport: {args.project_id}")
1764
+ print(f" Updated: {result['updated']}")
1765
+ print(f" Added: {result['added']}")
1766
+ print(f" Deleted: {result['deleted']}")
1767
+ print(f" Unchanged: {result['unchanged']}")
1768
+ if result.get("error"):
1769
+ print(f" Error: {result['error']}")
1770
+ print("CUI // SP-CTI")
1771
+
1772
+ # ---- report ----
1773
+ elif args.command == "report":
1774
+ if args.json_output:
1775
+ # For JSON mode, run detect_drift and output the result
1776
+ result = detect_drift(args.project_id, db_path=db)
1777
+ print("CUI // SP-CTI")
1778
+ print(json.dumps(result, indent=2, default=str))
1779
+ print("CUI // SP-CTI")
1780
+ else:
1781
+ report = generate_sync_report(args.project_id, db_path=db)
1782
+ print(report)
1783
+
1784
+ sys.exit(0)
1785
+
1786
+
1787
+ if __name__ == "__main__":
1788
+ main()
1789
+ # [TEMPLATE: CUI // SP-CTI]