icdev 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1105) hide show
  1. icdev/__init__.py +18 -0
  2. icdev/_paths.py +85 -0
  3. icdev/_version.py +3 -0
  4. icdev/data/__init__.py +1 -0
  5. icdev/data/args/__init__.py +1 -0
  6. icdev/data/args/agent_authority.yaml +61 -0
  7. icdev/data/args/agent_config.yaml +355 -0
  8. icdev/data/args/agentic_fitness.yaml +31 -0
  9. icdev/data/args/ai_governance_config.yaml +137 -0
  10. icdev/data/args/atlas_critique_config.yaml +66 -0
  11. icdev/data/args/bedrock_models.yaml +63 -0
  12. icdev/data/args/cicd_config.yaml +82 -0
  13. icdev/data/args/classification_config.yaml +232 -0
  14. icdev/data/args/cli_config.yaml +154 -0
  15. icdev/data/args/cloud_config.yaml +63 -0
  16. icdev/data/args/code_pattern_config.yaml +151 -0
  17. icdev/data/args/code_quality_config.yaml +47 -0
  18. icdev/data/args/companion_registry.yaml +202 -0
  19. icdev/data/args/context_config.yaml +82 -0
  20. icdev/data/args/csp_monitor_config.yaml +268 -0
  21. icdev/data/args/cui_markings.yaml +35 -0
  22. icdev/data/args/db_config.yaml +40 -0
  23. icdev/data/args/deployment_profiles.yaml +248 -0
  24. icdev/data/args/dev_profile_config.yaml +144 -0
  25. icdev/data/args/devsecops_config.yaml +286 -0
  26. icdev/data/args/endpoint_security_config.yaml +137 -0
  27. icdev/data/args/extension_config.yaml +79 -0
  28. icdev/data/args/file_access_tiers.yaml +88 -0
  29. icdev/data/args/framework_registry.yaml +415 -0
  30. icdev/data/args/innovation_config.yaml +431 -0
  31. icdev/data/args/installation_manifest.yaml +1087 -0
  32. icdev/data/args/llm_config.yaml +495 -0
  33. icdev/data/args/maintenance_config.yaml +55 -0
  34. icdev/data/args/memory_config.yaml +83 -0
  35. icdev/data/args/monitoring_config.yaml +127 -0
  36. icdev/data/args/mosa_config.yaml +190 -0
  37. icdev/data/args/nlq_config.yaml +35 -0
  38. icdev/data/args/observability_config.yaml +39 -0
  39. icdev/data/args/observability_tracing_config.yaml +170 -0
  40. icdev/data/args/oscal_tools_config.yaml +43 -0
  41. icdev/data/args/owasp_agentic_config.yaml +171 -0
  42. icdev/data/args/phase_registry.yaml +618 -0
  43. icdev/data/args/project_defaults.yaml +235 -0
  44. icdev/data/args/prompt_chains.yaml +163 -0
  45. icdev/data/args/resilience_config.yaml +50 -0
  46. icdev/data/args/ricoas_config.yaml +191 -0
  47. icdev/data/args/role_personas.yaml +362 -0
  48. icdev/data/args/scaling_config.yaml +176 -0
  49. icdev/data/args/security_gates.yaml +685 -0
  50. icdev/data/args/skill_injection_config.yaml +322 -0
  51. icdev/data/args/spec_config.yaml +53 -0
  52. icdev/data/args/supply_chain_config.yaml +76 -0
  53. icdev/data/args/translation_config.yaml +228 -0
  54. icdev/data/args/workflow_templates/ato_acceleration.yaml +54 -0
  55. icdev/data/args/workflow_templates/build_deploy.yaml +63 -0
  56. icdev/data/args/workflow_templates/full_compliance.yaml +43 -0
  57. icdev/data/args/workflow_templates/security_hardening.yaml +55 -0
  58. icdev/data/args/worktree_config.yaml +34 -0
  59. icdev/data/args/zta_config.yaml +247 -0
  60. icdev/data/context/__init__.py +1 -0
  61. icdev/data/context/agent/__init__.py +1 -0
  62. icdev/data/context/agent/response_schemas/__init__.py +1 -0
  63. icdev/data/context/agent/response_schemas/debate_position.json +46 -0
  64. icdev/data/context/agent/response_schemas/fitness_scorecard.json +74 -0
  65. icdev/data/context/agent/response_schemas/review_decision.json +39 -0
  66. icdev/data/context/agent/response_schemas/task_decomposition.json +82 -0
  67. icdev/data/context/agent/response_schemas/veto_decision.json +40 -0
  68. icdev/data/context/agentic/__init__.py +1 -0
  69. icdev/data/context/agentic/architecture_patterns.md +269 -0
  70. icdev/data/context/agentic/capability_registry.yaml +202 -0
  71. icdev/data/context/agentic/csp_mcp_registry.yaml +280 -0
  72. icdev/data/context/agentic/fitness_rubric.md +56 -0
  73. icdev/data/context/agentic/governance_baseline.md +205 -0
  74. icdev/data/context/ci/__init__.py +1 -0
  75. icdev/data/context/ci/worktree_templates.json +44 -0
  76. icdev/data/context/cloud/__init__.py +1 -0
  77. icdev/data/context/cloud/csp_service_registry.json +739 -0
  78. icdev/data/context/compliance/__init__.py +1 -0
  79. icdev/data/context/compliance/atlas_mitigations.json +293 -0
  80. icdev/data/context/compliance/atlas_techniques.json +833 -0
  81. icdev/data/context/compliance/cisa_sbd_requirements.json +432 -0
  82. icdev/data/context/compliance/cjis_security_policy.json +522 -0
  83. icdev/data/context/compliance/cmmc_practices.json +2494 -0
  84. icdev/data/context/compliance/cmmc_report_template.md +142 -0
  85. icdev/data/context/compliance/cnssi_1253_overlay.json +109 -0
  86. icdev/data/context/compliance/control_crosswalk.json +1914 -0
  87. icdev/data/context/compliance/control_families/__init__.py +1 -0
  88. icdev/data/context/compliance/csp_certifications.json +251 -0
  89. icdev/data/context/compliance/cssp_report_template.md +193 -0
  90. icdev/data/context/compliance/cui_templates/__init__.py +1 -0
  91. icdev/data/context/compliance/cui_templates/banner_block.txt +4 -0
  92. icdev/data/context/compliance/cui_templates/code_header.txt +8 -0
  93. icdev/data/context/compliance/cui_templates/document_template.md +35 -0
  94. icdev/data/context/compliance/data_type_framework_map.json +321 -0
  95. icdev/data/context/compliance/data_type_registry.json +147 -0
  96. icdev/data/context/compliance/dod_cssp_8530.json +463 -0
  97. icdev/data/context/compliance/eu_ai_act_annex_iii.json +108 -0
  98. icdev/data/context/compliance/export_templates/__init__.py +1 -0
  99. icdev/data/context/compliance/export_templates/emass_controls.csv.j2 +4 -0
  100. icdev/data/context/compliance/export_templates/evidence_package.md.j2 +39 -0
  101. icdev/data/context/compliance/export_templates/executive_summary.md.j2 +55 -0
  102. icdev/data/context/compliance/export_templates/poam_tracking.csv.j2 +4 -0
  103. icdev/data/context/compliance/fedramp_20x_ksi_schemas.json +133 -0
  104. icdev/data/context/compliance/fedramp_high_baseline.json +4370 -0
  105. icdev/data/context/compliance/fedramp_moderate_baseline.json +2183 -0
  106. icdev/data/context/compliance/fedramp_report_template.md +181 -0
  107. icdev/data/context/compliance/fips_200_areas.json +362 -0
  108. icdev/data/context/compliance/gao_ai_accountability.json +262 -0
  109. icdev/data/context/compliance/hipaa_security_rule.json +720 -0
  110. icdev/data/context/compliance/hitrust_csf_v11.json +930 -0
  111. icdev/data/context/compliance/impact_level_profiles.json +251 -0
  112. icdev/data/context/compliance/incident_response_template.md +1110 -0
  113. icdev/data/context/compliance/iso27001_2022_controls.json +750 -0
  114. icdev/data/context/compliance/iso27001_nist_bridge.json +382 -0
  115. icdev/data/context/compliance/iso42001_controls.json +254 -0
  116. icdev/data/context/compliance/ivv_checklist_template.md +80 -0
  117. icdev/data/context/compliance/ivv_report_template.md +116 -0
  118. icdev/data/context/compliance/ivv_requirements.json +372 -0
  119. icdev/data/context/compliance/mosa_crosswalk.json +327 -0
  120. icdev/data/context/compliance/mosa_framework.json +250 -0
  121. icdev/data/context/compliance/narrative_templates/AC.md.j2 +101 -0
  122. icdev/data/context/compliance/narrative_templates/AU.md.j2 +106 -0
  123. icdev/data/context/compliance/narrative_templates/IA.md.j2 +104 -0
  124. icdev/data/context/compliance/narrative_templates/SC.md.j2 +102 -0
  125. icdev/data/context/compliance/narrative_templates/SI.md.j2 +111 -0
  126. icdev/data/context/compliance/narrative_templates/__init__.py +1 -0
  127. icdev/data/context/compliance/narrative_templates/default.md.j2 +50 -0
  128. icdev/data/context/compliance/narrative_templates/executive_summary.j2 +27 -0
  129. icdev/data/context/compliance/narrative_templates/poam_milestone.j2 +19 -0
  130. icdev/data/context/compliance/narrative_templates/ssp_section.j2 +11 -0
  131. icdev/data/context/compliance/nist_800_171_controls.json +1552 -0
  132. icdev/data/context/compliance/nist_800_207_crosswalk.json +399 -0
  133. icdev/data/context/compliance/nist_800_207_zta.json +258 -0
  134. icdev/data/context/compliance/nist_800_53.json +324 -0
  135. icdev/data/context/compliance/nist_ai_600_1_genai.json +326 -0
  136. icdev/data/context/compliance/nist_ai_rmf.json +206 -0
  137. icdev/data/context/compliance/nist_sp_800_60_types.json +1667 -0
  138. icdev/data/context/compliance/omb_m25_21_high_impact_ai.json +248 -0
  139. icdev/data/context/compliance/omb_m26_04_unbiased_ai.json +262 -0
  140. icdev/data/context/compliance/owasp_agentic_asi.json +133 -0
  141. icdev/data/context/compliance/owasp_agentic_threats.json +285 -0
  142. icdev/data/context/compliance/owasp_llm_top10.json +274 -0
  143. icdev/data/context/compliance/pci_dss_v4.json +510 -0
  144. icdev/data/context/compliance/poam_template.md +117 -0
  145. icdev/data/context/compliance/safeai_controls.json +512 -0
  146. icdev/data/context/compliance/sbd_report_template.md +77 -0
  147. icdev/data/context/compliance/siem_config_templates/__init__.py +1 -0
  148. icdev/data/context/compliance/siem_config_templates/filebeat.yml +213 -0
  149. icdev/data/context/compliance/siem_config_templates/log_sources.json +208 -0
  150. icdev/data/context/compliance/soc2_trust_criteria.json +661 -0
  151. icdev/data/context/compliance/ssp_template.md +432 -0
  152. icdev/data/context/compliance/stig_templates/__init__.py +1 -0
  153. icdev/data/context/compliance/stig_templates/webapp_stig.json +139 -0
  154. icdev/data/context/compliance/xai_requirements.json +108 -0
  155. icdev/data/context/dashboard/__init__.py +1 -0
  156. icdev/data/context/dashboard/nlq_examples.json +50 -0
  157. icdev/data/context/dashboard/schema_descriptions.json +23 -0
  158. icdev/data/context/integration/__init__.py +1 -0
  159. icdev/data/context/integration/approval_workflows.json +32 -0
  160. icdev/data/context/integration/gitlab_field_mappings.json +33 -0
  161. icdev/data/context/integration/jira_field_mappings.json +32 -0
  162. icdev/data/context/integration/reqif_export_schema.json +23 -0
  163. icdev/data/context/integration/servicenow_field_mappings.json +22 -0
  164. icdev/data/context/languages/__init__.py +1 -0
  165. icdev/data/context/languages/framework_patterns.json +205 -0
  166. icdev/data/context/languages/language_registry.json +279 -0
  167. icdev/data/context/llm/__init__.py +1 -0
  168. icdev/data/context/llm/example_provider.py +86 -0
  169. icdev/data/context/mbse/__init__.py +1 -0
  170. icdev/data/context/mbse/des_report_template.md +162 -0
  171. icdev/data/context/mbse/des_requirements.json +411 -0
  172. icdev/data/context/mbse/digital_thread_patterns.json +403 -0
  173. icdev/data/context/mbse/reqif_schema.json +280 -0
  174. icdev/data/context/mbse/sysml_element_types.json +432 -0
  175. icdev/data/context/modernization/__init__.py +1 -0
  176. icdev/data/context/modernization/db_type_mappings.json +148 -0
  177. icdev/data/context/modernization/decomposition_patterns.json +284 -0
  178. icdev/data/context/modernization/framework_migration_patterns.json +359 -0
  179. icdev/data/context/modernization/migration_report_template.md +168 -0
  180. icdev/data/context/modernization/seven_rs_catalog.json +369 -0
  181. icdev/data/context/modernization/version_upgrade_rules.json +279 -0
  182. icdev/data/context/oscal/NIST_SP-800-53_rev5_catalog.json +254987 -0
  183. icdev/data/context/oscal/README.md +43 -0
  184. icdev/data/context/patterns/__init__.py +1 -0
  185. icdev/data/context/profiles/__init__.py +1 -0
  186. icdev/data/context/profiles/dod_baseline_v1.yaml +145 -0
  187. icdev/data/context/profiles/fedramp_baseline_v1.yaml +143 -0
  188. icdev/data/context/profiles/financial_baseline_v1.yaml +142 -0
  189. icdev/data/context/profiles/healthcare_baseline_v1.yaml +135 -0
  190. icdev/data/context/profiles/law_enforcement_v1.yaml +129 -0
  191. icdev/data/context/profiles/startup_v1.yaml +134 -0
  192. icdev/data/context/requirements/__init__.py +1 -0
  193. icdev/data/context/requirements/ambiguity_patterns.json +97 -0
  194. icdev/data/context/requirements/boundary_impact_rules.json +123 -0
  195. icdev/data/context/requirements/default_constitutions.json +67 -0
  196. icdev/data/context/requirements/document_extraction_rules.json +58 -0
  197. icdev/data/context/requirements/gap_patterns.json +108 -0
  198. icdev/data/context/requirements/readiness_rubric.json +78 -0
  199. icdev/data/context/requirements/red_alternative_patterns.json +210 -0
  200. icdev/data/context/requirements/safe_templates.json +72 -0
  201. icdev/data/context/requirements/spec_quality_checklist.json +122 -0
  202. icdev/data/context/simulation/__init__.py +1 -0
  203. icdev/data/context/simulation/architecture_patterns.json +36 -0
  204. icdev/data/context/simulation/coa_templates.json +38 -0
  205. icdev/data/context/simulation/cost_models.json +23 -0
  206. icdev/data/context/simulation/risk_categories.json +46 -0
  207. icdev/data/context/supply_chain/__init__.py +1 -0
  208. icdev/data/context/supply_chain/isa_templates.json +129 -0
  209. icdev/data/context/supply_chain/nist_800_161_controls.json +247 -0
  210. icdev/data/context/supply_chain/scrm_risk_matrix.json +147 -0
  211. icdev/data/context/templates/__init__.py +1 -0
  212. icdev/data/context/templates/ansible/__init__.py +1 -0
  213. icdev/data/context/templates/ansible/playbooks/__init__.py +1 -0
  214. icdev/data/context/templates/ansible/roles/__init__.py +1 -0
  215. icdev/data/context/templates/gitlab_ci/__init__.py +1 -0
  216. icdev/data/context/templates/grafana/__init__.py +1 -0
  217. icdev/data/context/templates/kubernetes/__init__.py +1 -0
  218. icdev/data/context/templates/project/__init__.py +1 -0
  219. icdev/data/context/templates/project/api/__init__.py +1 -0
  220. icdev/data/context/templates/project/cli/__init__.py +1 -0
  221. icdev/data/context/templates/project/data_pipeline/__init__.py +1 -0
  222. icdev/data/context/templates/project/iac/__init__.py +1 -0
  223. icdev/data/context/templates/project/javascript_frontend/__init__.py +1 -0
  224. icdev/data/context/templates/project/javascript_frontend/src/__init__.py +1 -0
  225. icdev/data/context/templates/project/javascript_frontend/tests/__init__.py +1 -0
  226. icdev/data/context/templates/project/microservice/__init__.py +1 -0
  227. icdev/data/context/templates/project/python_backend/__init__.py +1 -0
  228. icdev/data/context/templates/project/python_backend/src/__init__.py +1 -0
  229. icdev/data/context/templates/project/python_backend/tests/__init__.py +1 -0
  230. icdev/data/context/templates/project/python_backend/tests/features/__init__.py +1 -0
  231. icdev/data/context/templates/project/python_backend/tests/steps/__init__.py +1 -0
  232. icdev/data/context/templates/terraform/__init__.py +1 -0
  233. icdev/data/context/templates/terraform/govcloud_base/__init__.py +1 -0
  234. icdev/data/context/templates/terraform/modules/__init__.py +1 -0
  235. icdev/data/context/tone/__init__.py +1 -0
  236. icdev/data/context/translation/dependency_mappings.json +186 -0
  237. icdev/data/context/translation/type_mappings.json +149 -0
  238. icdev/data/docs/README.md +187 -0
  239. icdev/data/docs/__init__.py +1 -0
  240. icdev/data/docs/admin/gateway-guide.md +338 -0
  241. icdev/data/docs/admin/marketplace-guide.md +396 -0
  242. icdev/data/docs/admin/monitoring-guide.md +509 -0
  243. icdev/data/docs/architecture/compliance-framework.md +764 -0
  244. icdev/data/docs/architecture/database-schema.md +689 -0
  245. icdev/data/docs/architecture/gotcha-framework.md +518 -0
  246. icdev/data/docs/architecture/multi-agent-system.md +603 -0
  247. icdev/data/docs/dx/README.md +106 -0
  248. icdev/data/docs/dx/__init__.py +1 -0
  249. icdev/data/docs/dx/ci-cd-integration.md +378 -0
  250. icdev/data/docs/dx/claude-code-guide.md +213 -0
  251. icdev/data/docs/dx/companion-guide.md +232 -0
  252. icdev/data/docs/dx/dev-profiles.md +309 -0
  253. icdev/data/docs/dx/icdev-yaml-spec.md +219 -0
  254. icdev/data/docs/dx/integration-tiers.md +279 -0
  255. icdev/data/docs/dx/llm-routing-guide.md +456 -0
  256. icdev/data/docs/dx/quickstart.md +192 -0
  257. icdev/data/docs/dx/sdk-reference.md +356 -0
  258. icdev/data/docs/dx/unified-mcp-setup.md +525 -0
  259. icdev/data/docs/features/__init__.py +1 -0
  260. icdev/data/docs/features/phase-01-gotcha-framework.md +249 -0
  261. icdev/data/docs/features/phase-02-atlas-build-workflow.md +223 -0
  262. icdev/data/docs/features/phase-03-tdd-bdd-testing.md +261 -0
  263. icdev/data/docs/features/phase-04-nist-compliance.md +255 -0
  264. icdev/data/docs/features/phase-05-security-scanning.md +229 -0
  265. icdev/data/docs/features/phase-06-infrastructure-deployment.md +288 -0
  266. icdev/data/docs/features/phase-07-code-review-gates.md +276 -0
  267. icdev/data/docs/features/phase-08-self-healing.md +223 -0
  268. icdev/data/docs/features/phase-09-monitoring-observability.md +230 -0
  269. icdev/data/docs/features/phase-10-dashboard-web-ui.md +218 -0
  270. icdev/data/docs/features/phase-11-multi-agent-architecture.md +272 -0
  271. icdev/data/docs/features/phase-12-integration-testing.md +228 -0
  272. icdev/data/docs/features/phase-13-cicd-integration.md +257 -0
  273. icdev/data/docs/features/phase-14-secure-by-design-ivv.md +240 -0
  274. icdev/data/docs/features/phase-15-maintenance-audit.md +192 -0
  275. icdev/data/docs/features/phase-16-ato-acceleration.md +228 -0
  276. icdev/data/docs/features/phase-17-multi-framework-compliance.md +223 -0
  277. icdev/data/docs/features/phase-18-mbse-integration.md +242 -0
  278. icdev/data/docs/features/phase-19-agentic-generation.md +202 -0
  279. icdev/data/docs/features/phase-20-fips-security-categorization.md +198 -0
  280. icdev/data/docs/features/phase-21-saas-multi-tenancy.md +273 -0
  281. icdev/data/docs/features/phase-22-federated-gotcha-marketplace.md +242 -0
  282. icdev/data/docs/features/phase-23-universal-compliance-platform.md +238 -0
  283. icdev/data/docs/features/phase-24-devsecops-pipeline-security.md +198 -0
  284. icdev/data/docs/features/phase-25-zero-trust-architecture.md +220 -0
  285. icdev/data/docs/features/phase-26-dod-mosa.md +205 -0
  286. icdev/data/docs/features/phase-27-cli-capabilities.md +222 -0
  287. icdev/data/docs/features/phase-28-remote-command-gateway.md +235 -0
  288. icdev/data/docs/features/phase-29-proactive-monitoring.md +212 -0
  289. icdev/data/docs/features/phase-30-dashboard-auth.md +215 -0
  290. icdev/data/docs/features/phase-31-dashboard-ux-low-impact.md +188 -0
  291. icdev/data/docs/features/phase-32-dashboard-ux-medium-impact.md +223 -0
  292. icdev/data/docs/features/phase-33-modular-installation.md +218 -0
  293. icdev/data/docs/features/phase-34-dev-profiles.md +239 -0
  294. icdev/data/docs/features/phase-35-innovation-engine.md +257 -0
  295. icdev/data/docs/features/phase-36-evolutionary-intelligence.md +351 -0
  296. icdev/data/docs/features/phase-37-mitre-atlas-integration.md +485 -0
  297. icdev/data/docs/features/phase-38-cloud-agnostic-architecture.md +1033 -0
  298. icdev/data/docs/features/phase-39-observability-operations.md +178 -0
  299. icdev/data/docs/features/phase-40-nlq-compliance-queries.md +176 -0
  300. icdev/data/docs/features/phase-41-parallel-cicd.md +169 -0
  301. icdev/data/docs/features/phase-42-framework-planning.md +177 -0
  302. icdev/data/docs/features/phase-43-cross-language-translation.md +225 -0
  303. icdev/data/docs/features/phase-44-innovation-adaptation.md +227 -0
  304. icdev/data/docs/features/phase-45-owasp-agentic-security.md +239 -0
  305. icdev/data/docs/features/phase-46-observability-traceability-xai.md +240 -0
  306. icdev/data/docs/features/phase-47-unified-mcp-gateway.md +257 -0
  307. icdev/data/docs/features/phase-48-ai-transparency.md +203 -0
  308. icdev/data/docs/features/phase-49-ai-accountability.md +243 -0
  309. icdev/data/docs/features/phase-50-ai-governance-intake-chat.md +195 -0
  310. icdev/data/docs/features/phase-51-unified-chat-dashboard.md +240 -0
  311. icdev/data/docs/features/phase-52-code-intelligence.md +244 -0
  312. icdev/data/docs/features/phase-53-fedramp-20x-owasp-asi.md +359 -0
  313. icdev/data/docs/features/phase-54-slsa-swft-orchestration.md +379 -0
  314. icdev/data/docs/features/phase-55-a2a-v03-mcp-oauth.md +322 -0
  315. icdev/data/docs/features/phase-56-evidence-lineage.md +352 -0
  316. icdev/data/docs/features/phase-57-eu-ai-act-iron-bank.md +319 -0
  317. icdev/data/docs/features/phase-58-creative-engine.md +370 -0
  318. icdev/data/docs/features/phase-59-govcon-intelligence.md +535 -0
  319. icdev/data/docs/features/phase-60-cpmp.md +528 -0
  320. icdev/data/docs/features/phase-61-orchestration-improvements.md +534 -0
  321. icdev/data/docs/operations/dashboard-guide.md +354 -0
  322. icdev/data/docs/operations/deployment-guide.md +556 -0
  323. icdev/data/docs/operations/saas-admin-guide.md +439 -0
  324. icdev/data/docs/operations/security-operations-guide.md +733 -0
  325. icdev/data/docs/runbooks/backup-restore.md +412 -0
  326. icdev/data/docs/runbooks/troubleshooting.md +499 -0
  327. icdev/data/features/__init__.py +1 -0
  328. icdev/data/features/cicd_integration.feature +41 -0
  329. icdev/data/features/compliance_gates.feature +46 -0
  330. icdev/data/features/dashboard.feature +72 -0
  331. icdev/data/features/environment.py +25 -0
  332. icdev/data/features/project_management.feature +32 -0
  333. icdev/data/features/requirements_intake.feature +42 -0
  334. icdev/data/features/saas_platform.feature +53 -0
  335. icdev/data/features/security_scanning.feature +36 -0
  336. icdev/data/features/steps/__init__.py +1 -0
  337. icdev/data/features/steps/cicd_steps.py +465 -0
  338. icdev/data/features/steps/compliance_steps.py +308 -0
  339. icdev/data/features/steps/dashboard_steps.py +88 -0
  340. icdev/data/features/steps/project_steps.py +126 -0
  341. icdev/data/features/steps/requirements_intake_steps.py +689 -0
  342. icdev/data/features/steps/saas_platform_steps.py +572 -0
  343. icdev/data/features/steps/security_steps.py +236 -0
  344. icdev/data/features/steps/testing_steps.py +226 -0
  345. icdev/data/features/testing_pipeline.feature +42 -0
  346. icdev/data/goals/__init__.py +1 -0
  347. icdev/data/goals/agent_management.md +144 -0
  348. icdev/data/goals/agentic_generation.md +345 -0
  349. icdev/data/goals/agentic_threat_model.md +309 -0
  350. icdev/data/goals/ai_accountability.md +90 -0
  351. icdev/data/goals/ai_governance_intake.md +132 -0
  352. icdev/data/goals/ai_transparency.md +76 -0
  353. icdev/data/goals/atlas_integration.md +405 -0
  354. icdev/data/goals/ato_acceleration.md +139 -0
  355. icdev/data/goals/boundary_supply_chain.md +206 -0
  356. icdev/data/goals/build_app.md +544 -0
  357. icdev/data/goals/cicd_integration.md +86 -0
  358. icdev/data/goals/claude_dir_maintenance.md +77 -0
  359. icdev/data/goals/cli_capabilities.md +340 -0
  360. icdev/data/goals/cloud_agnostic.md +312 -0
  361. icdev/data/goals/code_intelligence.md +197 -0
  362. icdev/data/goals/code_review.md +94 -0
  363. icdev/data/goals/compliance_workflow.md +858 -0
  364. icdev/data/goals/continuous_harmonization.md +140 -0
  365. icdev/data/goals/cross_language_translation.md +171 -0
  366. icdev/data/goals/dashboard.md +142 -0
  367. icdev/data/goals/deploy_workflow.md +390 -0
  368. icdev/data/goals/devsecops_workflow.md +408 -0
  369. icdev/data/goals/evolutionary_intelligence.md +305 -0
  370. icdev/data/goals/external_integration.md +113 -0
  371. icdev/data/goals/framework_planning.md +63 -0
  372. icdev/data/goals/init_project.md +235 -0
  373. icdev/data/goals/innovation_engine.md +199 -0
  374. icdev/data/goals/integration_testing.md +189 -0
  375. icdev/data/goals/maintenance_audit.md +196 -0
  376. icdev/data/goals/manifest.md +56 -0
  377. icdev/data/goals/mbse_integration.md +504 -0
  378. icdev/data/goals/modernization_workflow.md +618 -0
  379. icdev/data/goals/monitoring.md +126 -0
  380. icdev/data/goals/mosa_workflow.md +463 -0
  381. icdev/data/goals/multi_agent_orchestration.md +68 -0
  382. icdev/data/goals/nlq_compliance.md +63 -0
  383. icdev/data/goals/observability.md +64 -0
  384. icdev/data/goals/observability_traceability_xai.md +154 -0
  385. icdev/data/goals/owasp_agentic_security.md +395 -0
  386. icdev/data/goals/parallel_cicd.md +61 -0
  387. icdev/data/goals/requirements_intake.md +213 -0
  388. icdev/data/goals/sbd_ivv_workflow.md +195 -0
  389. icdev/data/goals/security_categorization.md +133 -0
  390. icdev/data/goals/security_scan.md +381 -0
  391. icdev/data/goals/self_healing.md +120 -0
  392. icdev/data/goals/simulation_engine.md +111 -0
  393. icdev/data/goals/tdd_workflow.md +403 -0
  394. icdev/data/goals/zero_trust_architecture.md +403 -0
  395. icdev/data/hardprompts/__init__.py +1 -0
  396. icdev/data/hardprompts/agent/__init__.py +1 -0
  397. icdev/data/hardprompts/agent/agentic_architect.md +100 -0
  398. icdev/data/hardprompts/agent/debate_prompt.md +32 -0
  399. icdev/data/hardprompts/agent/fitness_evaluation.md +48 -0
  400. icdev/data/hardprompts/agent/governance_review.md +214 -0
  401. icdev/data/hardprompts/agent/reviewer_prompt.md +34 -0
  402. icdev/data/hardprompts/agent/skill_design.md +172 -0
  403. icdev/data/hardprompts/agent/task_decomposition.md +275 -0
  404. icdev/data/hardprompts/agent/veto_check_prompt.md +33 -0
  405. icdev/data/hardprompts/architect/__init__.py +1 -0
  406. icdev/data/hardprompts/architect/api_design.md +283 -0
  407. icdev/data/hardprompts/architect/data_model.md +277 -0
  408. icdev/data/hardprompts/architect/system_design.md +180 -0
  409. icdev/data/hardprompts/builder/__init__.py +1 -0
  410. icdev/data/hardprompts/builder/code_generation.md +59 -0
  411. icdev/data/hardprompts/builder/refactor.md +58 -0
  412. icdev/data/hardprompts/builder/scaffold_project.md +69 -0
  413. icdev/data/hardprompts/builder/test_generation.md +87 -0
  414. icdev/data/hardprompts/ci/__init__.py +1 -0
  415. icdev/data/hardprompts/ci/worktree_setup.md +35 -0
  416. icdev/data/hardprompts/compliance/__init__.py +1 -0
  417. icdev/data/hardprompts/compliance/cmmc_assessment.md +63 -0
  418. icdev/data/hardprompts/compliance/cssp_assessment.md +75 -0
  419. icdev/data/hardprompts/compliance/cui_marking.md +86 -0
  420. icdev/data/hardprompts/compliance/fedramp_assessment.md +55 -0
  421. icdev/data/hardprompts/compliance/ivv_assessment.md +96 -0
  422. icdev/data/hardprompts/compliance/poam_generation.md +57 -0
  423. icdev/data/hardprompts/compliance/sbd_assessment.md +101 -0
  424. icdev/data/hardprompts/compliance/security_categorization.md +74 -0
  425. icdev/data/hardprompts/compliance/ssp_generation.md +56 -0
  426. icdev/data/hardprompts/compliance/stig_evaluation.md +63 -0
  427. icdev/data/hardprompts/dashboard/__init__.py +1 -0
  428. icdev/data/hardprompts/dashboard/nlq_system_prompt.md +26 -0
  429. icdev/data/hardprompts/infra/__init__.py +1 -0
  430. icdev/data/hardprompts/infra/k8s_manifests.md +118 -0
  431. icdev/data/hardprompts/infra/pipeline_generation.md +160 -0
  432. icdev/data/hardprompts/infra/terraform_generation.md +92 -0
  433. icdev/data/hardprompts/integration/__init__.py +1 -0
  434. icdev/data/hardprompts/integration/approval_review.md +17 -0
  435. icdev/data/hardprompts/integration/jira_mapping.md +25 -0
  436. icdev/data/hardprompts/integration/servicenow_mapping.md +14 -0
  437. icdev/data/hardprompts/knowledge/__init__.py +1 -0
  438. icdev/data/hardprompts/knowledge/pattern_detection.md +73 -0
  439. icdev/data/hardprompts/knowledge/recommendation_engine.md +90 -0
  440. icdev/data/hardprompts/knowledge/root_cause_analysis.md +91 -0
  441. icdev/data/hardprompts/maintenance/__init__.py +1 -0
  442. icdev/data/hardprompts/maintenance/maintenance_assessment.md +82 -0
  443. icdev/data/hardprompts/mbse/__init__.py +1 -0
  444. icdev/data/hardprompts/mbse/digital_thread.md +67 -0
  445. icdev/data/hardprompts/mbse/model_import.md +62 -0
  446. icdev/data/hardprompts/mbse/model_to_code.md +65 -0
  447. icdev/data/hardprompts/modernization/__init__.py +1 -0
  448. icdev/data/hardprompts/modernization/legacy_analysis.md +93 -0
  449. icdev/data/hardprompts/modernization/migration_planning.md +150 -0
  450. icdev/data/hardprompts/modernization/seven_r_assessment.md +107 -0
  451. icdev/data/hardprompts/requirements/__init__.py +1 -0
  452. icdev/data/hardprompts/requirements/bdd_generation.md +35 -0
  453. icdev/data/hardprompts/requirements/clarification_prioritization.md +29 -0
  454. icdev/data/hardprompts/requirements/decomposition.md +60 -0
  455. icdev/data/hardprompts/requirements/document_extraction.md +45 -0
  456. icdev/data/hardprompts/requirements/gap_detection.md +70 -0
  457. icdev/data/hardprompts/requirements/intake_conversation.md +101 -0
  458. icdev/data/hardprompts/requirements/readiness_assessment.md +39 -0
  459. icdev/data/hardprompts/requirements/spec_quality.md +33 -0
  460. icdev/data/hardprompts/requirements/traceability_analysis.md +23 -0
  461. icdev/data/hardprompts/security/__init__.py +1 -0
  462. icdev/data/hardprompts/security/endpoint_security.md +78 -0
  463. icdev/data/hardprompts/security/threat_model.md +70 -0
  464. icdev/data/hardprompts/security/vulnerability_assessment.md +81 -0
  465. icdev/data/hardprompts/simulation/__init__.py +1 -0
  466. icdev/data/hardprompts/simulation/architecture_impact.md +27 -0
  467. icdev/data/hardprompts/simulation/coa_alternative.md +27 -0
  468. icdev/data/hardprompts/simulation/coa_generation.md +25 -0
  469. icdev/data/hardprompts/simulation/compliance_impact.md +28 -0
  470. icdev/data/hardprompts/simulation/cost_estimation.md +33 -0
  471. icdev/data/hardprompts/simulation/risk_assessment.md +28 -0
  472. icdev/data/hardprompts/translation/code_translation.md +68 -0
  473. icdev/data/hardprompts/translation/dependency_suggestion.md +44 -0
  474. icdev/data/hardprompts/translation/test_translation.md +64 -0
  475. icdev/data/hardprompts/translation/translation_repair.md +59 -0
  476. icdev/py.typed +0 -0
  477. icdev/tools/__init__.py +1 -0
  478. icdev/tools/_gen_formatter.py +12 -0
  479. icdev/tools/a2a/__init__.py +1 -0
  480. icdev/tools/a2a/agent_cards/architect.json +43 -0
  481. icdev/tools/a2a/agent_cards/builder.json +50 -0
  482. icdev/tools/a2a/agent_cards/compliance.json +57 -0
  483. icdev/tools/a2a/agent_cards/devsecops.json +71 -0
  484. icdev/tools/a2a/agent_cards/infra.json +57 -0
  485. icdev/tools/a2a/agent_cards/integration.json +57 -0
  486. icdev/tools/a2a/agent_cards/knowledge.json +43 -0
  487. icdev/tools/a2a/agent_cards/mbse.json +57 -0
  488. icdev/tools/a2a/agent_cards/modernization.json +50 -0
  489. icdev/tools/a2a/agent_cards/monitor.json +43 -0
  490. icdev/tools/a2a/agent_cards/orchestrator.json +36 -0
  491. icdev/tools/a2a/agent_cards/requirements_analyst.json +64 -0
  492. icdev/tools/a2a/agent_cards/security.json +50 -0
  493. icdev/tools/a2a/agent_cards/simulation.json +57 -0
  494. icdev/tools/a2a/agent_cards/supply_chain.json +50 -0
  495. icdev/tools/a2a/agent_client.py +349 -0
  496. icdev/tools/a2a/agent_registry.py +412 -0
  497. icdev/tools/a2a/agent_server.py +579 -0
  498. icdev/tools/a2a/task.py +200 -0
  499. icdev/tools/agent/__init__.py +2 -0
  500. icdev/tools/agent/a2a_agent_card_generator.py +285 -0
  501. icdev/tools/agent/a2a_discovery_server.py +250 -0
  502. icdev/tools/agent/agent_executor.py +529 -0
  503. icdev/tools/agent/agent_memory.py +557 -0
  504. icdev/tools/agent/agent_models.py +51 -0
  505. icdev/tools/agent/atlas_critique.py +908 -0
  506. icdev/tools/agent/authority.py +443 -0
  507. icdev/tools/agent/bedrock_client.py +1075 -0
  508. icdev/tools/agent/collaboration.py +871 -0
  509. icdev/tools/agent/dispatcher_mode.py +665 -0
  510. icdev/tools/agent/mailbox.py +575 -0
  511. icdev/tools/agent/prompt_chain_executor.py +1064 -0
  512. icdev/tools/agent/session_purpose.py +350 -0
  513. icdev/tools/agent/skill_router.py +638 -0
  514. icdev/tools/agent/skill_selector.py +486 -0
  515. icdev/tools/agent/team_orchestrator.py +1108 -0
  516. icdev/tools/agent/token_tracker.py +290 -0
  517. icdev/tools/analysis/__init__.py +1 -0
  518. icdev/tools/analysis/code_analyzer.py +780 -0
  519. icdev/tools/analysis/runtime_feedback.py +389 -0
  520. icdev/tools/audit/__init__.py +1 -0
  521. icdev/tools/audit/audit_logger.py +196 -0
  522. icdev/tools/audit/audit_query.py +157 -0
  523. icdev/tools/audit/decision_recorder.py +72 -0
  524. icdev/tools/builder/__init__.py +1 -0
  525. icdev/tools/builder/agentic_fitness.py +534 -0
  526. icdev/tools/builder/agentic_test_templates/test_a2a_callback.py +117 -0
  527. icdev/tools/builder/agentic_test_templates/test_a2a_lifecycle.feature +52 -0
  528. icdev/tools/builder/agentic_test_templates/test_agent_card.feature +37 -0
  529. icdev/tools/builder/agentic_test_templates/test_agent_health.py +128 -0
  530. icdev/tools/builder/agentic_test_templates/test_memory_system.feature +50 -0
  531. icdev/tools/builder/agentic_test_templates/test_skill_execution.feature +40 -0
  532. icdev/tools/builder/app_blueprint.py +1583 -0
  533. icdev/tools/builder/child_app_generator.py +2852 -0
  534. icdev/tools/builder/claude_md_generator.py +1734 -0
  535. icdev/tools/builder/code_generator.py +3703 -0
  536. icdev/tools/builder/db_init_generator.py +1709 -0
  537. icdev/tools/builder/dev_profile_manager.py +954 -0
  538. icdev/tools/builder/formatter.py +768 -0
  539. icdev/tools/builder/goal_adapter.py +592 -0
  540. icdev/tools/builder/gotcha_validator.py +812 -0
  541. icdev/tools/builder/language_support.py +441 -0
  542. icdev/tools/builder/linter.py +976 -0
  543. icdev/tools/builder/profile_detector.py +657 -0
  544. icdev/tools/builder/profile_md_generator.py +723 -0
  545. icdev/tools/builder/scaffolder.py +1590 -0
  546. icdev/tools/builder/scaffolder_extended.py +1771 -0
  547. icdev/tools/builder/test_writer.py +950 -0
  548. icdev/tools/ci/__init__.py +2 -0
  549. icdev/tools/ci/connectors/__init__.py +2 -0
  550. icdev/tools/ci/connectors/base_connector.py +80 -0
  551. icdev/tools/ci/connectors/connector_registry.py +188 -0
  552. icdev/tools/ci/connectors/mattermost_connector.py +159 -0
  553. icdev/tools/ci/connectors/slack_connector.py +197 -0
  554. icdev/tools/ci/core/__init__.py +2 -0
  555. icdev/tools/ci/core/air_gap_detector.py +115 -0
  556. icdev/tools/ci/core/comment_handler.py +192 -0
  557. icdev/tools/ci/core/conversation_manager.py +479 -0
  558. icdev/tools/ci/core/event_envelope.py +500 -0
  559. icdev/tools/ci/core/event_router.py +443 -0
  560. icdev/tools/ci/core/failure_parser.py +397 -0
  561. icdev/tools/ci/core/recovery_engine.py +527 -0
  562. icdev/tools/ci/modules/__init__.py +2 -0
  563. icdev/tools/ci/modules/agent.py +271 -0
  564. icdev/tools/ci/modules/git_ops.py +175 -0
  565. icdev/tools/ci/modules/state.py +117 -0
  566. icdev/tools/ci/modules/vcs.py +303 -0
  567. icdev/tools/ci/modules/workflow_ops.py +295 -0
  568. icdev/tools/ci/modules/worktree.py +340 -0
  569. icdev/tools/ci/pipeline_config_generator.py +558 -0
  570. icdev/tools/ci/triggers/__init__.py +2 -0
  571. icdev/tools/ci/triggers/gitlab_task_monitor.py +330 -0
  572. icdev/tools/ci/triggers/poll_trigger.py +237 -0
  573. icdev/tools/ci/triggers/webhook_server.py +356 -0
  574. icdev/tools/ci/workflows/__init__.py +2 -0
  575. icdev/tools/ci/workflows/icdev_build.py +140 -0
  576. icdev/tools/ci/workflows/icdev_comply.py +284 -0
  577. icdev/tools/ci/workflows/icdev_document.py +152 -0
  578. icdev/tools/ci/workflows/icdev_e2e.py +188 -0
  579. icdev/tools/ci/workflows/icdev_patch.py +186 -0
  580. icdev/tools/ci/workflows/icdev_plan.py +202 -0
  581. icdev/tools/ci/workflows/icdev_plan_build.py +41 -0
  582. icdev/tools/ci/workflows/icdev_plan_build_test.py +46 -0
  583. icdev/tools/ci/workflows/icdev_plan_build_test_review.py +47 -0
  584. icdev/tools/ci/workflows/icdev_review.py +126 -0
  585. icdev/tools/ci/workflows/icdev_sdlc.py +261 -0
  586. icdev/tools/ci/workflows/icdev_test.py +240 -0
  587. icdev/tools/cli/__init__.py +1 -0
  588. icdev/tools/cli/output_formatter.py +756 -0
  589. icdev/tools/cli_formatter.py +42 -0
  590. icdev/tools/cloud/__init__.py +11 -0
  591. icdev/tools/cloud/cloud_mode_manager.py +364 -0
  592. icdev/tools/cloud/csp_changelog.py +383 -0
  593. icdev/tools/cloud/csp_health_checker.py +268 -0
  594. icdev/tools/cloud/csp_monitor.py +951 -0
  595. icdev/tools/cloud/iam_provider.py +593 -0
  596. icdev/tools/cloud/kms_provider.py +346 -0
  597. icdev/tools/cloud/monitoring_provider.py +628 -0
  598. icdev/tools/cloud/provider_factory.py +376 -0
  599. icdev/tools/cloud/region_validator.py +345 -0
  600. icdev/tools/cloud/registry_provider.py +563 -0
  601. icdev/tools/cloud/secrets_provider.py +486 -0
  602. icdev/tools/cloud/storage_provider.py +446 -0
  603. icdev/tools/compat/__init__.py +21 -0
  604. icdev/tools/compat/cli_harmonizer.py +251 -0
  605. icdev/tools/compat/datetime_utils.py +18 -0
  606. icdev/tools/compat/db_utils.py +160 -0
  607. icdev/tools/compat/platform_utils.py +123 -0
  608. icdev/tools/compliance/__init__.py +1 -0
  609. icdev/tools/compliance/accountability_manager.py +397 -0
  610. icdev/tools/compliance/ai_accountability_audit.py +294 -0
  611. icdev/tools/compliance/ai_impact_assessor.py +273 -0
  612. icdev/tools/compliance/ai_incident_response.py +301 -0
  613. icdev/tools/compliance/ai_inventory_manager.py +239 -0
  614. icdev/tools/compliance/ai_reassessment_scheduler.py +256 -0
  615. icdev/tools/compliance/ai_transparency_audit.py +248 -0
  616. icdev/tools/compliance/atlas_assessor.py +278 -0
  617. icdev/tools/compliance/atlas_report_generator.py +1211 -0
  618. icdev/tools/compliance/base_assessor.py +597 -0
  619. icdev/tools/compliance/cato_monitor.py +1385 -0
  620. icdev/tools/compliance/cato_scheduler.py +699 -0
  621. icdev/tools/compliance/cjis_assessor.py +76 -0
  622. icdev/tools/compliance/classification_manager.py +1353 -0
  623. icdev/tools/compliance/cmmc_assessor.py +1491 -0
  624. icdev/tools/compliance/cmmc_report_generator.py +1100 -0
  625. icdev/tools/compliance/compliance_detector.py +463 -0
  626. icdev/tools/compliance/compliance_exporter.py +427 -0
  627. icdev/tools/compliance/compliance_status.py +825 -0
  628. icdev/tools/compliance/control_mapper.py +505 -0
  629. icdev/tools/compliance/crosswalk_engine.py +1203 -0
  630. icdev/tools/compliance/cssp_assessor.py +1045 -0
  631. icdev/tools/compliance/cssp_evidence_collector.py +729 -0
  632. icdev/tools/compliance/cssp_report_generator.py +1116 -0
  633. icdev/tools/compliance/cui_marker.py +388 -0
  634. icdev/tools/compliance/diagram_validator.py +600 -0
  635. icdev/tools/compliance/emass/__init__.py +2 -0
  636. icdev/tools/compliance/emass/emass_client.py +840 -0
  637. icdev/tools/compliance/emass/emass_export.py +777 -0
  638. icdev/tools/compliance/emass/emass_sync.py +826 -0
  639. icdev/tools/compliance/eu_ai_act_classifier.py +194 -0
  640. icdev/tools/compliance/evidence_collector.py +468 -0
  641. icdev/tools/compliance/fairness_assessor.py +316 -0
  642. icdev/tools/compliance/fedramp_assessor.py +1808 -0
  643. icdev/tools/compliance/fedramp_authorization_packager.py +137 -0
  644. icdev/tools/compliance/fedramp_ksi_generator.py +355 -0
  645. icdev/tools/compliance/fedramp_report_generator.py +1128 -0
  646. icdev/tools/compliance/fips199_categorizer.py +881 -0
  647. icdev/tools/compliance/fips200_validator.py +315 -0
  648. icdev/tools/compliance/gao_ai_assessor.py +231 -0
  649. icdev/tools/compliance/gao_evidence_builder.py +308 -0
  650. icdev/tools/compliance/hipaa_assessor.py +78 -0
  651. icdev/tools/compliance/hitrust_assessor.py +49 -0
  652. icdev/tools/compliance/incident_response_plan.py +718 -0
  653. icdev/tools/compliance/iso27001_assessor.py +92 -0
  654. icdev/tools/compliance/iso42001_assessor.py +114 -0
  655. icdev/tools/compliance/ivv_assessor.py +2327 -0
  656. icdev/tools/compliance/ivv_report_generator.py +1662 -0
  657. icdev/tools/compliance/model_card_generator.py +297 -0
  658. icdev/tools/compliance/mosa_assessor.py +117 -0
  659. icdev/tools/compliance/multi_regime_assessor.py +451 -0
  660. icdev/tools/compliance/narrative_generator.py +1013 -0
  661. icdev/tools/compliance/nist_800_207_assessor.py +191 -0
  662. icdev/tools/compliance/nist_ai_600_1_assessor.py +188 -0
  663. icdev/tools/compliance/nist_ai_rmf_assessor.py +110 -0
  664. icdev/tools/compliance/nist_lookup.py +245 -0
  665. icdev/tools/compliance/omb_m25_21_assessor.py +228 -0
  666. icdev/tools/compliance/omb_m26_04_assessor.py +188 -0
  667. icdev/tools/compliance/oscal_catalog_adapter.py +395 -0
  668. icdev/tools/compliance/oscal_generator.py +2170 -0
  669. icdev/tools/compliance/oscal_tools.py +1182 -0
  670. icdev/tools/compliance/owasp_agentic_assessor.py +226 -0
  671. icdev/tools/compliance/owasp_asi_assessor.py +200 -0
  672. icdev/tools/compliance/owasp_llm_assessor.py +244 -0
  673. icdev/tools/compliance/pci_dss_assessor.py +80 -0
  674. icdev/tools/compliance/pi_compliance_tracker.py +1461 -0
  675. icdev/tools/compliance/poam_generator.py +405 -0
  676. icdev/tools/compliance/resolve_marking.py +283 -0
  677. icdev/tools/compliance/sbd_assessor.py +2068 -0
  678. icdev/tools/compliance/sbd_report_generator.py +1236 -0
  679. icdev/tools/compliance/sbom_generator.py +1008 -0
  680. icdev/tools/compliance/siem_config_generator.py +674 -0
  681. icdev/tools/compliance/slsa_attestation_generator.py +490 -0
  682. icdev/tools/compliance/soc2_assessor.py +77 -0
  683. icdev/tools/compliance/ssp_generator.py +573 -0
  684. icdev/tools/compliance/stig_checker.py +727 -0
  685. icdev/tools/compliance/swft_evidence_bundler.py +337 -0
  686. icdev/tools/compliance/system_card_generator.py +309 -0
  687. icdev/tools/compliance/traceability_matrix.py +1281 -0
  688. icdev/tools/compliance/universal_classification_manager.py +1172 -0
  689. icdev/tools/compliance/xacta/__init__.py +2 -0
  690. icdev/tools/compliance/xacta/xacta_client.py +449 -0
  691. icdev/tools/compliance/xacta/xacta_export.py +557 -0
  692. icdev/tools/compliance/xacta/xacta_sync.py +333 -0
  693. icdev/tools/compliance/xai_assessor.py +231 -0
  694. icdev/tools/dashboard/__init__.py +1 -0
  695. icdev/tools/dashboard/api/__init__.py +1 -0
  696. icdev/tools/dashboard/api/_pipeline_state.py +17 -0
  697. icdev/tools/dashboard/api/activity.py +206 -0
  698. icdev/tools/dashboard/api/admin.py +176 -0
  699. icdev/tools/dashboard/api/agents.py +53 -0
  700. icdev/tools/dashboard/api/ai_accountability.py +163 -0
  701. icdev/tools/dashboard/api/ai_transparency.py +198 -0
  702. icdev/tools/dashboard/api/audit.py +58 -0
  703. icdev/tools/dashboard/api/batch.py +666 -0
  704. icdev/tools/dashboard/api/chat.py +241 -0
  705. icdev/tools/dashboard/api/cicd.py +219 -0
  706. icdev/tools/dashboard/api/code_quality.py +223 -0
  707. icdev/tools/dashboard/api/compliance.py +171 -0
  708. icdev/tools/dashboard/api/cpmp.py +915 -0
  709. icdev/tools/dashboard/api/diagrams.py +65 -0
  710. icdev/tools/dashboard/api/events.py +250 -0
  711. icdev/tools/dashboard/api/evidence.py +99 -0
  712. icdev/tools/dashboard/api/fedramp_20x.py +77 -0
  713. icdev/tools/dashboard/api/govcon.py +1095 -0
  714. icdev/tools/dashboard/api/intake.py +1171 -0
  715. icdev/tools/dashboard/api/lineage.py +163 -0
  716. icdev/tools/dashboard/api/metrics.py +155 -0
  717. icdev/tools/dashboard/api/nlq.py +72 -0
  718. icdev/tools/dashboard/api/orchestration.py +472 -0
  719. icdev/tools/dashboard/api/oscal.py +183 -0
  720. icdev/tools/dashboard/api/prod_audit.py +183 -0
  721. icdev/tools/dashboard/api/projects.py +191 -0
  722. icdev/tools/dashboard/api/proposals.py +1084 -0
  723. icdev/tools/dashboard/api/traces.py +363 -0
  724. icdev/tools/dashboard/api/usage.py +234 -0
  725. icdev/tools/dashboard/app.py +1986 -0
  726. icdev/tools/dashboard/auth.py +500 -0
  727. icdev/tools/dashboard/byok.py +245 -0
  728. icdev/tools/dashboard/chat_manager.py +675 -0
  729. icdev/tools/dashboard/config.py +116 -0
  730. icdev/tools/dashboard/diagram_definitions.py +642 -0
  731. icdev/tools/dashboard/nlq_processor.py +323 -0
  732. icdev/tools/dashboard/phase_loader.py +136 -0
  733. icdev/tools/dashboard/sse_manager.py +89 -0
  734. icdev/tools/dashboard/state_tracker.py +267 -0
  735. icdev/tools/dashboard/static/css/style.css +706 -0
  736. icdev/tools/dashboard/static/css/ux.css +2047 -0
  737. icdev/tools/dashboard/static/js/activity.js +322 -0
  738. icdev/tools/dashboard/static/js/api.js +161 -0
  739. icdev/tools/dashboard/static/js/batch.js +814 -0
  740. icdev/tools/dashboard/static/js/charts.js +618 -0
  741. icdev/tools/dashboard/static/js/chat.js +1514 -0
  742. icdev/tools/dashboard/static/js/kanban.js +113 -0
  743. icdev/tools/dashboard/static/js/live.js +569 -0
  744. icdev/tools/dashboard/static/js/mermaid-icdev.js +332 -0
  745. icdev/tools/dashboard/static/js/proposals.js +588 -0
  746. icdev/tools/dashboard/static/js/shortcuts.js +544 -0
  747. icdev/tools/dashboard/static/js/tables.js +652 -0
  748. icdev/tools/dashboard/static/js/tour.js +524 -0
  749. icdev/tools/dashboard/static/js/ux.js +942 -0
  750. icdev/tools/dashboard/templates/404.html +10 -0
  751. icdev/tools/dashboard/templates/activity.html +80 -0
  752. icdev/tools/dashboard/templates/admin/users.html +144 -0
  753. icdev/tools/dashboard/templates/ai_accountability.html +235 -0
  754. icdev/tools/dashboard/templates/ai_transparency.html +263 -0
  755. icdev/tools/dashboard/templates/base.html +104 -0
  756. icdev/tools/dashboard/templates/batch.html +23 -0
  757. icdev/tools/dashboard/templates/chat.html +332 -0
  758. icdev/tools/dashboard/templates/children.html +149 -0
  759. icdev/tools/dashboard/templates/cicd.html +253 -0
  760. icdev/tools/dashboard/templates/code_quality.html +214 -0
  761. icdev/tools/dashboard/templates/cpmp/cor_detail.html +220 -0
  762. icdev/tools/dashboard/templates/cpmp/cor_portal.html +91 -0
  763. icdev/tools/dashboard/templates/cpmp/deliverable_detail.html +197 -0
  764. icdev/tools/dashboard/templates/cpmp/detail.html +578 -0
  765. icdev/tools/dashboard/templates/cpmp/portfolio.html +202 -0
  766. icdev/tools/dashboard/templates/dev_profiles.html +304 -0
  767. icdev/tools/dashboard/templates/diagrams.html +224 -0
  768. icdev/tools/dashboard/templates/events/timeline.html +232 -0
  769. icdev/tools/dashboard/templates/evidence.html +134 -0
  770. icdev/tools/dashboard/templates/fedramp_20x.html +207 -0
  771. icdev/tools/dashboard/templates/gateway.html +244 -0
  772. icdev/tools/dashboard/templates/govcon/capabilities.html +135 -0
  773. icdev/tools/dashboard/templates/govcon/pipeline.html +214 -0
  774. icdev/tools/dashboard/templates/govcon/requirements.html +120 -0
  775. icdev/tools/dashboard/templates/index.html +254 -0
  776. icdev/tools/dashboard/templates/lineage.html +141 -0
  777. icdev/tools/dashboard/templates/login.html +51 -0
  778. icdev/tools/dashboard/templates/monitoring/overview.html +193 -0
  779. icdev/tools/dashboard/templates/orchestration/dashboard.html +545 -0
  780. icdev/tools/dashboard/templates/oscal.html +263 -0
  781. icdev/tools/dashboard/templates/phases.html +150 -0
  782. icdev/tools/dashboard/templates/prod_audit.html +280 -0
  783. icdev/tools/dashboard/templates/profile.html +183 -0
  784. icdev/tools/dashboard/templates/projects/detail.html +583 -0
  785. icdev/tools/dashboard/templates/projects/list.html +47 -0
  786. icdev/tools/dashboard/templates/proposals/detail.html +1253 -0
  787. icdev/tools/dashboard/templates/proposals/list.html +179 -0
  788. icdev/tools/dashboard/templates/proposals/section_detail.html +193 -0
  789. icdev/tools/dashboard/templates/provenance.html +181 -0
  790. icdev/tools/dashboard/templates/query/nlq.html +234 -0
  791. icdev/tools/dashboard/templates/quick_paths.html +69 -0
  792. icdev/tools/dashboard/templates/traces.html +155 -0
  793. icdev/tools/dashboard/templates/translation_detail.html +199 -0
  794. icdev/tools/dashboard/templates/translations.html +162 -0
  795. icdev/tools/dashboard/templates/usage.html +225 -0
  796. icdev/tools/dashboard/templates/wizard.html +539 -0
  797. icdev/tools/dashboard/templates/xai.html +208 -0
  798. icdev/tools/dashboard/ux_helpers.py +962 -0
  799. icdev/tools/dashboard/websocket.py +81 -0
  800. icdev/tools/db/__init__.py +1 -0
  801. icdev/tools/db/backup.py +312 -0
  802. icdev/tools/db/backup_manager.py +832 -0
  803. icdev/tools/db/init_icdev_db.py +5900 -0
  804. icdev/tools/db/migrate.py +178 -0
  805. icdev/tools/db/migration_runner.py +549 -0
  806. icdev/tools/db/migrations/001_baseline/meta.json +9 -0
  807. icdev/tools/db/migrations/001_baseline/up.py +68 -0
  808. icdev/tools/db/migrations/002_memory_enhancements/down.sql +8 -0
  809. icdev/tools/db/migrations/002_memory_enhancements/meta.json +9 -0
  810. icdev/tools/db/migrations/002_memory_enhancements/up.py +118 -0
  811. icdev/tools/db/migrations/003_dev_profiles/meta.json +8 -0
  812. icdev/tools/db/migrations/003_dev_profiles/up.py +93 -0
  813. icdev/tools/db/migrations/004_innovation_engine/down.py +19 -0
  814. icdev/tools/db/migrations/004_innovation_engine/up.py +227 -0
  815. icdev/tools/db/migrations/005_phase_37_ai_security/down.py +19 -0
  816. icdev/tools/db/migrations/005_phase_37_ai_security/up.py +258 -0
  817. icdev/tools/db/migrations/006_phase_36_evolution/down.py +21 -0
  818. icdev/tools/db/migrations/006_phase_36_evolution/up.py +323 -0
  819. icdev/tools/db/migrations/007_phase_38_cloud/down.py +14 -0
  820. icdev/tools/db/migrations/007_phase_38_cloud/up.py +110 -0
  821. icdev/tools/db/migrations/008_phase36_37_integration/up.py +55 -0
  822. icdev/tools/db/migrations/__init__.py +2 -0
  823. icdev/tools/devsecops/__init__.py +2 -0
  824. icdev/tools/devsecops/attestation_manager.py +458 -0
  825. icdev/tools/devsecops/network_segmentation_generator.py +614 -0
  826. icdev/tools/devsecops/pdp_config_generator.py +1256 -0
  827. icdev/tools/devsecops/pipeline_security_generator.py +484 -0
  828. icdev/tools/devsecops/policy_generator.py +653 -0
  829. icdev/tools/devsecops/profile_manager.py +388 -0
  830. icdev/tools/devsecops/service_mesh_generator.py +1073 -0
  831. icdev/tools/devsecops/zta_maturity_scorer.py +368 -0
  832. icdev/tools/devsecops/zta_terraform_generator.py +1303 -0
  833. icdev/tools/dx/__init__.py +3 -0
  834. icdev/tools/dx/companion.py +266 -0
  835. icdev/tools/dx/instruction_generator.py +753 -0
  836. icdev/tools/dx/mcp_config_generator.py +282 -0
  837. icdev/tools/dx/skill_translator.py +425 -0
  838. icdev/tools/dx/tool_detector.py +144 -0
  839. icdev/tools/extensions/__init__.py +21 -0
  840. icdev/tools/extensions/builtins/010_ai_governance_chat.py +277 -0
  841. icdev/tools/extensions/builtins/__init__.py +2 -0
  842. icdev/tools/extensions/extension_manager.py +455 -0
  843. icdev/tools/infra/__init__.py +1 -0
  844. icdev/tools/infra/ansible_generator.py +869 -0
  845. icdev/tools/infra/dockerfile_generator.py +361 -0
  846. icdev/tools/infra/infra_status.py +393 -0
  847. icdev/tools/infra/ironbank_metadata_generator.py +411 -0
  848. icdev/tools/infra/k8s_generator.py +1002 -0
  849. icdev/tools/infra/pipeline_generator.py +832 -0
  850. icdev/tools/infra/rollback.py +400 -0
  851. icdev/tools/infra/terraform_generator.py +1142 -0
  852. icdev/tools/infra/terraform_generator_azure.py +1254 -0
  853. icdev/tools/infra/terraform_generator_gcp.py +953 -0
  854. icdev/tools/infra/terraform_generator_ibm.py +360 -0
  855. icdev/tools/infra/terraform_generator_oci.py +919 -0
  856. icdev/tools/infra/terraform_generator_onprem.py +319 -0
  857. icdev/tools/innovation/__init__.py +8 -0
  858. icdev/tools/innovation/competitive_intel.py +492 -0
  859. icdev/tools/innovation/innovation_manager.py +681 -0
  860. icdev/tools/innovation/introspective_analyzer.py +774 -0
  861. icdev/tools/innovation/register_external_patterns.py +440 -0
  862. icdev/tools/innovation/signal_ranker.py +1038 -0
  863. icdev/tools/innovation/solution_generator.py +697 -0
  864. icdev/tools/innovation/standards_monitor.py +466 -0
  865. icdev/tools/innovation/trend_detector.py +1046 -0
  866. icdev/tools/innovation/triage_engine.py +1149 -0
  867. icdev/tools/innovation/web_scanner.py +894 -0
  868. icdev/tools/installer/__init__.py +1 -0
  869. icdev/tools/installer/compliance_configurator.py +637 -0
  870. icdev/tools/installer/installer.py +1711 -0
  871. icdev/tools/installer/module_registry.py +805 -0
  872. icdev/tools/installer/platform_setup.py +961 -0
  873. icdev/tools/integration/__init__.py +2 -0
  874. icdev/tools/integration/approval_manager.py +561 -0
  875. icdev/tools/integration/doors_exporter.py +627 -0
  876. icdev/tools/integration/gitlab_connector.py +784 -0
  877. icdev/tools/integration/jira_connector.py +774 -0
  878. icdev/tools/integration/servicenow_connector.py +693 -0
  879. icdev/tools/knowledge/__init__.py +1 -0
  880. icdev/tools/knowledge/knowledge_ingest.py +293 -0
  881. icdev/tools/knowledge/pattern_detector.py +693 -0
  882. icdev/tools/knowledge/recommendation_engine.py +461 -0
  883. icdev/tools/knowledge/self_heal_analyzer.py +504 -0
  884. icdev/tools/llm/__init__.py +72 -0
  885. icdev/tools/llm/anthropic_provider.py +170 -0
  886. icdev/tools/llm/azure_openai_provider.py +338 -0
  887. icdev/tools/llm/bedrock_provider.py +315 -0
  888. icdev/tools/llm/embedding_provider.py +438 -0
  889. icdev/tools/llm/gemini_provider.py +381 -0
  890. icdev/tools/llm/ibm_watsonx_provider.py +232 -0
  891. icdev/tools/llm/oci_genai_provider.py +462 -0
  892. icdev/tools/llm/ollama_provider.py +340 -0
  893. icdev/tools/llm/openai_provider.py +225 -0
  894. icdev/tools/llm/provider.py +355 -0
  895. icdev/tools/llm/provider_sdk.py +175 -0
  896. icdev/tools/llm/router.py +780 -0
  897. icdev/tools/llm/vertex_ai_provider.py +374 -0
  898. icdev/tools/maintenance/__init__.py +2 -0
  899. icdev/tools/maintenance/dependency_scanner.py +1030 -0
  900. icdev/tools/maintenance/maintenance_auditor.py +815 -0
  901. icdev/tools/maintenance/remediation_engine.py +966 -0
  902. icdev/tools/maintenance/vulnerability_checker.py +987 -0
  903. icdev/tools/mbse/__init__.py +3 -0
  904. icdev/tools/mbse/des_assessor.py +1186 -0
  905. icdev/tools/mbse/des_report_generator.py +800 -0
  906. icdev/tools/mbse/diagram_extractor.py +811 -0
  907. icdev/tools/mbse/digital_thread.py +1665 -0
  908. icdev/tools/mbse/model_code_generator.py +1122 -0
  909. icdev/tools/mbse/model_control_mapper.py +420 -0
  910. icdev/tools/mbse/pi_model_tracker.py +1093 -0
  911. icdev/tools/mbse/reqif_parser.py +1483 -0
  912. icdev/tools/mbse/sync_engine.py +1805 -0
  913. icdev/tools/mbse/xmi_parser.py +1573 -0
  914. icdev/tools/mcp/__init__.py +1 -0
  915. icdev/tools/mcp/base_server.py +535 -0
  916. icdev/tools/mcp/builder_server.py +725 -0
  917. icdev/tools/mcp/compliance_server.py +1407 -0
  918. icdev/tools/mcp/context_indexer.py +199 -0
  919. icdev/tools/mcp/context_server.py +305 -0
  920. icdev/tools/mcp/core_server.py +679 -0
  921. icdev/tools/mcp/devsecops_server.py +432 -0
  922. icdev/tools/mcp/gap_handlers.py +1079 -0
  923. icdev/tools/mcp/gateway_server.py +339 -0
  924. icdev/tools/mcp/generate_registry.py +623 -0
  925. icdev/tools/mcp/infra_server.py +264 -0
  926. icdev/tools/mcp/innovation_server.py +316 -0
  927. icdev/tools/mcp/integration_server.py +527 -0
  928. icdev/tools/mcp/knowledge_server.py +429 -0
  929. icdev/tools/mcp/maintenance_server.py +248 -0
  930. icdev/tools/mcp/marketplace_server.py +499 -0
  931. icdev/tools/mcp/mbse_server.py +398 -0
  932. icdev/tools/mcp/modernization_server.py +496 -0
  933. icdev/tools/mcp/observability_server.py +354 -0
  934. icdev/tools/mcp/requirements_server.py +415 -0
  935. icdev/tools/mcp/simulation_server.py +468 -0
  936. icdev/tools/mcp/standalone/__init__.py +2 -0
  937. icdev/tools/mcp/standalone/builder.py +59 -0
  938. icdev/tools/mcp/standalone/compliance.py +59 -0
  939. icdev/tools/mcp/standalone/core.py +59 -0
  940. icdev/tools/mcp/standalone/knowledge.py +59 -0
  941. icdev/tools/mcp/standalone/maintenance.py +59 -0
  942. icdev/tools/mcp/supply_chain_server.py +476 -0
  943. icdev/tools/mcp/tool_registry.py +2008 -0
  944. icdev/tools/mcp/unified_server.py +158 -0
  945. icdev/tools/memory/__init__.py +2 -0
  946. icdev/tools/memory/auto_capture.py +347 -0
  947. icdev/tools/memory/embed_memory.py +158 -0
  948. icdev/tools/memory/history_compressor.py +334 -0
  949. icdev/tools/memory/hybrid_search.py +236 -0
  950. icdev/tools/memory/maintenance_cron.py +289 -0
  951. icdev/tools/memory/memory_consolidation.py +444 -0
  952. icdev/tools/memory/memory_db.py +133 -0
  953. icdev/tools/memory/memory_read.py +102 -0
  954. icdev/tools/memory/memory_write.py +222 -0
  955. icdev/tools/memory/semantic_search.py +139 -0
  956. icdev/tools/memory/time_decay.py +435 -0
  957. icdev/tools/modernization/__init__.py +3 -0
  958. icdev/tools/modernization/architecture_extractor.py +734 -0
  959. icdev/tools/modernization/compliance_bridge.py +1499 -0
  960. icdev/tools/modernization/db_migration_planner.py +1385 -0
  961. icdev/tools/modernization/doc_generator.py +1428 -0
  962. icdev/tools/modernization/framework_migrator.py +1525 -0
  963. icdev/tools/modernization/legacy_analyzer.py +1948 -0
  964. icdev/tools/modernization/migration_code_generator.py +1639 -0
  965. icdev/tools/modernization/migration_report_generator.py +1653 -0
  966. icdev/tools/modernization/migration_tracker.py +1726 -0
  967. icdev/tools/modernization/monolith_decomposer.py +1508 -0
  968. icdev/tools/modernization/seven_r_assessor.py +1658 -0
  969. icdev/tools/modernization/strangler_fig_manager.py +1705 -0
  970. icdev/tools/modernization/ui_analyzer.py +771 -0
  971. icdev/tools/modernization/version_migrator.py +1392 -0
  972. icdev/tools/monitor/__init__.py +1 -0
  973. icdev/tools/monitor/alert_correlator.py +495 -0
  974. icdev/tools/monitor/auto_resolver.py +612 -0
  975. icdev/tools/monitor/health_checker.py +509 -0
  976. icdev/tools/monitor/heartbeat_daemon.py +792 -0
  977. icdev/tools/monitor/log_analyzer.py +516 -0
  978. icdev/tools/monitor/metric_collector.py +496 -0
  979. icdev/tools/mosa/__init__.py +10 -0
  980. icdev/tools/mosa/icd_generator.py +370 -0
  981. icdev/tools/mosa/modular_design_analyzer.py +683 -0
  982. icdev/tools/mosa/mosa_code_enforcer.py +349 -0
  983. icdev/tools/mosa/tsp_generator.py +265 -0
  984. icdev/tools/observability/__init__.py +100 -0
  985. icdev/tools/observability/genai_attributes.py +88 -0
  986. icdev/tools/observability/instrumentation.py +140 -0
  987. icdev/tools/observability/mlflow_exporter.py +194 -0
  988. icdev/tools/observability/otel_tracer.py +168 -0
  989. icdev/tools/observability/provenance/__init__.py +3 -0
  990. icdev/tools/observability/provenance/prov_recorder.py +324 -0
  991. icdev/tools/observability/shap/__init__.py +3 -0
  992. icdev/tools/observability/shap/agent_shap.py +275 -0
  993. icdev/tools/observability/sqlite_tracer.py +361 -0
  994. icdev/tools/observability/trace_context.py +205 -0
  995. icdev/tools/observability/tracer.py +230 -0
  996. icdev/tools/orchestration/__init__.py +2 -0
  997. icdev/tools/orchestration/workflow_composer.py +361 -0
  998. icdev/tools/project/__init__.py +1 -0
  999. icdev/tools/project/manifest_loader.py +418 -0
  1000. icdev/tools/project/project_create.py +350 -0
  1001. icdev/tools/project/project_list.py +174 -0
  1002. icdev/tools/project/project_scaffold.py +1715 -0
  1003. icdev/tools/project/project_status.py +479 -0
  1004. icdev/tools/project/session_context_builder.py +757 -0
  1005. icdev/tools/project/validate_manifest.py +55 -0
  1006. icdev/tools/registry/__init__.py +10 -0
  1007. icdev/tools/registry/absorption_engine.py +832 -0
  1008. icdev/tools/registry/capability_evaluator.py +668 -0
  1009. icdev/tools/registry/child_registry.py +617 -0
  1010. icdev/tools/registry/cross_pollinator.py +1065 -0
  1011. icdev/tools/registry/genome_manager.py +671 -0
  1012. icdev/tools/registry/learning_collector.py +912 -0
  1013. icdev/tools/registry/propagation_manager.py +942 -0
  1014. icdev/tools/registry/staging_manager.py +742 -0
  1015. icdev/tools/registry/telemetry_collector.py +423 -0
  1016. icdev/tools/requirements/__init__.py +1 -0
  1017. icdev/tools/requirements/ai_governance_scorer.py +208 -0
  1018. icdev/tools/requirements/boundary_analyzer.py +1293 -0
  1019. icdev/tools/requirements/clarification_engine.py +618 -0
  1020. icdev/tools/requirements/complexity_scorer.py +387 -0
  1021. icdev/tools/requirements/consistency_analyzer.py +803 -0
  1022. icdev/tools/requirements/constitution_manager.py +605 -0
  1023. icdev/tools/requirements/decomposition_engine.py +778 -0
  1024. icdev/tools/requirements/document_extractor.py +1016 -0
  1025. icdev/tools/requirements/elicitation_techniques.py +519 -0
  1026. icdev/tools/requirements/gap_detector.py +271 -0
  1027. icdev/tools/requirements/intake_engine.py +2188 -0
  1028. icdev/tools/requirements/prd_generator.py +847 -0
  1029. icdev/tools/requirements/prd_validator.py +595 -0
  1030. icdev/tools/requirements/readiness_scorer.py +313 -0
  1031. icdev/tools/requirements/spec_organizer.py +1029 -0
  1032. icdev/tools/requirements/spec_quality_checker.py +1097 -0
  1033. icdev/tools/requirements/traceability_builder.py +579 -0
  1034. icdev/tools/resilience/__init__.py +34 -0
  1035. icdev/tools/resilience/circuit_breaker.py +340 -0
  1036. icdev/tools/resilience/correlation.py +150 -0
  1037. icdev/tools/resilience/errors.py +81 -0
  1038. icdev/tools/resilience/retry.py +95 -0
  1039. icdev/tools/schemas/__init__.py +27 -0
  1040. icdev/tools/schemas/chat.py +61 -0
  1041. icdev/tools/schemas/compliance.py +56 -0
  1042. icdev/tools/schemas/core.py +85 -0
  1043. icdev/tools/schemas/innovation.py +37 -0
  1044. icdev/tools/schemas/validation.py +109 -0
  1045. icdev/tools/sdk/__init__.py +3 -0
  1046. icdev/tools/sdk/icdev_client.py +218 -0
  1047. icdev/tools/security/__init__.py +1 -0
  1048. icdev/tools/security/agent_output_validator.py +330 -0
  1049. icdev/tools/security/agent_trust_scorer.py +466 -0
  1050. icdev/tools/security/ai_bom_generator.py +725 -0
  1051. icdev/tools/security/ai_telemetry_logger.py +469 -0
  1052. icdev/tools/security/atlas_red_team.py +543 -0
  1053. icdev/tools/security/code_pattern_scanner.py +378 -0
  1054. icdev/tools/security/confabulation_detector.py +271 -0
  1055. icdev/tools/security/container_scanner.py +491 -0
  1056. icdev/tools/security/dependency_auditor.py +944 -0
  1057. icdev/tools/security/endpoint_security_scanner.py +579 -0
  1058. icdev/tools/security/mcp_tool_authorizer.py +243 -0
  1059. icdev/tools/security/prompt_injection_detector.py +737 -0
  1060. icdev/tools/security/sast_runner.py +948 -0
  1061. icdev/tools/security/secret_detector.py +378 -0
  1062. icdev/tools/security/tool_chain_validator.py +357 -0
  1063. icdev/tools/security/vuln_scanner.py +539 -0
  1064. icdev/tools/simulation/__init__.py +2 -0
  1065. icdev/tools/simulation/coa_generator.py +1552 -0
  1066. icdev/tools/simulation/monte_carlo.py +758 -0
  1067. icdev/tools/simulation/scenario_manager.py +1073 -0
  1068. icdev/tools/simulation/simulation_engine.py +1104 -0
  1069. icdev/tools/supply_chain/__init__.py +2 -0
  1070. icdev/tools/supply_chain/cve_triager.py +705 -0
  1071. icdev/tools/supply_chain/dependency_graph.py +645 -0
  1072. icdev/tools/supply_chain/isa_manager.py +540 -0
  1073. icdev/tools/supply_chain/scrm_assessor.py +546 -0
  1074. icdev/tools/testing/__init__.py +2 -0
  1075. icdev/tools/testing/acceptance_validator.py +411 -0
  1076. icdev/tools/testing/claude_dir_validator.py +831 -0
  1077. icdev/tools/testing/data_types.py +199 -0
  1078. icdev/tools/testing/e2e_runner.py +715 -0
  1079. icdev/tools/testing/fuzz_cli.py +306 -0
  1080. icdev/tools/testing/health_check.py +483 -0
  1081. icdev/tools/testing/platform_check.py +143 -0
  1082. icdev/tools/testing/production_audit.py +1862 -0
  1083. icdev/tools/testing/production_remediate.py +804 -0
  1084. icdev/tools/testing/screenshot_validator.py +539 -0
  1085. icdev/tools/testing/smoke_test.py +283 -0
  1086. icdev/tools/testing/test_agent_models.py +117 -0
  1087. icdev/tools/testing/test_orchestrator.py +957 -0
  1088. icdev/tools/testing/utils.py +229 -0
  1089. icdev/tools/translation/__init__.py +17 -0
  1090. icdev/tools/translation/code_translator.py +550 -0
  1091. icdev/tools/translation/dependency_mapper.py +277 -0
  1092. icdev/tools/translation/feature_map.py +395 -0
  1093. icdev/tools/translation/project_assembler.py +439 -0
  1094. icdev/tools/translation/source_extractor.py +609 -0
  1095. icdev/tools/translation/test_translator.py +333 -0
  1096. icdev/tools/translation/translation_manager.py +582 -0
  1097. icdev/tools/translation/translation_validator.py +662 -0
  1098. icdev/tools/translation/type_checker.py +371 -0
  1099. icdev-1.0.0.dist-info/METADATA +868 -0
  1100. icdev-1.0.0.dist-info/RECORD +1105 -0
  1101. icdev-1.0.0.dist-info/WHEEL +5 -0
  1102. icdev-1.0.0.dist-info/entry_points.txt +9 -0
  1103. icdev-1.0.0.dist-info/licenses/LICENSE +254 -0
  1104. icdev-1.0.0.dist-info/licenses/NOTICE +268 -0
  1105. icdev-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,1726 @@
1
+ # [TEMPLATE: CUI // SP-CTI]
2
+ #!/usr/bin/env python3
3
+ """SAFe PI-Cadenced Migration Progress Tracker for ICDEV DoD Modernization.
4
+
5
+ Tracks migration progress across Program Increments (PIs) with velocity
6
+ metrics, burndown projections, compliance gate checks, and detailed PI
7
+ reporting. Integrates with the ICDEV operational database to snapshot
8
+ migration state, compute task-completion velocity, project remaining work,
9
+ and enforce ATO compliance gates at PI boundaries.
10
+
11
+ All computation is deterministic — no LLM calls, no external network access.
12
+ Uses Python stdlib only.
13
+
14
+ Usage:
15
+ # Create a PI snapshot
16
+ python tools/modernization/migration_tracker.py \\
17
+ --plan-id MP-001 --snapshot --pi PI-25.3 --type pi_start
18
+
19
+ # View velocity metrics
20
+ python tools/modernization/migration_tracker.py --plan-id MP-001 --velocity
21
+
22
+ # View burndown projection
23
+ python tools/modernization/migration_tracker.py --plan-id MP-001 --burndown
24
+
25
+ # Compare two PIs
26
+ python tools/modernization/migration_tracker.py \\
27
+ --plan-id MP-001 --compare --from-pi PI-25.2 --to-pi PI-25.3
28
+
29
+ # Assign tasks to a PI
30
+ python tools/modernization/migration_tracker.py \\
31
+ --plan-id MP-001 --assign --pi PI-25.3 --tasks T-001,T-002,T-003
32
+
33
+ # Generate PI migration report
34
+ python tools/modernization/migration_tracker.py \\
35
+ --plan-id MP-001 --pi-report --pi PI-25.3 --output-dir .tmp/reports
36
+
37
+ # Check compliance gate
38
+ python tools/modernization/migration_tracker.py \\
39
+ --plan-id MP-001 --gate --pi PI-25.3
40
+
41
+ # Update a task
42
+ python tools/modernization/migration_tracker.py \\
43
+ --plan-id MP-001 --update-task --task-id T-001 --status completed --hours 8
44
+
45
+ # Show dashboard
46
+ python tools/modernization/migration_tracker.py --plan-id MP-001 --dashboard
47
+
48
+ Classification: CUI // SP-CTI
49
+ Environment: AWS GovCloud (us-gov-west-1)
50
+ Compliance: NIST 800-53 Rev 5 / RMF
51
+ """
52
+
53
+ import argparse
54
+ import json
55
+ import math
56
+ import sqlite3
57
+ import sys
58
+ from datetime import datetime, timezone
59
+ from pathlib import Path
60
+ from icdev._paths import get_project_root
61
+
62
+ # ---------------------------------------------------------------------------
63
+ # Paths
64
+ # ---------------------------------------------------------------------------
65
+ BASE_DIR = get_project_root()
66
+ DB_PATH = BASE_DIR / "data" / "icdev.db"
67
+
68
+ # ---------------------------------------------------------------------------
69
+ # Constants
70
+ # ---------------------------------------------------------------------------
71
+ VALID_SNAPSHOT_TYPES = ("pi_start", "pi_end", "milestone", "manual")
72
+ VALID_TASK_STATUSES = ("pending", "in_progress", "completed", "blocked", "skipped")
73
+ COMPLIANCE_THRESHOLD = 0.95
74
+
75
+
76
+ # ---------------------------------------------------------------------------
77
+ # Database helper
78
+ # ---------------------------------------------------------------------------
79
+
80
+ def _get_db(db_path=None):
81
+ """Return a sqlite3 connection with Row factory enabled.
82
+
83
+ Args:
84
+ db_path: Optional path override for the database file.
85
+
86
+ Returns:
87
+ sqlite3.Connection with row_factory = sqlite3.Row.
88
+ """
89
+ path = db_path or DB_PATH
90
+ conn = sqlite3.connect(str(path))
91
+ conn.row_factory = sqlite3.Row
92
+ conn.execute("PRAGMA journal_mode=WAL")
93
+ conn.execute("PRAGMA foreign_keys=ON")
94
+ return conn
95
+
96
+
97
+ def _now_iso():
98
+ """Return current UTC timestamp in ISO 8601 format."""
99
+ return datetime.now(timezone.utc).isoformat()
100
+
101
+
102
+ def _log_audit(conn, event_type, actor, action, project_id=None, details=None):
103
+ """Write an append-only audit trail entry via the provided connection.
104
+
105
+ This function writes directly to the audit_trail table to avoid
106
+ circular imports with the audit_logger module.
107
+
108
+ Args:
109
+ conn: Active sqlite3 connection.
110
+ event_type: Audit event type string.
111
+ actor: Identity of the acting agent/user.
112
+ action: Human-readable description of the action.
113
+ project_id: Optional project identifier.
114
+ details: Optional dict of additional detail data.
115
+ """
116
+ try:
117
+ conn.execute(
118
+ """INSERT INTO audit_trail
119
+ (project_id, event_type, actor, action, details, classification)
120
+ VALUES (?, ?, ?, ?, ?, ?)""",
121
+ (
122
+ project_id,
123
+ event_type,
124
+ actor,
125
+ action,
126
+ json.dumps(details) if details else None,
127
+ "CUI",
128
+ ),
129
+ )
130
+ except sqlite3.OperationalError:
131
+ # Audit table may not exist in test environments — silently skip
132
+ pass
133
+
134
+
135
+ # ============================================================================
136
+ # 1. create_pi_migration_snapshot
137
+ # ============================================================================
138
+
139
+ def create_pi_migration_snapshot(plan_id, pi_number, snapshot_type="manual",
140
+ notes=None, db_path=None):
141
+ """Snapshot the current migration state for a given plan and PI.
142
+
143
+ Queries migration_tasks for the plan, counts statuses, counts migrated
144
+ components/APIs/tables, computes test coverage and compliance score,
145
+ then INSERTs a row into migration_progress.
146
+
147
+ Args:
148
+ plan_id: Migration plan identifier.
149
+ pi_number: PI label (e.g. 'PI-25.3').
150
+ snapshot_type: One of 'pi_start', 'pi_end', 'milestone', 'manual'.
151
+ notes: Optional free-text notes for the snapshot.
152
+ db_path: Optional database path override.
153
+
154
+ Returns:
155
+ Dict containing all snapshot fields.
156
+ """
157
+ if snapshot_type not in VALID_SNAPSHOT_TYPES:
158
+ raise ValueError(
159
+ f"Invalid snapshot_type '{snapshot_type}'. "
160
+ f"Valid: {VALID_SNAPSHOT_TYPES}"
161
+ )
162
+
163
+ conn = _get_db(db_path)
164
+ try:
165
+ # -- Task status counts --
166
+ rows = conn.execute(
167
+ "SELECT status, COUNT(*) as cnt FROM migration_tasks "
168
+ "WHERE plan_id = ? GROUP BY status",
169
+ (plan_id,),
170
+ ).fetchall()
171
+
172
+ status_counts = {s: 0 for s in VALID_TASK_STATUSES}
173
+ for r in rows:
174
+ status_counts[r["status"]] = r["cnt"]
175
+
176
+ tasks_total = sum(status_counts.values())
177
+ tasks_completed = status_counts.get("completed", 0)
178
+ tasks_in_progress = status_counts.get("in_progress", 0)
179
+ tasks_blocked = status_counts.get("blocked", 0)
180
+
181
+ # -- Components migrated (extract_service tasks completed) --
182
+ components_migrated = conn.execute(
183
+ "SELECT COUNT(*) as cnt FROM migration_tasks "
184
+ "WHERE plan_id = ? AND task_type = 'extract_service' "
185
+ "AND status = 'completed'",
186
+ (plan_id,),
187
+ ).fetchone()["cnt"]
188
+
189
+ # -- Get total components from legacy_components for plan's app --
190
+ plan_row = conn.execute(
191
+ "SELECT legacy_app_id FROM migration_plans WHERE id = ?",
192
+ (plan_id,),
193
+ ).fetchone()
194
+ legacy_app_id = plan_row["legacy_app_id"] if plan_row else None
195
+
196
+ components_remaining = 0
197
+ if legacy_app_id:
198
+ total_comps = conn.execute(
199
+ "SELECT COUNT(*) as cnt FROM legacy_components "
200
+ "WHERE legacy_app_id = ?",
201
+ (legacy_app_id,),
202
+ ).fetchone()["cnt"]
203
+ components_remaining = max(0, total_comps - components_migrated)
204
+
205
+ # -- APIs migrated (create_api tasks completed) --
206
+ apis_migrated = conn.execute(
207
+ "SELECT COUNT(*) as cnt FROM migration_tasks "
208
+ "WHERE plan_id = ? AND task_type = 'create_api' "
209
+ "AND status = 'completed'",
210
+ (plan_id,),
211
+ ).fetchone()["cnt"]
212
+
213
+ # -- Tables migrated (migrate_schema tasks completed) --
214
+ tables_migrated = conn.execute(
215
+ "SELECT COUNT(*) as cnt FROM migration_tasks "
216
+ "WHERE plan_id = ? AND task_type = 'migrate_schema' "
217
+ "AND status = 'completed'",
218
+ (plan_id,),
219
+ ).fetchone()["cnt"]
220
+
221
+ # -- Hours spent (sum of actual_hours from completed tasks) --
222
+ hours_row = conn.execute(
223
+ "SELECT COALESCE(SUM(actual_hours), 0) as total "
224
+ "FROM migration_tasks WHERE plan_id = ? AND status = 'completed'",
225
+ (plan_id,),
226
+ ).fetchone()
227
+ hours_spent = hours_row["total"]
228
+
229
+ # -- Test coverage estimate --
230
+ total_test_tasks = conn.execute(
231
+ "SELECT COUNT(*) as cnt FROM migration_tasks "
232
+ "WHERE plan_id = ? AND task_type IN ('write_tests', 'integration_test', 'e2e_test')",
233
+ (plan_id,),
234
+ ).fetchone()["cnt"]
235
+
236
+ completed_test_tasks = conn.execute(
237
+ "SELECT COUNT(*) as cnt FROM migration_tasks "
238
+ "WHERE plan_id = ? AND task_type IN ('write_tests', 'integration_test', 'e2e_test') "
239
+ "AND status = 'completed'",
240
+ (plan_id,),
241
+ ).fetchone()["cnt"]
242
+
243
+ test_coverage = 0.0
244
+ if total_test_tasks > 0:
245
+ test_coverage = round(completed_test_tasks / total_test_tasks, 4)
246
+
247
+ # -- Compliance score: latest snapshot or compute from compliance tasks --
248
+ compliance_score = 0.0
249
+ latest_compliance = conn.execute(
250
+ "SELECT compliance_score FROM migration_progress "
251
+ "WHERE plan_id = ? AND compliance_score > 0 "
252
+ "ORDER BY created_at DESC LIMIT 1",
253
+ (plan_id,),
254
+ ).fetchone()
255
+ if latest_compliance:
256
+ compliance_score = latest_compliance["compliance_score"]
257
+ else:
258
+ # Estimate: ratio of compliance-type tasks completed
259
+ total_comp_tasks = conn.execute(
260
+ "SELECT COUNT(*) as cnt FROM migration_tasks "
261
+ "WHERE plan_id = ? AND task_type IN "
262
+ "('compliance_check', 'stig_remediation', 'ssp_update', 'cui_marking')",
263
+ (plan_id,),
264
+ ).fetchone()["cnt"]
265
+ completed_comp_tasks = conn.execute(
266
+ "SELECT COUNT(*) as cnt FROM migration_tasks "
267
+ "WHERE plan_id = ? AND task_type IN "
268
+ "('compliance_check', 'stig_remediation', 'ssp_update', 'cui_marking') "
269
+ "AND status = 'completed'",
270
+ (plan_id,),
271
+ ).fetchone()["cnt"]
272
+ if total_comp_tasks > 0:
273
+ compliance_score = round(completed_comp_tasks / total_comp_tasks, 4)
274
+
275
+ # -- INSERT into migration_progress --
276
+ now = _now_iso()
277
+ conn.execute(
278
+ """INSERT INTO migration_progress
279
+ (plan_id, pi_number, snapshot_type,
280
+ tasks_total, tasks_completed, tasks_in_progress, tasks_blocked,
281
+ components_migrated, components_remaining,
282
+ apis_migrated, tables_migrated,
283
+ test_coverage, compliance_score,
284
+ hours_spent, notes, created_at)
285
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
286
+ (
287
+ plan_id, pi_number, snapshot_type,
288
+ tasks_total, tasks_completed, tasks_in_progress, tasks_blocked,
289
+ components_migrated, components_remaining,
290
+ apis_migrated, tables_migrated,
291
+ test_coverage, compliance_score,
292
+ hours_spent, notes, now,
293
+ ),
294
+ )
295
+
296
+ _log_audit(
297
+ conn,
298
+ event_type="compliance_check",
299
+ actor="migration-tracker",
300
+ action=f"Created {snapshot_type} snapshot for {plan_id} at {pi_number}",
301
+ project_id=plan_id,
302
+ details={
303
+ "pi_number": pi_number,
304
+ "snapshot_type": snapshot_type,
305
+ "tasks_total": tasks_total,
306
+ "tasks_completed": tasks_completed,
307
+ "components_migrated": components_migrated,
308
+ },
309
+ )
310
+
311
+ conn.commit()
312
+
313
+ snapshot = {
314
+ "plan_id": plan_id,
315
+ "pi_number": pi_number,
316
+ "snapshot_type": snapshot_type,
317
+ "tasks_total": tasks_total,
318
+ "tasks_completed": tasks_completed,
319
+ "tasks_in_progress": tasks_in_progress,
320
+ "tasks_blocked": tasks_blocked,
321
+ "components_migrated": components_migrated,
322
+ "components_remaining": components_remaining,
323
+ "apis_migrated": apis_migrated,
324
+ "tables_migrated": tables_migrated,
325
+ "test_coverage": test_coverage,
326
+ "compliance_score": compliance_score,
327
+ "hours_spent": hours_spent,
328
+ "notes": notes,
329
+ "created_at": now,
330
+ }
331
+ return snapshot
332
+
333
+ finally:
334
+ conn.close()
335
+
336
+
337
+ # ============================================================================
338
+ # 2. get_migration_velocity
339
+ # ============================================================================
340
+
341
+ def get_migration_velocity(plan_id, db_path=None):
342
+ """Compute tasks/components completed per PI and velocity trends.
343
+
344
+ Queries all pi_end snapshots for the plan, computes deltas between
345
+ consecutive PIs, and calculates averages and trend direction.
346
+
347
+ Args:
348
+ plan_id: Migration plan identifier.
349
+ db_path: Optional database path override.
350
+
351
+ Returns:
352
+ Dict with keys: snapshots (list of per-PI deltas), averages, trend.
353
+ """
354
+ conn = _get_db(db_path)
355
+ try:
356
+ rows = conn.execute(
357
+ "SELECT * FROM migration_progress "
358
+ "WHERE plan_id = ? AND snapshot_type = 'pi_end' "
359
+ "ORDER BY pi_number ASC",
360
+ (plan_id,),
361
+ ).fetchall()
362
+ finally:
363
+ conn.close()
364
+
365
+ snapshots = [dict(r) for r in rows]
366
+
367
+ if len(snapshots) < 1:
368
+ return {
369
+ "snapshots": [],
370
+ "averages": {"tasks": 0, "components": 0, "hours": 0},
371
+ "trend": "insufficient_data",
372
+ }
373
+
374
+ # Compute deltas between consecutive snapshots
375
+ deltas = []
376
+ for i in range(len(snapshots)):
377
+ if i == 0:
378
+ # First PI: delta is from zero baseline
379
+ delta = {
380
+ "pi": snapshots[i]["pi_number"],
381
+ "tasks_completed_delta": snapshots[i]["tasks_completed"],
382
+ "components_delta": snapshots[i]["components_migrated"],
383
+ "hours_delta": snapshots[i]["hours_spent"],
384
+ }
385
+ else:
386
+ prev = snapshots[i - 1]
387
+ curr = snapshots[i]
388
+ delta = {
389
+ "pi": curr["pi_number"],
390
+ "tasks_completed_delta": curr["tasks_completed"] - prev["tasks_completed"],
391
+ "components_delta": curr["components_migrated"] - prev["components_migrated"],
392
+ "hours_delta": curr["hours_spent"] - prev["hours_spent"],
393
+ }
394
+ deltas.append(delta)
395
+
396
+ # Compute averages
397
+ num_pis = len(deltas)
398
+ avg_tasks = sum(d["tasks_completed_delta"] for d in deltas) / num_pis
399
+ avg_components = sum(d["components_delta"] for d in deltas) / num_pis
400
+ avg_hours = sum(d["hours_delta"] for d in deltas) / num_pis
401
+
402
+ # Determine trend from last 3 PIs (or fewer if not enough data)
403
+ trend = "stable"
404
+ recent = deltas[-3:] if len(deltas) >= 3 else deltas
405
+ if len(recent) >= 2:
406
+ recent_tasks = [d["tasks_completed_delta"] for d in recent]
407
+ # Check if trending up or down
408
+ increasing = all(
409
+ recent_tasks[j] >= recent_tasks[j - 1]
410
+ for j in range(1, len(recent_tasks))
411
+ )
412
+ decreasing = all(
413
+ recent_tasks[j] <= recent_tasks[j - 1]
414
+ for j in range(1, len(recent_tasks))
415
+ )
416
+ if increasing and recent_tasks[-1] > recent_tasks[0]:
417
+ trend = "improving"
418
+ elif decreasing and recent_tasks[-1] < recent_tasks[0]:
419
+ trend = "declining"
420
+ else:
421
+ trend = "stable"
422
+
423
+ return {
424
+ "snapshots": deltas,
425
+ "averages": {
426
+ "tasks": round(avg_tasks, 2),
427
+ "components": round(avg_components, 2),
428
+ "hours": round(avg_hours, 2),
429
+ },
430
+ "trend": trend,
431
+ }
432
+
433
+
434
+ # ============================================================================
435
+ # 3. get_migration_burndown
436
+ # ============================================================================
437
+
438
+ def get_migration_burndown(plan_id, db_path=None):
439
+ """Project remaining work vs velocity to estimate completion PI.
440
+
441
+ Uses current task counts and average velocity to project how many
442
+ PIs remain and whether the plan is on track.
443
+
444
+ Args:
445
+ plan_id: Migration plan identifier.
446
+ db_path: Optional database path override.
447
+
448
+ Returns:
449
+ Dict with burndown data, projected completion, and on_track flag.
450
+ """
451
+ conn = _get_db(db_path)
452
+ try:
453
+ # Current state from migration_plans
454
+ plan_row = conn.execute(
455
+ "SELECT * FROM migration_plans WHERE id = ?",
456
+ (plan_id,),
457
+ ).fetchone()
458
+ if not plan_row:
459
+ return {"error": f"Plan {plan_id} not found"}
460
+
461
+ total_tasks = plan_row["total_tasks"] or 0
462
+ completed_tasks = plan_row["completed_tasks"] or 0
463
+ remaining_tasks = max(0, total_tasks - completed_tasks)
464
+
465
+ # Get all pi_end snapshots for burndown data points
466
+ snapshots = conn.execute(
467
+ "SELECT pi_number, tasks_completed, tasks_total "
468
+ "FROM migration_progress "
469
+ "WHERE plan_id = ? AND snapshot_type = 'pi_end' "
470
+ "ORDER BY pi_number ASC",
471
+ (plan_id,),
472
+ ).fetchall()
473
+ finally:
474
+ conn.close()
475
+
476
+ # Get velocity
477
+ velocity = get_migration_velocity(plan_id, db_path=db_path)
478
+ avg_tasks_per_pi = velocity["averages"]["tasks"]
479
+
480
+ # Project remaining PIs
481
+ remaining_pis = None
482
+ projected_completion_pi = None
483
+ if avg_tasks_per_pi > 0:
484
+ remaining_pis = math.ceil(remaining_tasks / avg_tasks_per_pi)
485
+ # Estimate projected PI label based on last snapshot
486
+ if snapshots:
487
+ last_pi = dict(snapshots[-1])["pi_number"]
488
+ projected_completion_pi = _project_pi_label(last_pi, remaining_pis)
489
+ else:
490
+ projected_completion_pi = f"+{remaining_pis} PIs"
491
+
492
+ # Build burndown data points
493
+ burndown_data = []
494
+ ideal_per_pi = total_tasks / max(len(snapshots) + (remaining_pis or 1), 1)
495
+ for idx, snap in enumerate(snapshots):
496
+ snap_dict = dict(snap)
497
+ tasks_remaining = total_tasks - snap_dict["tasks_completed"]
498
+ ideal_remaining = max(0, total_tasks - ideal_per_pi * (idx + 1))
499
+ burndown_data.append({
500
+ "pi_number": snap_dict["pi_number"],
501
+ "tasks_remaining": tasks_remaining,
502
+ "ideal_remaining": round(ideal_remaining, 1),
503
+ })
504
+
505
+ # On-track: remaining work is at or below ideal line
506
+ on_track = True
507
+ if burndown_data:
508
+ last = burndown_data[-1]
509
+ on_track = last["tasks_remaining"] <= last["ideal_remaining"] + 1
510
+
511
+ return {
512
+ "plan_id": plan_id,
513
+ "total_tasks": total_tasks,
514
+ "completed_tasks": completed_tasks,
515
+ "remaining_tasks": remaining_tasks,
516
+ "avg_tasks_per_pi": avg_tasks_per_pi,
517
+ "remaining_pis": remaining_pis,
518
+ "projected_completion_pi": projected_completion_pi,
519
+ "on_track": on_track,
520
+ "burndown_data": burndown_data,
521
+ "velocity_trend": velocity["trend"],
522
+ }
523
+
524
+
525
+ def _project_pi_label(current_pi, additional_pis):
526
+ """Estimate a future PI label by incrementing the current one.
527
+
528
+ Supports labels like 'PI-25.3' (year.increment format). Wraps at
529
+ increment 6 to the next year (SAFe typically has 4-6 PIs/year).
530
+
531
+ Args:
532
+ current_pi: Current PI label string (e.g. 'PI-25.3').
533
+ additional_pis: Number of PIs to add.
534
+
535
+ Returns:
536
+ Projected PI label string.
537
+ """
538
+ try:
539
+ prefix, version = current_pi.rsplit("-", 1)
540
+ parts = version.split(".")
541
+ year = int(parts[0])
542
+ increment = int(parts[1])
543
+
544
+ for _ in range(additional_pis):
545
+ increment += 1
546
+ if increment > 6:
547
+ increment = 1
548
+ year += 1
549
+
550
+ return f"{prefix}-{year}.{increment}"
551
+ except (ValueError, IndexError):
552
+ return f"{current_pi}+{additional_pis}"
553
+
554
+
555
+ # ============================================================================
556
+ # 4. compare_pi_snapshots
557
+ # ============================================================================
558
+
559
+ def compare_pi_snapshots(plan_id, from_pi, to_pi, db_path=None):
560
+ """Compute deltas between two PI snapshots for the same plan.
561
+
562
+ Queries the latest pi_end (or manual) snapshot for each PI and
563
+ computes the difference for all tracked metrics.
564
+
565
+ Args:
566
+ plan_id: Migration plan identifier.
567
+ from_pi: Starting PI label (e.g. 'PI-25.2').
568
+ to_pi: Ending PI label (e.g. 'PI-25.3').
569
+ db_path: Optional database path override.
570
+
571
+ Returns:
572
+ Dict with from_snapshot, to_snapshot, and deltas.
573
+ """
574
+ conn = _get_db(db_path)
575
+ try:
576
+ from_row = conn.execute(
577
+ "SELECT * FROM migration_progress "
578
+ "WHERE plan_id = ? AND pi_number = ? "
579
+ "ORDER BY created_at DESC LIMIT 1",
580
+ (plan_id, from_pi),
581
+ ).fetchone()
582
+
583
+ to_row = conn.execute(
584
+ "SELECT * FROM migration_progress "
585
+ "WHERE plan_id = ? AND pi_number = ? "
586
+ "ORDER BY created_at DESC LIMIT 1",
587
+ (plan_id, to_pi),
588
+ ).fetchone()
589
+ finally:
590
+ conn.close()
591
+
592
+ if not from_row:
593
+ return {"error": f"No snapshot found for {from_pi}"}
594
+ if not to_row:
595
+ return {"error": f"No snapshot found for {to_pi}"}
596
+
597
+ from_dict = dict(from_row)
598
+ to_dict = dict(to_row)
599
+
600
+ # Numeric fields to compare
601
+ compare_fields = [
602
+ "tasks_total", "tasks_completed", "tasks_in_progress", "tasks_blocked",
603
+ "components_migrated", "components_remaining",
604
+ "apis_migrated", "tables_migrated",
605
+ "test_coverage", "compliance_score", "hours_spent",
606
+ ]
607
+
608
+ deltas = {}
609
+ for field in compare_fields:
610
+ from_val = from_dict.get(field, 0) or 0
611
+ to_val = to_dict.get(field, 0) or 0
612
+ deltas[field] = round(to_val - from_val, 4)
613
+
614
+ # Highlight important changes
615
+ highlights = []
616
+ if deltas["tasks_completed"] > 0:
617
+ highlights.append(f"{deltas['tasks_completed']} tasks completed")
618
+ if deltas["tasks_blocked"] > 0:
619
+ highlights.append(f"{deltas['tasks_blocked']} new blockers")
620
+ if deltas["tasks_blocked"] < 0:
621
+ highlights.append(f"{abs(deltas['tasks_blocked'])} blockers resolved")
622
+ if deltas["compliance_score"] != 0:
623
+ direction = "improved" if deltas["compliance_score"] > 0 else "decreased"
624
+ highlights.append(
625
+ f"Compliance score {direction} by "
626
+ f"{abs(deltas['compliance_score']):.4f}"
627
+ )
628
+ if deltas["hours_spent"] > 0:
629
+ highlights.append(f"{deltas['hours_spent']:.1f} hours spent")
630
+
631
+ return {
632
+ "plan_id": plan_id,
633
+ "from_pi": from_pi,
634
+ "to_pi": to_pi,
635
+ "from_snapshot": from_dict,
636
+ "to_snapshot": to_dict,
637
+ "deltas": deltas,
638
+ "highlights": highlights,
639
+ }
640
+
641
+
642
+ # ============================================================================
643
+ # 5. assign_tasks_to_pi
644
+ # ============================================================================
645
+
646
+ def assign_tasks_to_pi(plan_id, pi_number, task_ids, db_path=None):
647
+ """Assign one or more migration tasks to a specific PI.
648
+
649
+ Updates the pi_number column on matching migration_tasks rows.
650
+
651
+ Args:
652
+ plan_id: Migration plan identifier.
653
+ pi_number: PI label to assign (e.g. 'PI-25.3').
654
+ task_ids: List of task identifier strings.
655
+ db_path: Optional database path override.
656
+
657
+ Returns:
658
+ Count of tasks successfully assigned.
659
+ """
660
+ if not task_ids:
661
+ return 0
662
+
663
+ conn = _get_db(db_path)
664
+ try:
665
+ assigned = 0
666
+ for tid in task_ids:
667
+ cursor = conn.execute(
668
+ "UPDATE migration_tasks SET pi_number = ? "
669
+ "WHERE id = ? AND plan_id = ?",
670
+ (pi_number, tid, plan_id),
671
+ )
672
+ assigned += cursor.rowcount
673
+
674
+ _log_audit(
675
+ conn,
676
+ event_type="project_updated",
677
+ actor="migration-tracker",
678
+ action=f"Assigned {assigned} tasks to {pi_number} in plan {plan_id}",
679
+ project_id=plan_id,
680
+ details={"pi_number": pi_number, "task_ids": task_ids},
681
+ )
682
+
683
+ conn.commit()
684
+ return assigned
685
+ finally:
686
+ conn.close()
687
+
688
+
689
+ # ============================================================================
690
+ # 6. get_pi_tasks
691
+ # ============================================================================
692
+
693
+ def get_pi_tasks(plan_id, pi_number, db_path=None):
694
+ """Retrieve all migration tasks assigned to a specific PI.
695
+
696
+ Args:
697
+ plan_id: Migration plan identifier.
698
+ pi_number: PI label to query.
699
+ db_path: Optional database path override.
700
+
701
+ Returns:
702
+ Dict with pi_number, tasks list, and by_status breakdown.
703
+ """
704
+ conn = _get_db(db_path)
705
+ try:
706
+ rows = conn.execute(
707
+ "SELECT id, title, task_type, priority, status, "
708
+ "estimated_hours, actual_hours, assigned_to "
709
+ "FROM migration_tasks "
710
+ "WHERE plan_id = ? AND pi_number = ? "
711
+ "ORDER BY priority ASC, title ASC",
712
+ (plan_id, pi_number),
713
+ ).fetchall()
714
+ finally:
715
+ conn.close()
716
+
717
+ tasks = []
718
+ by_status = {s: 0 for s in VALID_TASK_STATUSES}
719
+
720
+ for r in rows:
721
+ task = {
722
+ "id": r["id"],
723
+ "title": r["title"],
724
+ "type": r["task_type"],
725
+ "priority": r["priority"],
726
+ "status": r["status"],
727
+ "estimated_hours": r["estimated_hours"],
728
+ "actual_hours": r["actual_hours"],
729
+ "assigned_to": r["assigned_to"],
730
+ }
731
+ tasks.append(task)
732
+ if r["status"] in by_status:
733
+ by_status[r["status"]] += 1
734
+
735
+ return {
736
+ "pi_number": pi_number,
737
+ "plan_id": plan_id,
738
+ "task_count": len(tasks),
739
+ "tasks": tasks,
740
+ "by_status": by_status,
741
+ }
742
+
743
+
744
+ # ============================================================================
745
+ # 7. generate_pi_migration_report
746
+ # ============================================================================
747
+
748
+ def generate_pi_migration_report(plan_id, pi_number, output_dir=None,
749
+ db_path=None):
750
+ """Generate a CUI-marked markdown PI migration report.
751
+
752
+ Combines task data, velocity, burndown, snapshot comparison, and
753
+ compliance gate status into a structured report.
754
+
755
+ Args:
756
+ plan_id: Migration plan identifier.
757
+ pi_number: PI label for the report.
758
+ output_dir: Optional directory to write the report file.
759
+ db_path: Optional database path override.
760
+
761
+ Returns:
762
+ Report content string, or file path if output_dir is provided.
763
+ """
764
+ # Gather data
765
+ pi_data = get_pi_tasks(plan_id, pi_number, db_path=db_path)
766
+ velocity = get_migration_velocity(plan_id, db_path=db_path)
767
+ burndown = get_migration_burndown(plan_id, db_path=db_path)
768
+ gate = check_pi_compliance_gate(plan_id, pi_number, db_path=db_path)
769
+
770
+ # Plan metadata
771
+ conn = _get_db(db_path)
772
+ try:
773
+ plan_row = conn.execute(
774
+ "SELECT * FROM migration_plans WHERE id = ?",
775
+ (plan_id,),
776
+ ).fetchone()
777
+ finally:
778
+ conn.close()
779
+
780
+ plan_name = plan_row["plan_name"] if plan_row else plan_id
781
+ strategy = plan_row["strategy"] if plan_row else "N/A"
782
+
783
+ # Determine previous PI for comparison
784
+ prev_pi = _previous_pi_label(pi_number)
785
+ comparison = compare_pi_snapshots(plan_id, prev_pi, pi_number, db_path=db_path)
786
+
787
+ # Build report
788
+ lines = []
789
+ lines.append("CUI // SP-CTI")
790
+ lines.append("=" * 80)
791
+ lines.append("")
792
+ lines.append(f"# PI Migration Report: {pi_number}")
793
+ lines.append("")
794
+ lines.append(f"**Plan:** {plan_name} ")
795
+ lines.append(f"**Plan ID:** {plan_id} ")
796
+ lines.append(f"**Strategy:** {strategy} ")
797
+ lines.append(f"**Generated:** {_now_iso()} ")
798
+ lines.append("")
799
+
800
+ # --- Task Completion ---
801
+ lines.append("## Task Completion")
802
+ lines.append("")
803
+ by_status = pi_data["by_status"]
804
+ total_pi = pi_data["task_count"]
805
+ completed = by_status.get("completed", 0)
806
+ in_prog = by_status.get("in_progress", 0)
807
+ blocked = by_status.get("blocked", 0)
808
+ pending = by_status.get("pending", 0)
809
+ skipped = by_status.get("skipped", 0)
810
+ pct = round(completed / total_pi * 100, 1) if total_pi > 0 else 0.0
811
+
812
+ lines.append("| Status | Count | Percentage |")
813
+ lines.append("|-------------|-------|------------|")
814
+ lines.append(f"| Completed | {completed:>5} | {pct:>9.1f}% |")
815
+ if total_pi > 0:
816
+ lines.append(f"| In Progress | {in_prog:>5} | {in_prog/total_pi*100:>9.1f}% |")
817
+ lines.append(f"| Blocked | {blocked:>5} | {blocked/total_pi*100:>9.1f}% |")
818
+ lines.append(f"| Pending | {pending:>5} | {pending/total_pi*100:>9.1f}% |")
819
+ lines.append(f"| Skipped | {skipped:>5} | {skipped/total_pi*100:>9.1f}% |")
820
+ lines.append(f"| **Total** | **{total_pi}** | |")
821
+ lines.append("")
822
+
823
+ # --- Velocity ---
824
+ lines.append("## Velocity")
825
+ lines.append("")
826
+ lines.append(f"**Trend:** {velocity['trend']} ")
827
+ lines.append(f"**Avg Tasks/PI:** {velocity['averages']['tasks']} ")
828
+ lines.append(f"**Avg Components/PI:** {velocity['averages']['components']} ")
829
+ lines.append(f"**Avg Hours/PI:** {velocity['averages']['hours']} ")
830
+ lines.append("")
831
+
832
+ # ASCII bar chart of tasks per PI
833
+ if velocity["snapshots"]:
834
+ lines.append("```")
835
+ max_tasks = max(
836
+ (d["tasks_completed_delta"] for d in velocity["snapshots"]),
837
+ default=1,
838
+ )
839
+ max_tasks = max(max_tasks, 1)
840
+ bar_width = 40
841
+ for d in velocity["snapshots"]:
842
+ bar_len = int(d["tasks_completed_delta"] / max_tasks * bar_width)
843
+ bar = "#" * bar_len
844
+ lines.append(
845
+ f" {d['pi']:<10} | {bar:<{bar_width}} | "
846
+ f"{d['tasks_completed_delta']} tasks"
847
+ )
848
+ lines.append("```")
849
+ lines.append("")
850
+
851
+ # --- Burndown ---
852
+ lines.append("## Burndown Projection")
853
+ lines.append("")
854
+ lines.append(f"**Total Tasks:** {burndown.get('total_tasks', 'N/A')} ")
855
+ lines.append(f"**Completed:** {burndown.get('completed_tasks', 'N/A')} ")
856
+ lines.append(f"**Remaining:** {burndown.get('remaining_tasks', 'N/A')} ")
857
+ lines.append(f"**Avg Velocity:** {burndown.get('avg_tasks_per_pi', 'N/A')} tasks/PI ")
858
+ remaining_pis = burndown.get("remaining_pis")
859
+ lines.append(
860
+ f"**Projected Remaining PIs:** "
861
+ f"{remaining_pis if remaining_pis is not None else 'N/A'} "
862
+ )
863
+ lines.append(
864
+ f"**Projected Completion:** "
865
+ f"{burndown.get('projected_completion_pi', 'N/A')} "
866
+ )
867
+ lines.append(f"**On Track:** {'YES' if burndown.get('on_track') else 'NO'} ")
868
+ lines.append("")
869
+
870
+ # --- Hours ---
871
+ lines.append("## Hours: Estimated vs Actual")
872
+ lines.append("")
873
+ est_total = sum(
874
+ (t.get("estimated_hours") or 0) for t in pi_data["tasks"]
875
+ )
876
+ act_total = sum(
877
+ (t.get("actual_hours") or 0) for t in pi_data["tasks"]
878
+ )
879
+ variance = act_total - est_total
880
+ lines.append("| Metric | Hours |")
881
+ lines.append("|-----------|-------|")
882
+ lines.append(f"| Estimated | {est_total:>5.1f} |")
883
+ lines.append(f"| Actual | {act_total:>5.1f} |")
884
+ lines.append(f"| Variance | {variance:>+5.1f} |")
885
+ lines.append("")
886
+
887
+ # --- Compliance Gate ---
888
+ lines.append("## Compliance Gate")
889
+ lines.append("")
890
+ gate_status = "PASS" if gate.get("passed") else "FAIL"
891
+ lines.append(f"**Status:** {gate_status} ")
892
+ lines.append(
893
+ f"**Score:** {gate.get('score', 0):.4f} "
894
+ f"(threshold: {gate.get('threshold', COMPLIANCE_THRESHOLD)}) "
895
+ )
896
+ if gate.get("issues"):
897
+ lines.append("")
898
+ lines.append("**Issues:**")
899
+ for issue in gate["issues"]:
900
+ lines.append(f"- {issue}")
901
+ lines.append("")
902
+
903
+ # --- Blockers & Risks ---
904
+ lines.append("## Blockers & Risks")
905
+ lines.append("")
906
+ blocked_tasks = [t for t in pi_data["tasks"] if t["status"] == "blocked"]
907
+ if blocked_tasks:
908
+ for bt in blocked_tasks:
909
+ lines.append(f"- **{bt['id']}** {bt['title']} (priority: {bt['priority']})")
910
+ else:
911
+ lines.append("No blocked tasks in this PI.")
912
+ lines.append("")
913
+
914
+ # --- Next PI Plan ---
915
+ lines.append("## Next PI Plan")
916
+ lines.append("")
917
+ next_pi = _next_pi_label(pi_number)
918
+ next_data = get_pi_tasks(plan_id, next_pi, db_path=db_path)
919
+ if next_data["tasks"]:
920
+ high_pri = [
921
+ t for t in next_data["tasks"]
922
+ if t["priority"] in (1, 2, "1", "2", "critical", "high")
923
+ ]
924
+ if high_pri:
925
+ lines.append(f"High-priority tasks for {next_pi}:")
926
+ for t in high_pri[:10]:
927
+ lines.append(f"- [{t['id']}] {t['title']} (priority: {t['priority']})")
928
+ else:
929
+ lines.append(
930
+ f"{next_data['task_count']} tasks assigned to {next_pi}."
931
+ )
932
+ else:
933
+ lines.append(f"No tasks yet assigned to {next_pi}.")
934
+ lines.append("")
935
+
936
+ # --- Comparison vs previous PI ---
937
+ if "error" not in comparison:
938
+ lines.append(f"## Comparison: {prev_pi} -> {pi_number}")
939
+ lines.append("")
940
+ if comparison.get("highlights"):
941
+ for h in comparison["highlights"]:
942
+ lines.append(f"- {h}")
943
+ lines.append("")
944
+
945
+ lines.append("=" * 80)
946
+ lines.append("CUI // SP-CTI")
947
+
948
+ report_content = "\n".join(lines)
949
+
950
+ # Write to file if output_dir provided
951
+ if output_dir:
952
+ out_path = Path(output_dir)
953
+ out_path.mkdir(parents=True, exist_ok=True)
954
+ filename = f"pi_migration_report_{plan_id}_{pi_number}.md"
955
+ filepath = out_path / filename
956
+ filepath.write_text(report_content, encoding="utf-8")
957
+ return str(filepath)
958
+
959
+ return report_content
960
+
961
+
962
+ def _previous_pi_label(pi_label):
963
+ """Compute the previous PI label from the given one.
964
+
965
+ Args:
966
+ pi_label: PI label string (e.g. 'PI-25.3').
967
+
968
+ Returns:
969
+ Previous PI label string.
970
+ """
971
+ try:
972
+ prefix, version = pi_label.rsplit("-", 1)
973
+ parts = version.split(".")
974
+ year = int(parts[0])
975
+ increment = int(parts[1])
976
+ increment -= 1
977
+ if increment < 1:
978
+ increment = 6
979
+ year -= 1
980
+ return f"{prefix}-{year}.{increment}"
981
+ except (ValueError, IndexError):
982
+ return pi_label
983
+
984
+
985
+ def _next_pi_label(pi_label):
986
+ """Compute the next PI label from the given one.
987
+
988
+ Args:
989
+ pi_label: PI label string (e.g. 'PI-25.3').
990
+
991
+ Returns:
992
+ Next PI label string.
993
+ """
994
+ return _project_pi_label(pi_label, 1)
995
+
996
+
997
+ # ============================================================================
998
+ # 8. check_pi_compliance_gate
999
+ # ============================================================================
1000
+
1001
+ def check_pi_compliance_gate(plan_id, pi_number, db_path=None):
1002
+ """Verify that ATO compliance is maintained for the given PI.
1003
+
1004
+ Checks:
1005
+ 1. Compliance score >= 0.95
1006
+ 2. No new critical blockers
1007
+ 3. All compliance-affecting PI tasks are completed
1008
+
1009
+ Args:
1010
+ plan_id: Migration plan identifier.
1011
+ pi_number: PI label to check.
1012
+ db_path: Optional database path override.
1013
+
1014
+ Returns:
1015
+ Dict with passed (bool), score, threshold, and issues list.
1016
+ """
1017
+ conn = _get_db(db_path)
1018
+ try:
1019
+ # Get latest snapshot compliance score
1020
+ snap_row = conn.execute(
1021
+ "SELECT compliance_score FROM migration_progress "
1022
+ "WHERE plan_id = ? AND pi_number = ? "
1023
+ "ORDER BY created_at DESC LIMIT 1",
1024
+ (plan_id, pi_number),
1025
+ ).fetchone()
1026
+
1027
+ score = snap_row["compliance_score"] if snap_row else 0.0
1028
+
1029
+ # Check for critical blocked tasks
1030
+ blocked_critical = conn.execute(
1031
+ "SELECT COUNT(*) as cnt FROM migration_tasks "
1032
+ "WHERE plan_id = ? AND pi_number = ? "
1033
+ "AND status = 'blocked' AND priority IN (1, 'critical')",
1034
+ (plan_id, pi_number),
1035
+ ).fetchone()["cnt"]
1036
+
1037
+ # Check compliance-affecting tasks
1038
+ compliance_task_types = (
1039
+ "compliance_check", "stig_remediation", "ssp_update", "cui_marking",
1040
+ )
1041
+ placeholders = ",".join("?" * len(compliance_task_types))
1042
+ incomplete_compliance = conn.execute(
1043
+ f"SELECT COUNT(*) as cnt FROM migration_tasks "
1044
+ f"WHERE plan_id = ? AND pi_number = ? "
1045
+ f"AND task_type IN ({placeholders}) "
1046
+ f"AND status NOT IN ('completed', 'skipped')",
1047
+ (plan_id, pi_number) + compliance_task_types,
1048
+ ).fetchone()["cnt"]
1049
+
1050
+ finally:
1051
+ conn.close()
1052
+
1053
+ issues = []
1054
+ passed = True
1055
+
1056
+ if score < COMPLIANCE_THRESHOLD:
1057
+ passed = False
1058
+ issues.append(
1059
+ f"Compliance score {score:.4f} is below threshold "
1060
+ f"{COMPLIANCE_THRESHOLD}"
1061
+ )
1062
+
1063
+ if blocked_critical > 0:
1064
+ passed = False
1065
+ issues.append(
1066
+ f"{blocked_critical} critical blocker(s) remain unresolved"
1067
+ )
1068
+
1069
+ if incomplete_compliance > 0:
1070
+ passed = False
1071
+ issues.append(
1072
+ f"{incomplete_compliance} compliance task(s) not yet completed"
1073
+ )
1074
+
1075
+ return {
1076
+ "plan_id": plan_id,
1077
+ "pi_number": pi_number,
1078
+ "passed": passed,
1079
+ "score": score,
1080
+ "threshold": COMPLIANCE_THRESHOLD,
1081
+ "issues": issues,
1082
+ }
1083
+
1084
+
1085
+ # ============================================================================
1086
+ # 9. update_task_status
1087
+ # ============================================================================
1088
+
1089
+ def update_task_status(task_id, status, actual_hours=None, db_path=None):
1090
+ """Update the status (and optionally actual_hours) of a migration task.
1091
+
1092
+ If status is 'completed', also sets completed_at and increments the
1093
+ parent plan's completed_tasks counter.
1094
+
1095
+ Args:
1096
+ task_id: Migration task identifier.
1097
+ status: New status string.
1098
+ actual_hours: Optional hours spent (float).
1099
+ db_path: Optional database path override.
1100
+
1101
+ Returns:
1102
+ Dict with the updated task fields.
1103
+ """
1104
+ if status not in VALID_TASK_STATUSES:
1105
+ raise ValueError(
1106
+ f"Invalid status '{status}'. Valid: {VALID_TASK_STATUSES}"
1107
+ )
1108
+
1109
+ conn = _get_db(db_path)
1110
+ try:
1111
+ # Fetch current task
1112
+ task_row = conn.execute(
1113
+ "SELECT * FROM migration_tasks WHERE id = ?",
1114
+ (task_id,),
1115
+ ).fetchone()
1116
+ if not task_row:
1117
+ return {"error": f"Task {task_id} not found"}
1118
+
1119
+ old_status = task_row["status"]
1120
+ plan_id = task_row["plan_id"]
1121
+ completed_at = None
1122
+
1123
+ if status == "completed":
1124
+ completed_at = _now_iso()
1125
+
1126
+ # Build update
1127
+ if actual_hours is not None and completed_at:
1128
+ conn.execute(
1129
+ "UPDATE migration_tasks "
1130
+ "SET status = ?, actual_hours = ?, completed_at = ? "
1131
+ "WHERE id = ?",
1132
+ (status, actual_hours, completed_at, task_id),
1133
+ )
1134
+ elif actual_hours is not None:
1135
+ conn.execute(
1136
+ "UPDATE migration_tasks SET status = ?, actual_hours = ? "
1137
+ "WHERE id = ?",
1138
+ (status, actual_hours, task_id),
1139
+ )
1140
+ elif completed_at:
1141
+ conn.execute(
1142
+ "UPDATE migration_tasks SET status = ?, completed_at = ? "
1143
+ "WHERE id = ?",
1144
+ (status, completed_at, task_id),
1145
+ )
1146
+ else:
1147
+ conn.execute(
1148
+ "UPDATE migration_tasks SET status = ? WHERE id = ?",
1149
+ (status, task_id),
1150
+ )
1151
+
1152
+ # Update migration_plans completed_tasks count
1153
+ completed_count = conn.execute(
1154
+ "SELECT COUNT(*) as cnt FROM migration_tasks "
1155
+ "WHERE plan_id = ? AND status = 'completed'",
1156
+ (plan_id,),
1157
+ ).fetchone()["cnt"]
1158
+
1159
+ conn.execute(
1160
+ "UPDATE migration_plans SET completed_tasks = ?, updated_at = ? "
1161
+ "WHERE id = ?",
1162
+ (completed_count, _now_iso(), plan_id),
1163
+ )
1164
+
1165
+ _log_audit(
1166
+ conn,
1167
+ event_type="project_updated",
1168
+ actor="migration-tracker",
1169
+ action=f"Task {task_id} status changed: {old_status} -> {status}",
1170
+ project_id=plan_id,
1171
+ details={
1172
+ "task_id": task_id,
1173
+ "old_status": old_status,
1174
+ "new_status": status,
1175
+ "actual_hours": actual_hours,
1176
+ },
1177
+ )
1178
+
1179
+ conn.commit()
1180
+
1181
+ # Re-fetch updated task
1182
+ updated = conn.execute(
1183
+ "SELECT * FROM migration_tasks WHERE id = ?",
1184
+ (task_id,),
1185
+ ).fetchone()
1186
+
1187
+ return dict(updated) if updated else {"task_id": task_id, "status": status}
1188
+
1189
+ finally:
1190
+ conn.close()
1191
+
1192
+
1193
+ # ============================================================================
1194
+ # 10. get_dashboard
1195
+ # ============================================================================
1196
+
1197
+ def get_dashboard(plan_id, db_path=None):
1198
+ """Generate a summary dashboard for the migration plan.
1199
+
1200
+ Combines plan overview, progress, current PI status, velocity,
1201
+ burndown, compliance, and blockers into a single view.
1202
+
1203
+ Args:
1204
+ plan_id: Migration plan identifier.
1205
+ db_path: Optional database path override.
1206
+
1207
+ Returns:
1208
+ Dict with all dashboard sections.
1209
+ """
1210
+ conn = _get_db(db_path)
1211
+ try:
1212
+ # Plan overview
1213
+ plan_row = conn.execute(
1214
+ "SELECT * FROM migration_plans WHERE id = ?",
1215
+ (plan_id,),
1216
+ ).fetchone()
1217
+ if not plan_row:
1218
+ return {"error": f"Plan {plan_id} not found"}
1219
+
1220
+ plan = dict(plan_row)
1221
+ total_tasks = plan.get("total_tasks", 0) or 0
1222
+ completed_tasks = plan.get("completed_tasks", 0) or 0
1223
+
1224
+ # Current PI: find the most recent pi_number in tasks
1225
+ current_pi_row = conn.execute(
1226
+ "SELECT pi_number, COUNT(*) as cnt FROM migration_tasks "
1227
+ "WHERE plan_id = ? AND pi_number IS NOT NULL "
1228
+ "GROUP BY pi_number ORDER BY pi_number DESC LIMIT 1",
1229
+ (plan_id,),
1230
+ ).fetchone()
1231
+ current_pi = current_pi_row["pi_number"] if current_pi_row else None
1232
+
1233
+ # Current PI task breakdown
1234
+ current_pi_tasks = {"assigned": 0, "completed": 0}
1235
+ if current_pi:
1236
+ pi_stats = conn.execute(
1237
+ "SELECT status, COUNT(*) as cnt FROM migration_tasks "
1238
+ "WHERE plan_id = ? AND pi_number = ? GROUP BY status",
1239
+ (plan_id, current_pi),
1240
+ ).fetchall()
1241
+ total_assigned = 0
1242
+ pi_completed = 0
1243
+ for r in pi_stats:
1244
+ total_assigned += r["cnt"]
1245
+ if r["status"] == "completed":
1246
+ pi_completed = r["cnt"]
1247
+ current_pi_tasks = {
1248
+ "assigned": total_assigned,
1249
+ "completed": pi_completed,
1250
+ }
1251
+
1252
+ # Blockers
1253
+ blockers = conn.execute(
1254
+ "SELECT id, title, priority FROM migration_tasks "
1255
+ "WHERE plan_id = ? AND status = 'blocked' "
1256
+ "ORDER BY priority ASC LIMIT 5",
1257
+ (plan_id,),
1258
+ ).fetchall()
1259
+ finally:
1260
+ conn.close()
1261
+
1262
+ # Velocity and burndown
1263
+ velocity = get_migration_velocity(plan_id, db_path=db_path)
1264
+ burndown = get_migration_burndown(plan_id, db_path=db_path)
1265
+
1266
+ # Compliance
1267
+ compliance_gate = None
1268
+ if current_pi:
1269
+ compliance_gate = check_pi_compliance_gate(
1270
+ plan_id, current_pi, db_path=db_path
1271
+ )
1272
+
1273
+ # Progress percentage
1274
+ progress_pct = 0.0
1275
+ if total_tasks > 0:
1276
+ progress_pct = round(completed_tasks / total_tasks * 100, 1)
1277
+
1278
+ # Progress bar (50-char wide)
1279
+ bar_width = 50
1280
+ filled = int(progress_pct / 100 * bar_width)
1281
+ progress_bar = "[" + "#" * filled + "-" * (bar_width - filled) + "]"
1282
+
1283
+ return {
1284
+ "plan_id": plan_id,
1285
+ "plan_name": plan.get("plan_name", plan_id),
1286
+ "strategy": plan.get("strategy", "N/A"),
1287
+ "status": plan.get("status", "N/A"),
1288
+ "progress": {
1289
+ "total_tasks": total_tasks,
1290
+ "completed_tasks": completed_tasks,
1291
+ "percentage": progress_pct,
1292
+ "bar": progress_bar,
1293
+ "estimated_hours": plan.get("estimated_hours", 0),
1294
+ "actual_hours": plan.get("actual_hours", 0),
1295
+ },
1296
+ "current_pi": {
1297
+ "pi_number": current_pi,
1298
+ "tasks_assigned": current_pi_tasks["assigned"],
1299
+ "tasks_completed": current_pi_tasks["completed"],
1300
+ },
1301
+ "velocity": {
1302
+ "last_3_pis": velocity["snapshots"][-3:]
1303
+ if velocity["snapshots"] else [],
1304
+ "trend": velocity["trend"],
1305
+ "averages": velocity["averages"],
1306
+ },
1307
+ "burndown": {
1308
+ "remaining_tasks": burndown.get("remaining_tasks", 0),
1309
+ "remaining_pis": burndown.get("remaining_pis"),
1310
+ "projected_completion": burndown.get("projected_completion_pi"),
1311
+ "on_track": burndown.get("on_track", False),
1312
+ },
1313
+ "compliance": {
1314
+ "score": compliance_gate["score"] if compliance_gate else 0.0,
1315
+ "gate_passed": compliance_gate["passed"]
1316
+ if compliance_gate else False,
1317
+ "issues": compliance_gate["issues"] if compliance_gate else [],
1318
+ },
1319
+ "blockers": {
1320
+ "count": len(blockers),
1321
+ "top_items": [
1322
+ {"id": b["id"], "title": b["title"], "priority": b["priority"]}
1323
+ for b in blockers
1324
+ ],
1325
+ },
1326
+ }
1327
+
1328
+
1329
+ # ============================================================================
1330
+ # CLI display helpers
1331
+ # ============================================================================
1332
+
1333
+ def _print_dashboard(dashboard):
1334
+ """Pretty-print the dashboard to stdout with CUI markings.
1335
+
1336
+ Args:
1337
+ dashboard: Dashboard dict from get_dashboard().
1338
+ """
1339
+ print("=" * 70)
1340
+ print("CUI // SP-CTI")
1341
+ print("=" * 70)
1342
+ print()
1343
+ print("MIGRATION DASHBOARD")
1344
+ print(f" Plan: {dashboard['plan_name']}")
1345
+ print(f" ID: {dashboard['plan_id']}")
1346
+ print(f" Strategy: {dashboard['strategy']}")
1347
+ print(f" Status: {dashboard['status']}")
1348
+ print()
1349
+
1350
+ prog = dashboard["progress"]
1351
+ print("PROGRESS")
1352
+ print(f" {prog['bar']} {prog['percentage']}%")
1353
+ print(f" Tasks: {prog['completed_tasks']}/{prog['total_tasks']}")
1354
+ print(f" Hours: {prog.get('actual_hours', 0)}/{prog.get('estimated_hours', 0)} (actual/estimated)")
1355
+ print()
1356
+
1357
+ pi = dashboard["current_pi"]
1358
+ if pi["pi_number"]:
1359
+ print(f"CURRENT PI: {pi['pi_number']}")
1360
+ print(f" Assigned: {pi['tasks_assigned']}")
1361
+ print(f" Completed: {pi['tasks_completed']}")
1362
+ print()
1363
+
1364
+ vel = dashboard["velocity"]
1365
+ print("VELOCITY")
1366
+ print(f" Trend: {vel['trend']}")
1367
+ print(f" Avg Tasks/PI: {vel['averages']['tasks']}")
1368
+ print(f" Avg Components/PI: {vel['averages']['components']}")
1369
+ print(f" Avg Hours/PI: {vel['averages']['hours']}")
1370
+ if vel["last_3_pis"]:
1371
+ print(" Recent PIs:")
1372
+ for d in vel["last_3_pis"]:
1373
+ print(f" {d['pi']}: {d['tasks_completed_delta']} tasks, "
1374
+ f"{d['components_delta']} components, "
1375
+ f"{d['hours_delta']} hours")
1376
+ print()
1377
+
1378
+ bd = dashboard["burndown"]
1379
+ print("BURNDOWN")
1380
+ print(f" Remaining Tasks: {bd['remaining_tasks']}")
1381
+ print(f" Remaining PIs: {bd['remaining_pis'] or 'N/A'}")
1382
+ print(f" Projected Done: {bd['projected_completion'] or 'N/A'}")
1383
+ print(f" On Track: {'YES' if bd['on_track'] else 'NO'}")
1384
+ print()
1385
+
1386
+ comp = dashboard["compliance"]
1387
+ print("COMPLIANCE")
1388
+ print(f" Score: {comp['score']:.4f}")
1389
+ print(f" Gate: {'PASS' if comp['gate_passed'] else 'FAIL'}")
1390
+ if comp["issues"]:
1391
+ for issue in comp["issues"]:
1392
+ print(f" - {issue}")
1393
+ print()
1394
+
1395
+ bl = dashboard["blockers"]
1396
+ print(f"BLOCKERS ({bl['count']})")
1397
+ if bl["top_items"]:
1398
+ for b in bl["top_items"]:
1399
+ print(f" [{b['id']}] {b['title']} (priority: {b['priority']})")
1400
+ else:
1401
+ print(" None")
1402
+ print()
1403
+
1404
+ print("=" * 70)
1405
+ print("CUI // SP-CTI")
1406
+ print("=" * 70)
1407
+
1408
+
1409
+ # ============================================================================
1410
+ # CLI entry point
1411
+ # ============================================================================
1412
+
1413
+ def main():
1414
+ """CLI entry point for the PI-cadenced migration progress tracker.
1415
+
1416
+ Parses arguments and dispatches to the appropriate function.
1417
+ """
1418
+ parser = argparse.ArgumentParser(
1419
+ description=(
1420
+ "CUI // SP-CTI -- SAFe PI-Cadenced Migration Progress Tracker. "
1421
+ "Track migration velocity, burndown, compliance gates, and "
1422
+ "generate PI reports for DoD modernization plans."
1423
+ ),
1424
+ epilog="CUI // SP-CTI",
1425
+ )
1426
+
1427
+ parser.add_argument(
1428
+ "--plan-id", required=True,
1429
+ help="Migration plan identifier (e.g. MP-001)",
1430
+ )
1431
+
1432
+ # Action flags (mutually exclusive)
1433
+ action = parser.add_mutually_exclusive_group(required=True)
1434
+ action.add_argument(
1435
+ "--snapshot", action="store_true",
1436
+ help="Create a PI migration snapshot",
1437
+ )
1438
+ action.add_argument(
1439
+ "--velocity", action="store_true",
1440
+ help="Show velocity metrics across PIs",
1441
+ )
1442
+ action.add_argument(
1443
+ "--burndown", action="store_true",
1444
+ help="Show burndown projection",
1445
+ )
1446
+ action.add_argument(
1447
+ "--compare", action="store_true",
1448
+ help="Compare two PI snapshots (requires --from-pi and --to-pi)",
1449
+ )
1450
+ action.add_argument(
1451
+ "--assign", action="store_true",
1452
+ help="Assign tasks to a PI (requires --pi and --tasks)",
1453
+ )
1454
+ action.add_argument(
1455
+ "--pi-report", action="store_true",
1456
+ help="Generate a PI migration report (requires --pi)",
1457
+ )
1458
+ action.add_argument(
1459
+ "--gate", action="store_true",
1460
+ help="Check compliance gate for a PI (requires --pi)",
1461
+ )
1462
+ action.add_argument(
1463
+ "--update-task", action="store_true",
1464
+ help="Update a task status (requires --task-id and --status)",
1465
+ )
1466
+ action.add_argument(
1467
+ "--dashboard", action="store_true",
1468
+ help="Show migration dashboard summary",
1469
+ )
1470
+
1471
+ # Supporting arguments
1472
+ parser.add_argument("--pi", help="PI label (e.g. PI-25.3)")
1473
+ parser.add_argument(
1474
+ "--type", dest="snapshot_type", default="manual",
1475
+ choices=VALID_SNAPSHOT_TYPES,
1476
+ help="Snapshot type (default: manual)",
1477
+ )
1478
+ parser.add_argument("--notes", help="Notes for the snapshot")
1479
+ parser.add_argument("--from-pi", help="Starting PI for comparison")
1480
+ parser.add_argument("--to-pi", help="Ending PI for comparison")
1481
+ parser.add_argument(
1482
+ "--tasks",
1483
+ help="Comma-separated list of task IDs (for --assign)",
1484
+ )
1485
+ parser.add_argument("--task-id", help="Task ID (for --update-task)")
1486
+ parser.add_argument(
1487
+ "--status",
1488
+ choices=VALID_TASK_STATUSES,
1489
+ help="Task status (for --update-task)",
1490
+ )
1491
+ parser.add_argument(
1492
+ "--hours", type=float,
1493
+ help="Actual hours spent (for --update-task)",
1494
+ )
1495
+ parser.add_argument("--output-dir", help="Output directory for reports")
1496
+ parser.add_argument(
1497
+ "--json", action="store_true", dest="output_json",
1498
+ help="Output results as JSON",
1499
+ )
1500
+
1501
+ args = parser.parse_args()
1502
+
1503
+ try:
1504
+ # --- Snapshot ---
1505
+ if args.snapshot:
1506
+ if not args.pi:
1507
+ parser.error("--pi is required for --snapshot")
1508
+ result = create_pi_migration_snapshot(
1509
+ plan_id=args.plan_id,
1510
+ pi_number=args.pi,
1511
+ snapshot_type=args.snapshot_type,
1512
+ notes=args.notes,
1513
+ )
1514
+ if args.output_json:
1515
+ print(json.dumps(result, indent=2, default=str))
1516
+ else:
1517
+ print("=" * 60)
1518
+ print("CUI // SP-CTI")
1519
+ print("=" * 60)
1520
+ print(f"Snapshot created for {args.plan_id} at {args.pi}")
1521
+ print(f" Type: {result['snapshot_type']}")
1522
+ print(f" Tasks Total: {result['tasks_total']}")
1523
+ print(f" Tasks Completed: {result['tasks_completed']}")
1524
+ print(f" Tasks In Progress: {result['tasks_in_progress']}")
1525
+ print(f" Tasks Blocked: {result['tasks_blocked']}")
1526
+ print(f" Components Migrated:{result['components_migrated']}")
1527
+ print(f" APIs Migrated: {result['apis_migrated']}")
1528
+ print(f" Tables Migrated: {result['tables_migrated']}")
1529
+ print(f" Test Coverage: {result['test_coverage']:.2%}")
1530
+ print(f" Compliance Score: {result['compliance_score']:.4f}")
1531
+ print(f" Hours Spent: {result['hours_spent']}")
1532
+ print("=" * 60)
1533
+ print("CUI // SP-CTI")
1534
+ print("=" * 60)
1535
+
1536
+ # --- Velocity ---
1537
+ elif args.velocity:
1538
+ result = get_migration_velocity(args.plan_id)
1539
+ if args.output_json:
1540
+ print(json.dumps(result, indent=2, default=str))
1541
+ else:
1542
+ print("=" * 60)
1543
+ print("CUI // SP-CTI")
1544
+ print("=" * 60)
1545
+ print(f"Migration Velocity: {args.plan_id}")
1546
+ print(f" Trend: {result['trend']}")
1547
+ print(f" Avg Tasks/PI: {result['averages']['tasks']}")
1548
+ print(f" Avg Components/PI: {result['averages']['components']}")
1549
+ print(f" Avg Hours/PI: {result['averages']['hours']}")
1550
+ print()
1551
+ if result["snapshots"]:
1552
+ print(" PI-by-PI Breakdown:")
1553
+ for d in result["snapshots"]:
1554
+ print(
1555
+ f" {d['pi']}: "
1556
+ f"{d['tasks_completed_delta']} tasks, "
1557
+ f"{d['components_delta']} components, "
1558
+ f"{d['hours_delta']} hours"
1559
+ )
1560
+ print("=" * 60)
1561
+ print("CUI // SP-CTI")
1562
+ print("=" * 60)
1563
+
1564
+ # --- Burndown ---
1565
+ elif args.burndown:
1566
+ result = get_migration_burndown(args.plan_id)
1567
+ if args.output_json:
1568
+ print(json.dumps(result, indent=2, default=str))
1569
+ else:
1570
+ print("=" * 60)
1571
+ print("CUI // SP-CTI")
1572
+ print("=" * 60)
1573
+ print(f"Migration Burndown: {args.plan_id}")
1574
+ print(f" Total Tasks: {result.get('total_tasks', 'N/A')}")
1575
+ print(f" Completed: {result.get('completed_tasks', 'N/A')}")
1576
+ print(f" Remaining: {result.get('remaining_tasks', 'N/A')}")
1577
+ print(f" Velocity: {result.get('avg_tasks_per_pi', 'N/A')} tasks/PI")
1578
+ print(f" Remaining PIs: {result.get('remaining_pis', 'N/A')}")
1579
+ print(f" Projected Done: {result.get('projected_completion_pi', 'N/A')}")
1580
+ print(f" On Track: {'YES' if result.get('on_track') else 'NO'}")
1581
+ print()
1582
+ if result.get("burndown_data"):
1583
+ print(" Burndown Data:")
1584
+ for bd in result["burndown_data"]:
1585
+ print(
1586
+ f" {bd['pi_number']}: "
1587
+ f"{bd['tasks_remaining']} remaining "
1588
+ f"(ideal: {bd['ideal_remaining']})"
1589
+ )
1590
+ print("=" * 60)
1591
+ print("CUI // SP-CTI")
1592
+ print("=" * 60)
1593
+
1594
+ # --- Compare ---
1595
+ elif args.compare:
1596
+ if not args.from_pi or not args.to_pi:
1597
+ parser.error("--from-pi and --to-pi are required for --compare")
1598
+ result = compare_pi_snapshots(
1599
+ args.plan_id, args.from_pi, args.to_pi,
1600
+ )
1601
+ if args.output_json:
1602
+ print(json.dumps(result, indent=2, default=str))
1603
+ else:
1604
+ if "error" in result:
1605
+ print(f"ERROR: {result['error']}")
1606
+ sys.exit(1)
1607
+ print("=" * 60)
1608
+ print("CUI // SP-CTI")
1609
+ print("=" * 60)
1610
+ print(f"PI Comparison: {args.from_pi} -> {args.to_pi}")
1611
+ print(f" Plan: {args.plan_id}")
1612
+ print()
1613
+ print(" Highlights:")
1614
+ for h in result.get("highlights", []):
1615
+ print(f" - {h}")
1616
+ print()
1617
+ print(" Deltas:")
1618
+ for key, val in result.get("deltas", {}).items():
1619
+ print(f" {key:<25} {val:>+10}")
1620
+ print("=" * 60)
1621
+ print("CUI // SP-CTI")
1622
+ print("=" * 60)
1623
+
1624
+ # --- Assign ---
1625
+ elif args.assign:
1626
+ if not args.pi:
1627
+ parser.error("--pi is required for --assign")
1628
+ if not args.tasks:
1629
+ parser.error("--tasks is required for --assign")
1630
+ task_ids = [t.strip() for t in args.tasks.split(",") if t.strip()]
1631
+ count = assign_tasks_to_pi(args.plan_id, args.pi, task_ids)
1632
+ if args.output_json:
1633
+ print(json.dumps({
1634
+ "plan_id": args.plan_id,
1635
+ "pi_number": args.pi,
1636
+ "tasks_requested": len(task_ids),
1637
+ "tasks_assigned": count,
1638
+ }, indent=2))
1639
+ else:
1640
+ print(f"Assigned {count}/{len(task_ids)} tasks to {args.pi}")
1641
+
1642
+ # --- PI Report ---
1643
+ elif args.pi_report:
1644
+ if not args.pi:
1645
+ parser.error("--pi is required for --pi-report")
1646
+ result = generate_pi_migration_report(
1647
+ plan_id=args.plan_id,
1648
+ pi_number=args.pi,
1649
+ output_dir=args.output_dir,
1650
+ )
1651
+ if args.output_dir:
1652
+ print(f"Report written to: {result}")
1653
+ else:
1654
+ print(result)
1655
+
1656
+ # --- Gate ---
1657
+ elif args.gate:
1658
+ if not args.pi:
1659
+ parser.error("--pi is required for --gate")
1660
+ result = check_pi_compliance_gate(args.plan_id, args.pi)
1661
+ if args.output_json:
1662
+ print(json.dumps(result, indent=2, default=str))
1663
+ else:
1664
+ print("=" * 60)
1665
+ print("CUI // SP-CTI")
1666
+ print("=" * 60)
1667
+ gate_label = "PASS" if result["passed"] else "FAIL"
1668
+ print(f"Compliance Gate: {gate_label}")
1669
+ print(f" Plan: {result['plan_id']}")
1670
+ print(f" PI: {result['pi_number']}")
1671
+ print(f" Score: {result['score']:.4f}")
1672
+ print(f" Threshold: {result['threshold']}")
1673
+ if result["issues"]:
1674
+ print(" Issues:")
1675
+ for issue in result["issues"]:
1676
+ print(f" - {issue}")
1677
+ print("=" * 60)
1678
+ print("CUI // SP-CTI")
1679
+ print("=" * 60)
1680
+
1681
+ # --- Update Task ---
1682
+ elif args.update_task:
1683
+ if not args.task_id:
1684
+ parser.error("--task-id is required for --update-task")
1685
+ if not args.status:
1686
+ parser.error("--status is required for --update-task")
1687
+ result = update_task_status(
1688
+ task_id=args.task_id,
1689
+ status=args.status,
1690
+ actual_hours=args.hours,
1691
+ )
1692
+ if args.output_json:
1693
+ print(json.dumps(result, indent=2, default=str))
1694
+ else:
1695
+ if "error" in result:
1696
+ print(f"ERROR: {result['error']}")
1697
+ sys.exit(1)
1698
+ print(f"Task {args.task_id} updated to '{args.status}'")
1699
+ if args.hours is not None:
1700
+ print(f" Actual hours: {args.hours}")
1701
+
1702
+ # --- Dashboard ---
1703
+ elif args.dashboard:
1704
+ result = get_dashboard(args.plan_id)
1705
+ if args.output_json:
1706
+ print(json.dumps(result, indent=2, default=str))
1707
+ else:
1708
+ if "error" in result:
1709
+ print(f"ERROR: {result['error']}")
1710
+ sys.exit(1)
1711
+ _print_dashboard(result)
1712
+
1713
+ except ValueError as exc:
1714
+ print(f"ERROR: {exc}", file=sys.stderr)
1715
+ sys.exit(1)
1716
+ except sqlite3.Error as exc:
1717
+ print(f"ERROR: Database error: {exc}", file=sys.stderr)
1718
+ sys.exit(1)
1719
+ except Exception as exc:
1720
+ print(f"ERROR: {exc}", file=sys.stderr)
1721
+ sys.exit(1)
1722
+
1723
+
1724
+ if __name__ == "__main__":
1725
+ main()
1726
+ # [TEMPLATE: CUI // SP-CTI]