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,1986 @@
1
+ #!/usr/bin/env python3
2
+ # CUI // SP-CTI
3
+ """
4
+ ICDEV Web Dashboard - Flask Application
5
+ ========================================
6
+ Provides a web interface for monitoring projects, agents, compliance,
7
+ and system health within the ICDEV framework.
8
+
9
+ Usage:
10
+ python tools/dashboard/app.py [--port 5000] [--debug]
11
+ """
12
+
13
+ import argparse
14
+ import sqlite3
15
+ import sys
16
+ import uuid
17
+ from datetime import datetime, timezone
18
+ from pathlib import Path
19
+ from icdev._paths import get_project_root
20
+
21
+ # ---------------------------------------------------------------------------
22
+ # Path setup (so `tools.dashboard.config` is importable when run directly)
23
+ # ---------------------------------------------------------------------------
24
+ BASE_DIR = get_project_root()
25
+ if str(BASE_DIR) not in sys.path:
26
+ sys.path.insert(0, str(BASE_DIR))
27
+
28
+ from flask import Flask, render_template, jsonify, request as flask_request, g, session as flask_session, redirect, url_for, flash
29
+
30
+ from icdev.tools.dashboard.config import (
31
+ DB_PATH,
32
+ CUI_BANNER_TOP,
33
+ CUI_BANNER_BOTTOM,
34
+ CUI_DESIGNATION,
35
+ CUI_BANNER_ENABLED,
36
+ BYOK_ENABLED,
37
+ PORT,
38
+ DEBUG,
39
+ )
40
+ from icdev.tools.dashboard.auth import register_dashboard_auth, validate_api_key, log_auth_event
41
+ from icdev.tools.dashboard.websocket import init_socketio, get_socketio
42
+ from icdev.tools.dashboard.api.projects import projects_api
43
+ from icdev.tools.dashboard.api.agents import agents_api
44
+ from icdev.tools.dashboard.api.compliance import compliance_api
45
+ from icdev.tools.dashboard.api.audit import audit_api
46
+ from icdev.tools.dashboard.api.metrics import metrics_api
47
+ from icdev.tools.dashboard.api.events import events_bp
48
+ from icdev.tools.dashboard.api.nlq import nlq_bp
49
+ from icdev.tools.dashboard.api.batch import batch_api
50
+ from icdev.tools.dashboard.api.diagrams import diagrams_api
51
+ from icdev.tools.dashboard.api.cicd import cicd_api
52
+ from icdev.tools.dashboard.api.intake import intake_api
53
+ from icdev.tools.dashboard.api.admin import admin_api
54
+ from icdev.tools.dashboard.api.activity import activity_api
55
+ from icdev.tools.dashboard.api.usage import usage_api
56
+ from icdev.tools.dashboard.api.traces import traces_api, provenance_api, xai_api
57
+ from icdev.tools.dashboard.api.oscal import oscal_api
58
+ from icdev.tools.dashboard.api.prod_audit import prod_audit_api
59
+ from icdev.tools.dashboard.api.ai_transparency import ai_transparency_api
60
+ from icdev.tools.dashboard.api.ai_accountability import ai_accountability_api
61
+ from icdev.tools.dashboard.api.code_quality import code_quality_api
62
+ from icdev.tools.dashboard.api.fedramp_20x import fedramp_20x_api
63
+ from icdev.tools.dashboard.api.evidence import evidence_api
64
+ from icdev.tools.dashboard.api.lineage import lineage_api
65
+ # D-CHILD-6: GovProposal/CPMP/GovCon conditionally loaded
66
+ import os as _os
67
+ _GOVCON_ENABLED = _os.environ.get("ICDEV_GOVCON_ENABLED", "false").lower() == "true"
68
+ _HAS_GOVCON = False
69
+ if _GOVCON_ENABLED:
70
+ try:
71
+ from icdev.tools.dashboard.api.proposals import proposals_api
72
+ from icdev.tools.dashboard.api.govcon import govcon_api
73
+ from icdev.tools.dashboard.api.cpmp import cpmp_api
74
+ _HAS_GOVCON = True
75
+ except ImportError:
76
+ _HAS_GOVCON = False
77
+ from icdev.tools.dashboard.api.orchestration import orchestration_api
78
+ try:
79
+ from icdev.tools.dashboard.api.chat import chat_api
80
+ _HAS_CHAT_API = True
81
+ except ImportError:
82
+ _HAS_CHAT_API = False
83
+ from icdev.tools.dashboard.ux_helpers import register_ux_filters
84
+
85
+ # ---------------------------------------------------------------------------
86
+ # GovCon/CPMP/Proposals page registration (D-CHILD-6: isolated)
87
+ # ---------------------------------------------------------------------------
88
+
89
+
90
+ def _register_govcon_pages(app: "Flask", _get_db):
91
+ """Register GovProposal/CPMP/GovCon SSR page routes on the Flask app.
92
+
93
+ Called only when _HAS_GOVCON is True. Extracted from create_app() so that
94
+ child apps (and parent apps with ICDEV_GOVCON_ENABLED=false) never register
95
+ these routes.
96
+ """
97
+
98
+ @app.route("/cpmp")
99
+ def cpmp_portfolio_page():
100
+ """CPMP Portfolio — contract performance overview, health scoring."""
101
+ try:
102
+ from icdev.tools.govcon.portfolio_manager import get_portfolio_summary
103
+ portfolio_data = get_portfolio_summary()
104
+ pf = portfolio_data.get("portfolio", {})
105
+ contracts = pf.get("contracts", [])
106
+ upcoming = pf.get("upcoming_deliverables", [])
107
+ portfolio = {
108
+ "total_contracts": pf.get("total_contracts", 0),
109
+ "active_contracts": pf.get("active_contracts", 0),
110
+ "total_value": pf.get("total_value", 0),
111
+ "burn_rate": pf.get("burn_rate_pct", 0),
112
+ "overdue_deliverables": pf.get("overdue_deliverables", 0),
113
+ "at_risk": pf.get("at_risk_contracts", 0),
114
+ "health_distribution": pf.get("health_distribution", {"green": 0, "yellow": 0, "red": 0}),
115
+ }
116
+ return render_template("cpmp/portfolio.html", portfolio=portfolio, contracts=contracts, upcoming_deliverables=upcoming)
117
+ except Exception as e:
118
+ import traceback; traceback.print_exc()
119
+ return render_template("cpmp/portfolio.html", portfolio={"total_contracts": 0, "active_contracts": 0, "total_value": 0, "burn_rate": 0, "overdue_deliverables": 0, "health_distribution": {"green": 0, "yellow": 0, "red": 0}}, contracts=[], upcoming_deliverables=[], error=str(e))
120
+
121
+ @app.route("/cpmp/<contract_id>")
122
+ def cpmp_detail_page(contract_id):
123
+ """CPMP Contract Detail — 7-tab view."""
124
+ try:
125
+ from icdev.tools.govcon.contract_manager import get_contract, list_clins, list_wbs, list_deliverables
126
+ contract_result = get_contract(contract_id)
127
+ if contract_result.get("status") == "error":
128
+ return render_template("404.html", message="Contract not found"), 404
129
+ contract = contract_result.get("contract", contract_result)
130
+ clins = list_clins(contract_id).get("clins", [])
131
+ wbs_elements = list_wbs(contract_id).get("wbs_elements", [])
132
+ deliverables = list_deliverables(contract_id).get("deliverables", [])
133
+ try:
134
+ from icdev.tools.govcon.subcontractor_tracker import list_subcontractors
135
+ subcontractors = list_subcontractors(contract_id).get("subcontractors", [])
136
+ except Exception:
137
+ subcontractors = []
138
+ try:
139
+ from icdev.tools.govcon.evm_engine import aggregate_contract_evm
140
+ evm = aggregate_contract_evm(contract_id)
141
+ if "indicators" in evm and isinstance(evm["indicators"], dict):
142
+ evm.update(evm["indicators"])
143
+ except Exception:
144
+ evm = {}
145
+ try:
146
+ from icdev.tools.govcon.cpars_predictor import predict_cpars, list_assessments
147
+ cpars_prediction = predict_cpars(contract_id)
148
+ if "dimension_scores" in cpars_prediction:
149
+ cpars_prediction["dimensions"] = {
150
+ k: round(v * 5, 2) for k, v in cpars_prediction["dimension_scores"].items()
151
+ }
152
+ cpars_assessments = list_assessments(contract_id).get("assessments", [])
153
+ except Exception:
154
+ cpars_prediction = {}
155
+ cpars_assessments = []
156
+ return render_template("cpmp/detail.html",
157
+ contract=contract, clins=clins, wbs_elements=wbs_elements,
158
+ deliverables=deliverables, subcontractors=subcontractors,
159
+ evm=evm, cpars_prediction=cpars_prediction,
160
+ cpars_assessments=cpars_assessments)
161
+ except Exception as e:
162
+ import traceback; traceback.print_exc()
163
+ return render_template("404.html", message=f"Error loading contract: {e}"), 500
164
+
165
+ @app.route("/cpmp/<contract_id>/deliverables/<deliverable_id>")
166
+ def cpmp_deliverable_detail_page(contract_id, deliverable_id):
167
+ """CPMP Deliverable Detail — status pipeline, CDRL generation."""
168
+ try:
169
+ from icdev.tools.govcon.contract_manager import get_contract, get_deliverable
170
+ contract_result = get_contract(contract_id)
171
+ contract = contract_result.get("contract", contract_result) if contract_result.get("status") == "ok" else {}
172
+ deliv_result = get_deliverable(deliverable_id)
173
+ if deliv_result.get("status") == "error":
174
+ return render_template("404.html", message="Deliverable not found"), 404
175
+ deliverable = deliv_result.get("deliverable", deliv_result)
176
+ generations = deliverable.get("generations", []) if isinstance(deliverable, dict) else []
177
+ status_history = deliverable.get("status_history", []) if isinstance(deliverable, dict) else []
178
+ return render_template("cpmp/deliverable_detail.html",
179
+ contract=contract, deliverable=deliverable,
180
+ generations=generations, status_history=status_history)
181
+ except Exception as e:
182
+ import traceback; traceback.print_exc()
183
+ return render_template("404.html", message=f"Error loading deliverable: {e}"), 500
184
+
185
+ @app.route("/cpmp/cor")
186
+ def cpmp_cor_portal_page():
187
+ """COR Portal — read-only government view of assigned contracts."""
188
+ user = getattr(g, "current_user", None)
189
+ cor_email = user.get("email", "") if user else ""
190
+ conn = _get_db()
191
+ try:
192
+ if cor_email:
193
+ rows = conn.execute(
194
+ "SELECT * FROM cpmp_contracts WHERE cor_email = ? ORDER BY created_at DESC",
195
+ (cor_email,),
196
+ ).fetchall()
197
+ contracts = [dict(r) for r in rows]
198
+ else:
199
+ contracts = []
200
+ return render_template("cpmp/cor_portal.html", contracts=contracts, cor_email=cor_email)
201
+ except Exception as e:
202
+ import traceback; traceback.print_exc()
203
+ return render_template("cpmp/cor_portal.html", contracts=[], cor_email=cor_email)
204
+ finally:
205
+ conn.close()
206
+
207
+ @app.route("/cpmp/cor/<contract_id>")
208
+ def cpmp_cor_detail_page(contract_id):
209
+ """COR Contract Detail — read-only, no internal cost data."""
210
+ user = getattr(g, "current_user", None)
211
+ cor_email = user.get("email", "") if user else ""
212
+ conn = _get_db()
213
+ try:
214
+ from icdev.tools.govcon.contract_manager import get_contract, list_deliverables
215
+ contract_result = get_contract(contract_id)
216
+ if contract_result.get("status") == "error":
217
+ return render_template("404.html", message="Contract not found"), 404
218
+ contract = contract_result.get("contract", contract_result)
219
+ deliverables = list_deliverables(contract_id).get("deliverables", [])
220
+ try:
221
+ from icdev.tools.govcon.evm_engine import aggregate_contract_evm
222
+ evm = aggregate_contract_evm(contract_id)
223
+ if "indicators" in evm and isinstance(evm["indicators"], dict):
224
+ evm.update(evm["indicators"])
225
+ if "total_bac" in evm:
226
+ evm.setdefault("bac", evm["total_bac"])
227
+ if "total_pv" in evm:
228
+ evm.setdefault("pv", evm["total_pv"])
229
+ if "total_ev" in evm:
230
+ evm.setdefault("ev", evm["total_ev"])
231
+ if "percent_complete" in evm:
232
+ evm.setdefault("percent_complete_schedule", evm["percent_complete"] / 100 if evm["percent_complete"] > 1 else evm["percent_complete"])
233
+ except Exception:
234
+ evm = {}
235
+ try:
236
+ from icdev.tools.govcon.cpars_predictor import list_assessments
237
+ cpars_assessments = list_assessments(contract_id).get("assessments", [])
238
+ except Exception:
239
+ cpars_assessments = []
240
+ try:
241
+ conn.execute(
242
+ "INSERT INTO cpmp_cor_access_log (id, user_id, contract_id, action, accessed_at, classification) "
243
+ "VALUES (?, ?, ?, ?, ?, ?)",
244
+ (str(uuid.uuid4()), cor_email, contract_id, "view_contract", datetime.now(timezone.utc).isoformat(), "CUI // SP-CTI"),
245
+ )
246
+ conn.commit()
247
+ except Exception:
248
+ pass
249
+ return render_template("cpmp/cor_detail.html",
250
+ contract=contract, deliverables=deliverables,
251
+ evm=evm, cpars_assessments=cpars_assessments, cor_email=cor_email)
252
+ except Exception as e:
253
+ return render_template("404.html", message=f"Error: {e}"), 500
254
+ finally:
255
+ conn.close()
256
+
257
+ @app.route("/proposals")
258
+ def proposals_list_page():
259
+ """Proposal Opportunities — GovCon proposal writing lifecycle tracker."""
260
+ conn = _get_db()
261
+ try:
262
+ rows = conn.execute("SELECT * FROM proposal_opportunities ORDER BY due_date ASC").fetchall()
263
+ opportunities = [dict(r) for r in rows]
264
+ from datetime import date
265
+ today = date.today()
266
+ nearest_deadline = None
267
+ for opp in opportunities:
268
+ if opp.get("due_date") and opp["status"] not in ("submitted", "won", "lost", "cancelled", "no_bid"):
269
+ try:
270
+ dd = date.fromisoformat(opp["due_date"])
271
+ days_left = (dd - today).days
272
+ opp["days_left"] = days_left
273
+ if nearest_deadline is None or days_left < nearest_deadline:
274
+ nearest_deadline = days_left
275
+ except (ValueError, TypeError):
276
+ opp["days_left"] = None
277
+ else:
278
+ opp["days_left"] = None
279
+ return render_template("proposals/list.html", opportunities=opportunities, nearest_deadline=nearest_deadline)
280
+ finally:
281
+ conn.close()
282
+
283
+ @app.route("/proposals/<opp_id>")
284
+ def proposals_detail_page(opp_id):
285
+ """Proposal Opportunity Detail — 6-tab view with sections, compliance, reviews."""
286
+ conn = _get_db()
287
+ try:
288
+ opp = conn.execute("SELECT * FROM proposal_opportunities WHERE id = ?", (opp_id,)).fetchone()
289
+ if not opp:
290
+ return render_template("404.html", message="Opportunity not found"), 404
291
+ opp = dict(opp)
292
+ sections = [dict(r) for r in conn.execute(
293
+ """SELECT s.*, v.volume_number, v.title as volume_title
294
+ FROM proposal_sections s
295
+ LEFT JOIN proposal_volumes v ON s.volume_id = v.id
296
+ WHERE s.opportunity_id = ?
297
+ ORDER BY v.volume_number, s.section_number""", (opp_id,)
298
+ ).fetchall()]
299
+ from datetime import date
300
+ today = date.today()
301
+ for s in sections:
302
+ s["overdue"] = False
303
+ if s.get("due_date") and s["status"] not in ("final", "submitted"):
304
+ try:
305
+ s["overdue"] = date.fromisoformat(s["due_date"]) < today
306
+ except (ValueError, TypeError):
307
+ pass
308
+ volumes = [dict(r) for r in conn.execute(
309
+ "SELECT * FROM proposal_volumes WHERE opportunity_id = ? ORDER BY volume_number", (opp_id,)
310
+ ).fetchall()]
311
+ compliance_items = [dict(r) for r in conn.execute(
312
+ "SELECT * FROM proposal_compliance_matrix WHERE opportunity_id = ?", (opp_id,)
313
+ ).fetchall()]
314
+ reviews = [dict(r) for r in conn.execute(
315
+ "SELECT * FROM proposal_reviews WHERE opportunity_id = ? ORDER BY scheduled_date", (opp_id,)
316
+ ).fetchall()]
317
+ findings = [dict(r) for r in conn.execute(
318
+ """SELECT f.*, r.review_type FROM proposal_review_findings f
319
+ JOIN proposal_reviews r ON f.review_id = r.id
320
+ WHERE r.opportunity_id = ?""", (opp_id,)
321
+ ).fetchall()]
322
+ total_sections = len(sections)
323
+ completed_sections = len([s for s in sections if s["status"] in ("final", "submitted")])
324
+ total_compliance = len(compliance_items)
325
+ compliant_count = len([c for c in compliance_items if c.get("compliance_status") == "compliant"])
326
+ coverage_pct = (compliant_count / total_compliance * 100) if total_compliance > 0 else 0
327
+ open_findings = len([f for f in findings if f.get("status") in ("open", "in_progress")])
328
+ critical_findings = len([f for f in findings if f.get("severity") == "critical" and f.get("status") in ("open", "in_progress")])
329
+ section_status_dist = {}
330
+ for s in sections:
331
+ st = s.get("status", "not_started")
332
+ section_status_dist[st] = section_status_dist.get(st, 0) + 1
333
+ finding_severity_dist = {}
334
+ for f in findings:
335
+ if f.get("status") in ("open", "in_progress"):
336
+ sev = f.get("severity", "minor")
337
+ finding_severity_dist[sev] = finding_severity_dist.get(sev, 0) + 1
338
+ cm_compliant = len([c for c in compliance_items if c.get("compliance_status") == "compliant"])
339
+ cm_partial = len([c for c in compliance_items if c.get("compliance_status") == "partial"])
340
+ cm_non_compliant = len([c for c in compliance_items if c.get("compliance_status") == "non_compliant"])
341
+ cm_not_addressed = len([c for c in compliance_items if c.get("compliance_status") == "not_addressed"])
342
+ cm_not_applicable = len([c for c in compliance_items if c.get("compliance_status") == "not_applicable"])
343
+ cm_gap_pct = round(cm_not_addressed / total_compliance * 100) if total_compliance > 0 else 0
344
+ compliance_stats = {
345
+ "total": total_compliance, "compliant": cm_compliant, "partial": cm_partial,
346
+ "non_compliant": cm_non_compliant, "not_addressed": cm_not_addressed,
347
+ "not_applicable": cm_not_applicable, "gap_pct": cm_gap_pct,
348
+ }
349
+ findings_by_review = {}
350
+ for f in findings:
351
+ rid = f.get("review_id")
352
+ if rid:
353
+ findings_by_review.setdefault(rid, []).append(f)
354
+ reviews_data = []
355
+ for rev in reviews:
356
+ rd = dict(rev)
357
+ rd["findings"] = findings_by_review.get(rev["id"], [])
358
+ reviews_data.append(rd)
359
+ days_left = None
360
+ if opp.get("due_date"):
361
+ try:
362
+ days_left = (date.fromisoformat(opp["due_date"]) - today).days
363
+ except (ValueError, TypeError):
364
+ pass
365
+ stats = {
366
+ "sections_total": total_sections, "sections_complete": completed_sections,
367
+ "compliance_coverage_pct": round(coverage_pct), "open_findings": open_findings,
368
+ "critical_findings": critical_findings, "section_status_distribution": section_status_dist,
369
+ "finding_severity_distribution": finding_severity_dist,
370
+ }
371
+ questions = [dict(r) for r in conn.execute(
372
+ "SELECT * FROM proposal_questions WHERE opportunity_id = ? ORDER BY question_number ASC", (opp_id,),
373
+ ).fetchall()]
374
+ question_stats = {
375
+ "total": len(questions),
376
+ "high_priority": len([q for q in questions if q.get("priority") == "high"]),
377
+ "draft": len([q for q in questions if q.get("status") == "draft"]),
378
+ "approved": len([q for q in questions if q.get("status") == "approved"]),
379
+ "submitted": len([q for q in questions if q.get("status") == "submitted"]),
380
+ "answered": len([q for q in questions if q.get("status") == "answered"]),
381
+ }
382
+ questions_days_left = None
383
+ if opp.get("questions_due_date"):
384
+ try:
385
+ questions_days_left = (date.fromisoformat(opp["questions_due_date"]) - today).days
386
+ except (ValueError, TypeError):
387
+ pass
388
+ amendments = [dict(r) for r in conn.execute(
389
+ "SELECT * FROM proposal_amendments WHERE opportunity_id = ? ORDER BY version_number ASC", (opp_id,),
390
+ ).fetchall()]
391
+ responses = {}
392
+ for q in questions:
393
+ if q.get("status") == "answered":
394
+ resp = conn.execute(
395
+ "SELECT * FROM proposal_question_responses WHERE question_id = ? ORDER BY created_at DESC LIMIT 1",
396
+ (q["id"],),
397
+ ).fetchone()
398
+ if resp:
399
+ responses[q["id"]] = dict(resp)
400
+ return render_template("proposals/detail.html",
401
+ opp=opp, sections=sections, volumes=volumes,
402
+ compliance_items=compliance_items, reviews=reviews_data, findings=findings,
403
+ stats=stats, compliance_stats=compliance_stats,
404
+ reviews_data=reviews_data, days_left=days_left,
405
+ questions=questions, question_stats=question_stats,
406
+ questions_days_left=questions_days_left,
407
+ amendments=amendments, responses=responses)
408
+ finally:
409
+ conn.close()
410
+
411
+ @app.route("/proposals/<opp_id>/sections/<sec_id>")
412
+ def proposals_section_detail_page(opp_id, sec_id):
413
+ """Proposal Section Detail — status pipeline, notes, compliance, findings, history."""
414
+ conn = _get_db()
415
+ try:
416
+ section = conn.execute(
417
+ """SELECT s.*, v.volume_number, v.title as volume_title
418
+ FROM proposal_sections s
419
+ LEFT JOIN proposal_volumes v ON s.volume_id = v.id
420
+ WHERE s.id = ? AND s.opportunity_id = ?""",
421
+ (sec_id, opp_id)).fetchone()
422
+ if not section:
423
+ return render_template("404.html", message="Section not found"), 404
424
+ section = dict(section)
425
+ opp = conn.execute("SELECT title FROM proposal_opportunities WHERE id = ?", (opp_id,)).fetchone()
426
+ opp_title = opp["title"] if opp else "Unknown"
427
+ from icdev.tools.dashboard.api.proposals import SECTION_TRANSITIONS
428
+ section["valid_transitions"] = SECTION_TRANSITIONS.get(section["status"], [])
429
+ from datetime import date
430
+ section["overdue"] = False
431
+ if section.get("due_date") and section["status"] not in ("final", "submitted"):
432
+ try:
433
+ section["overdue"] = date.fromisoformat(section["due_date"]) < date.today()
434
+ except (ValueError, TypeError):
435
+ pass
436
+ section["compliance_items"] = [dict(r) for r in conn.execute(
437
+ "SELECT * FROM proposal_compliance_matrix WHERE proposal_section_id = ?", (sec_id,)
438
+ ).fetchall()]
439
+ section["findings"] = [dict(r) for r in conn.execute(
440
+ """SELECT f.*, r.review_type FROM proposal_review_findings f
441
+ JOIN proposal_reviews r ON f.review_id = r.id
442
+ WHERE f.section_id = ?""", (sec_id,)
443
+ ).fetchall()]
444
+ deps = conn.execute(
445
+ """SELECT d.*, s.title as depends_on_title, s.status as depends_on_status
446
+ FROM proposal_section_dependencies d
447
+ JOIN proposal_sections s ON d.depends_on_section_id = s.id
448
+ WHERE d.section_id = ?""", (sec_id,)
449
+ ).fetchall()
450
+ dep_list = []
451
+ for d in deps:
452
+ d = dict(d)
453
+ from icdev.tools.dashboard.api.proposals import SECTION_STATUS_ORDER
454
+ req_idx = SECTION_STATUS_ORDER.index(d["required_status"]) if d["required_status"] in SECTION_STATUS_ORDER else 0
455
+ cur_idx = SECTION_STATUS_ORDER.index(d["depends_on_status"]) if d["depends_on_status"] in SECTION_STATUS_ORDER else 0
456
+ d["met"] = cur_idx >= req_idx
457
+ dep_list.append(d)
458
+ section["dependencies"] = dep_list
459
+ section["history"] = [dict(r) for r in conn.execute(
460
+ "SELECT * FROM proposal_status_history WHERE entity_id = ? ORDER BY created_at DESC", (sec_id,)
461
+ ).fetchall()]
462
+ return render_template("proposals/section_detail.html", section=section, opp_title=opp_title)
463
+ finally:
464
+ conn.close()
465
+
466
+ @app.route("/govcon")
467
+ def govcon_pipeline_page():
468
+ """GovCon Intelligence — pipeline status, recent opportunities, domain distribution."""
469
+ conn = _get_db()
470
+ try:
471
+ from icdev.tools.govcon.govcon_engine import get_status
472
+ stats = get_status()
473
+ try:
474
+ opps = conn.execute("SELECT * FROM sam_gov_opportunities ORDER BY posted_date DESC LIMIT 25").fetchall()
475
+ opportunities = [dict(r) for r in opps]
476
+ except Exception:
477
+ opportunities = []
478
+ linked_opp_ids = set()
479
+ try:
480
+ linked = conn.execute("SELECT sam_gov_opportunity_id FROM proposal_opportunities WHERE sam_gov_opportunity_id IS NOT NULL").fetchall()
481
+ linked_opp_ids = {r["sam_gov_opportunity_id"] for r in linked}
482
+ except Exception:
483
+ pass
484
+ return render_template("govcon/pipeline.html", stats=stats, opportunities=opportunities, linked_opp_ids=linked_opp_ids)
485
+ except Exception:
486
+ stats = {"total_opportunities": 0, "total_requirements": 0, "total_patterns": 0,
487
+ "total_capability_maps": 0, "total_drafts": 0, "total_awards": 0,
488
+ "knowledge_blocks": 0, "linked_proposals": 0, "domain_distribution": {},
489
+ "last_pipeline_run": None}
490
+ return render_template("govcon/pipeline.html", stats=stats, opportunities=[], linked_opp_ids=set())
491
+ finally:
492
+ conn.close()
493
+
494
+ @app.route("/govcon/requirements")
495
+ def govcon_requirements_page():
496
+ """GovCon Requirements — pattern frequency, domain heatmap, statement types."""
497
+ conn = _get_db()
498
+ try:
499
+ total_requirements = 0
500
+ try:
501
+ r = conn.execute("SELECT COUNT(*) as cnt FROM rfp_shall_statements").fetchone()
502
+ total_requirements = r["cnt"] if r else 0
503
+ except Exception:
504
+ pass
505
+ total_patterns = 0
506
+ try:
507
+ r = conn.execute("SELECT COUNT(*) as cnt FROM rfp_requirement_patterns").fetchone()
508
+ total_patterns = r["cnt"] if r else 0
509
+ except Exception:
510
+ pass
511
+ domain_stats = {}
512
+ try:
513
+ rows = conn.execute("SELECT domain_category, COUNT(*) as cnt FROM rfp_shall_statements GROUP BY domain_category ORDER BY cnt DESC").fetchall()
514
+ domain_stats = {r["domain_category"]: {"count": r["cnt"]} for r in rows}
515
+ except Exception:
516
+ pass
517
+ domain_count = len(domain_stats)
518
+ patterns = []
519
+ min_frequency = 3
520
+ try:
521
+ rows = conn.execute("SELECT * FROM rfp_requirement_patterns WHERE frequency >= ? ORDER BY frequency DESC LIMIT 30", (min_frequency,)).fetchall()
522
+ patterns = [dict(r) for r in rows]
523
+ except Exception:
524
+ pass
525
+ top_frequency = patterns[0]["frequency"] if patterns else 0
526
+ type_stats = {}
527
+ try:
528
+ rows = conn.execute("SELECT statement_type, COUNT(*) as cnt FROM rfp_shall_statements GROUP BY statement_type ORDER BY cnt DESC").fetchall()
529
+ type_stats = {r["statement_type"]: r["cnt"] for r in rows}
530
+ except Exception:
531
+ pass
532
+ return render_template("govcon/requirements.html",
533
+ total_requirements=total_requirements, total_patterns=total_patterns,
534
+ domain_stats=domain_stats, domain_count=domain_count,
535
+ patterns=patterns, top_frequency=top_frequency,
536
+ type_stats=type_stats, min_frequency=min_frequency)
537
+ finally:
538
+ conn.close()
539
+
540
+ @app.route("/govcon/capabilities")
541
+ def govcon_capabilities_page():
542
+ """GovCon Capabilities — coverage by domain, gap list, enhancement recommendations."""
543
+ conn = _get_db()
544
+ try:
545
+ coverage = {"L": 0, "M": 0, "N": 0, "rate": 0}
546
+ try:
547
+ rows = conn.execute(
548
+ """SELECT
549
+ SUM(CASE WHEN m.coverage_score >= 0.80 THEN 1 ELSE 0 END) as L,
550
+ SUM(CASE WHEN m.coverage_score >= 0.40 AND m.coverage_score < 0.80 THEN 1 ELSE 0 END) as M,
551
+ SUM(CASE WHEN m.coverage_score < 0.40 OR m.coverage_score IS NULL THEN 1 ELSE 0 END) as N,
552
+ COUNT(*) as total
553
+ FROM rfp_shall_statements s
554
+ LEFT JOIN icdev_capability_map m ON s.id = m.pattern_id"""
555
+ ).fetchone()
556
+ if rows and rows["total"] > 0:
557
+ coverage["L"] = rows["L"] or 0
558
+ coverage["M"] = rows["M"] or 0
559
+ coverage["N"] = rows["N"] or 0
560
+ coverage["rate"] = round(coverage["L"] / rows["total"] * 100)
561
+ except Exception:
562
+ pass
563
+ domain_coverage = []
564
+ try:
565
+ rows = conn.execute(
566
+ """SELECT s.domain_category as domain, COUNT(*) as total,
567
+ SUM(CASE WHEN m.coverage_score >= 0.80 THEN 1 ELSE 0 END) as L,
568
+ SUM(CASE WHEN m.coverage_score >= 0.40 AND m.coverage_score < 0.80 THEN 1 ELSE 0 END) as M,
569
+ SUM(CASE WHEN m.coverage_score < 0.40 OR m.coverage_score IS NULL THEN 1 ELSE 0 END) as N
570
+ FROM rfp_shall_statements s
571
+ LEFT JOIN icdev_capability_map m ON s.id = m.pattern_id
572
+ GROUP BY s.domain_category ORDER BY total DESC"""
573
+ ).fetchall()
574
+ domain_coverage = [dict(r) for r in rows]
575
+ except Exception:
576
+ pass
577
+ gaps = []
578
+ total_gaps = 0
579
+ try:
580
+ rows = conn.execute(
581
+ """SELECT p.pattern_name as requirement, p.domain_category as domain,
582
+ p.frequency, COALESCE(m.coverage_score, 0) as coverage,
583
+ p.frequency * (1 - COALESCE(m.coverage_score, 0)) as priority
584
+ FROM rfp_requirement_patterns p
585
+ LEFT JOIN icdev_capability_map m ON p.id = m.pattern_id
586
+ WHERE COALESCE(m.coverage_score, 0) < 0.40
587
+ ORDER BY priority DESC LIMIT 20"""
588
+ ).fetchall()
589
+ gaps = [dict(r) for r in rows]
590
+ total_gaps = len(gaps)
591
+ except Exception:
592
+ pass
593
+ recommendations = []
594
+ try:
595
+ from icdev.tools.govcon.gap_analyzer import generate_recommendations
596
+ rec_result = generate_recommendations()
597
+ recommendations = rec_result.get("recommendations", [])[:15]
598
+ except Exception:
599
+ pass
600
+ return render_template("govcon/capabilities.html",
601
+ coverage=coverage, domain_coverage=domain_coverage,
602
+ gaps=gaps, total_gaps=total_gaps,
603
+ recommendations=recommendations)
604
+ finally:
605
+ conn.close()
606
+
607
+
608
+ # ---------------------------------------------------------------------------
609
+ # App factory
610
+ # ---------------------------------------------------------------------------
611
+
612
+
613
+ def create_app() -> Flask:
614
+ app = Flask(
615
+ __name__,
616
+ template_folder=str(Path(__file__).resolve().parent / "templates"),
617
+ static_folder=str(Path(__file__).resolve().parent / "static"),
618
+ )
619
+
620
+ # Register UX filters (glossary, timestamps, error recovery, quick paths)
621
+ register_ux_filters(app)
622
+
623
+ # Register dashboard auth middleware (D169-D172)
624
+ register_dashboard_auth(app)
625
+
626
+ # Initialize WebSocket (D170 — optional, graceful fallback)
627
+ init_socketio(app)
628
+
629
+ # Correlation ID middleware (D149)
630
+ try:
631
+ from icdev.tools.resilience.correlation import register_correlation_middleware
632
+ register_correlation_middleware(app)
633
+ except ImportError:
634
+ pass
635
+
636
+ # Role-based view configuration
637
+ ROLE_VIEWS = {
638
+ "pm": {
639
+ "label": "Program Manager",
640
+ "show_tabs": ["overview", "compliance", "deployments", "audit"],
641
+ "hide_columns": ["stig_id", "finding_id"],
642
+ },
643
+ "developer": {
644
+ "label": "Developer / Architect",
645
+ "show_tabs": ["overview", "security", "deployments", "audit"],
646
+ "hide_columns": [],
647
+ },
648
+ "isso": {
649
+ "label": "ISSO / Security Officer",
650
+ "show_tabs": ["overview", "compliance", "security", "audit"],
651
+ "hide_columns": [],
652
+ },
653
+ "co": {
654
+ "label": "Contracting Officer",
655
+ "show_tabs": ["overview", "compliance", "deployments"],
656
+ "hide_columns": ["stig_id", "finding_id", "source"],
657
+ },
658
+ "analyst": {
659
+ "label": "Analyst",
660
+ "show_tabs": ["overview", "compliance", "security", "audit"],
661
+ "hide_columns": [],
662
+ },
663
+ "solutions_architect": {
664
+ "label": "Solutions Architect",
665
+ "show_tabs": ["overview", "security", "deployments", "audit"],
666
+ "hide_columns": [],
667
+ },
668
+ "sales_engineer": {
669
+ "label": "Sales Engineer",
670
+ "show_tabs": ["overview", "compliance", "deployments"],
671
+ "hide_columns": ["stig_id", "finding_id"],
672
+ },
673
+ "innovator": {
674
+ "label": "Innovator",
675
+ "show_tabs": ["overview", "security", "deployments", "audit"],
676
+ "hide_columns": [],
677
+ },
678
+ "biz_dev": {
679
+ "label": "Business Development",
680
+ "show_tabs": ["overview", "compliance", "deployments"],
681
+ "hide_columns": ["stig_id", "finding_id", "source"],
682
+ },
683
+ "cor": {
684
+ "label": "Contracting Officer Representative",
685
+ "show_tabs": ["overview", "compliance"],
686
+ "hide_columns": ["stig_id", "finding_id", "source", "internal_cost_details"],
687
+ },
688
+ }
689
+
690
+ # Make CUI config, role, and user info available in all templates
691
+ @app.context_processor
692
+ def inject_cui():
693
+ role = flask_request.args.get("role", "")
694
+ role_config = ROLE_VIEWS.get(role, None)
695
+ current_user = getattr(g, "current_user", None)
696
+ return {
697
+ "cui_banner_top": CUI_BANNER_TOP,
698
+ "cui_banner_bottom": CUI_BANNER_BOTTOM,
699
+ "cui_banner_enabled": CUI_BANNER_ENABLED,
700
+ "cui_designation": CUI_DESIGNATION,
701
+ "current_role": role,
702
+ "role_config": role_config,
703
+ "ROLE_VIEWS": ROLE_VIEWS,
704
+ "current_user": current_user,
705
+ "byok_enabled": BYOK_ENABLED,
706
+ "govcon_enabled": _HAS_GOVCON,
707
+ }
708
+
709
+ # ---- Auto-register A2A agents from card files ----
710
+ try:
711
+ from icdev.tools.a2a.agent_registry import register_all_from_cards
712
+ registered = register_all_from_cards()
713
+ if registered:
714
+ app.logger.info("Auto-registered %d agents from card files", len(registered))
715
+ except Exception as exc:
716
+ app.logger.debug("Agent auto-registration skipped: %s", exc)
717
+
718
+ # ---- Register API blueprints ----
719
+ app.register_blueprint(projects_api)
720
+ app.register_blueprint(agents_api)
721
+ app.register_blueprint(compliance_api)
722
+ app.register_blueprint(audit_api)
723
+ app.register_blueprint(metrics_api)
724
+ app.register_blueprint(events_bp)
725
+ app.register_blueprint(nlq_bp)
726
+ app.register_blueprint(batch_api)
727
+ app.register_blueprint(diagrams_api)
728
+ app.register_blueprint(cicd_api)
729
+ app.register_blueprint(intake_api)
730
+ app.register_blueprint(admin_api)
731
+ app.register_blueprint(activity_api)
732
+ app.register_blueprint(usage_api)
733
+ app.register_blueprint(traces_api)
734
+ app.register_blueprint(provenance_api)
735
+ app.register_blueprint(xai_api)
736
+ app.register_blueprint(oscal_api)
737
+ app.register_blueprint(prod_audit_api)
738
+ app.register_blueprint(ai_transparency_api)
739
+ app.register_blueprint(ai_accountability_api)
740
+ app.register_blueprint(code_quality_api)
741
+ app.register_blueprint(fedramp_20x_api)
742
+ app.register_blueprint(evidence_api)
743
+ app.register_blueprint(lineage_api)
744
+ if _HAS_GOVCON:
745
+ app.register_blueprint(proposals_api)
746
+ app.register_blueprint(govcon_api)
747
+ app.register_blueprint(cpmp_api)
748
+ app.register_blueprint(orchestration_api)
749
+ if _HAS_CHAT_API:
750
+ app.register_blueprint(chat_api)
751
+
752
+ # ---- Convenience JSON routes that match the spec ----
753
+
754
+ @app.route("/api/alerts", methods=["GET"])
755
+ def api_alerts_shortcut():
756
+ """Shortcut: GET /api/alerts -> delegates to metrics alerts."""
757
+ conn = _get_db()
758
+ try:
759
+ rows = conn.execute(
760
+ "SELECT * FROM alerts ORDER BY created_at DESC LIMIT 50"
761
+ ).fetchall()
762
+ return jsonify({"alerts": [dict(r) for r in rows], "total": len(rows)})
763
+ finally:
764
+ conn.close()
765
+
766
+ @app.route("/api/notifications", methods=["GET"])
767
+ def api_notifications():
768
+ """Return current notification-worthy items (firing alerts, overdue POAMs)."""
769
+ conn = _get_db()
770
+ try:
771
+ notifications = []
772
+ firing = conn.execute(
773
+ "SELECT COUNT(*) as cnt FROM alerts WHERE status = 'firing'"
774
+ ).fetchone()["cnt"]
775
+ if firing > 0:
776
+ notifications.append({
777
+ "type": "error",
778
+ "message": f"{firing} alert{'s' if firing > 1 else ''} currently firing",
779
+ "link": "/monitoring",
780
+ })
781
+ open_poam = conn.execute(
782
+ "SELECT COUNT(*) as cnt FROM poam_items WHERE status = 'open'"
783
+ ).fetchone()["cnt"]
784
+ if open_poam > 5:
785
+ notifications.append({
786
+ "type": "warning",
787
+ "message": f"{open_poam} open POA&M items need attention",
788
+ "link": "/projects",
789
+ })
790
+ inactive = conn.execute(
791
+ "SELECT COUNT(*) as cnt FROM agents WHERE status != 'active'"
792
+ ).fetchone()["cnt"]
793
+ if inactive > 0:
794
+ notifications.append({
795
+ "type": "info",
796
+ "message": f"{inactive} agent{'s' if inactive > 1 else ''} inactive",
797
+ "link": "/agents",
798
+ })
799
+ return jsonify({"notifications": notifications})
800
+ finally:
801
+ conn.close()
802
+
803
+ @app.route("/api/charts/overview", methods=["GET"])
804
+ def api_charts_overview():
805
+ """Aggregate chart data for the home dashboard."""
806
+ conn = _get_db()
807
+ try:
808
+ # Project status distribution (donut chart)
809
+ project_statuses = conn.execute(
810
+ "SELECT status, COUNT(*) as cnt FROM projects GROUP BY status"
811
+ ).fetchall()
812
+
813
+ # Alert trend: last 7 days (line chart)
814
+ alert_trend = conn.execute(
815
+ "SELECT DATE(created_at) as day, COUNT(*) as cnt "
816
+ "FROM alerts WHERE created_at >= DATE('now', '-7 days') "
817
+ "GROUP BY DATE(created_at) ORDER BY day"
818
+ ).fetchall()
819
+
820
+ # Compliance posture: open vs closed across POAM + STIG (bar chart)
821
+ poam_open = conn.execute(
822
+ "SELECT COUNT(*) as cnt FROM poam_items WHERE status = 'open'"
823
+ ).fetchone()["cnt"]
824
+ poam_closed = conn.execute(
825
+ "SELECT COUNT(*) as cnt FROM poam_items WHERE status != 'open'"
826
+ ).fetchone()["cnt"]
827
+ stig_open = conn.execute(
828
+ "SELECT COUNT(*) as cnt FROM stig_findings WHERE status = 'Open'"
829
+ ).fetchone()["cnt"]
830
+ stig_closed = conn.execute(
831
+ "SELECT COUNT(*) as cnt FROM stig_findings WHERE status != 'Open'"
832
+ ).fetchone()["cnt"]
833
+
834
+ # Deployment frequency: last 7 days (sparkline)
835
+ deploy_trend = conn.execute(
836
+ "SELECT DATE(created_at) as day, COUNT(*) as cnt "
837
+ "FROM deployments WHERE created_at >= DATE('now', '-7 days') "
838
+ "GROUP BY DATE(created_at) ORDER BY day"
839
+ ).fetchall()
840
+
841
+ # Agent health (gauge: % active)
842
+ total_agents = conn.execute(
843
+ "SELECT COUNT(*) as cnt FROM agents"
844
+ ).fetchone()["cnt"]
845
+ active_agents = conn.execute(
846
+ "SELECT COUNT(*) as cnt FROM agents WHERE status = 'active'"
847
+ ).fetchone()["cnt"]
848
+
849
+ return jsonify({
850
+ "project_statuses": [dict(r) for r in project_statuses],
851
+ "alert_trend": [dict(r) for r in alert_trend],
852
+ "compliance": {
853
+ "poam": {"open": poam_open, "closed": poam_closed},
854
+ "stig": {"open": stig_open, "closed": stig_closed},
855
+ },
856
+ "deploy_trend": [dict(r) for r in deploy_trend],
857
+ "agent_health": {
858
+ "total": total_agents,
859
+ "active": active_agents,
860
+ "ratio": active_agents / total_agents if total_agents > 0 else 1.0,
861
+ },
862
+ })
863
+ finally:
864
+ conn.close()
865
+
866
+ @app.route("/api/charts/project/<project_id>", methods=["GET"])
867
+ def api_charts_project(project_id):
868
+ """Chart data for a specific project detail page."""
869
+ conn = _get_db()
870
+ try:
871
+ # STIG by severity (donut)
872
+ stig_sev = conn.execute(
873
+ "SELECT severity, status, COUNT(*) as cnt "
874
+ "FROM stig_findings WHERE project_id = ? "
875
+ "GROUP BY severity, status",
876
+ (project_id,),
877
+ ).fetchall()
878
+
879
+ # POAM by severity (bar)
880
+ poam_sev = conn.execute(
881
+ "SELECT severity, status, COUNT(*) as cnt "
882
+ "FROM poam_items WHERE project_id = ? "
883
+ "GROUP BY severity, status",
884
+ (project_id,),
885
+ ).fetchall()
886
+
887
+ # Deployment history (line — status over time)
888
+ deploys = conn.execute(
889
+ "SELECT DATE(created_at) as day, status, COUNT(*) as cnt "
890
+ "FROM deployments WHERE project_id = ? "
891
+ "GROUP BY DATE(created_at), status ORDER BY day",
892
+ (project_id,),
893
+ ).fetchall()
894
+
895
+ # Alert trend for project
896
+ alerts = conn.execute(
897
+ "SELECT DATE(created_at) as day, severity, COUNT(*) as cnt "
898
+ "FROM alerts WHERE project_id = ? "
899
+ "GROUP BY DATE(created_at), severity ORDER BY day",
900
+ (project_id,),
901
+ ).fetchall()
902
+
903
+ return jsonify({
904
+ "stig_by_severity": [dict(r) for r in stig_sev],
905
+ "poam_by_severity": [dict(r) for r in poam_sev],
906
+ "deployment_history": [dict(r) for r in deploys],
907
+ "alert_trend": [dict(r) for r in alerts],
908
+ })
909
+ finally:
910
+ conn.close()
911
+
912
+ # ---- HTML page routes ----
913
+
914
+ @app.route("/")
915
+ def index():
916
+ """Dashboard home page with Kanban board."""
917
+ conn = _get_db()
918
+ try:
919
+ # All projects for Kanban board
920
+ projects = conn.execute(
921
+ "SELECT id, name, type, status, classification "
922
+ "FROM projects ORDER BY updated_at DESC, created_at DESC"
923
+ ).fetchall()
924
+ projects = [dict(r) for r in projects]
925
+
926
+ # Agent counts (stat bar)
927
+ total_agents = conn.execute("SELECT COUNT(*) as cnt FROM agents").fetchone()["cnt"]
928
+ active_agents = conn.execute(
929
+ "SELECT COUNT(*) as cnt FROM agents WHERE status = 'active'"
930
+ ).fetchone()["cnt"]
931
+ inactive_agents = total_agents - active_agents
932
+
933
+ # Recent audit entries
934
+ recent_audit = conn.execute(
935
+ "SELECT * FROM audit_trail ORDER BY created_at DESC LIMIT 10"
936
+ ).fetchall()
937
+
938
+ # Recent alerts
939
+ recent_alerts = conn.execute(
940
+ "SELECT * FROM alerts ORDER BY created_at DESC LIMIT 10"
941
+ ).fetchall()
942
+
943
+ # Firing alert count (stat bar)
944
+ firing_alerts = conn.execute(
945
+ "SELECT COUNT(*) as cnt FROM alerts WHERE status = 'firing'"
946
+ ).fetchone()["cnt"]
947
+
948
+ # Open POAM count (stat bar)
949
+ open_poam = conn.execute(
950
+ "SELECT COUNT(*) as cnt FROM poam_items WHERE status = 'open'"
951
+ ).fetchone()["cnt"]
952
+
953
+ # Group projects by status for Kanban columns
954
+ kanban_columns = {
955
+ "planning": [],
956
+ "active": [],
957
+ "completed": [],
958
+ "inactive": [],
959
+ }
960
+ for p in projects:
961
+ status = p.get("status", "inactive")
962
+ if status in kanban_columns:
963
+ kanban_columns[status].append(p)
964
+ else:
965
+ kanban_columns["inactive"].append(p)
966
+
967
+ return render_template(
968
+ "index.html",
969
+ projects=projects,
970
+ kanban_columns=kanban_columns,
971
+ total_projects=len(projects),
972
+ total_agents=total_agents,
973
+ active_agents=active_agents,
974
+ inactive_agents=inactive_agents,
975
+ recent_audit=[dict(r) for r in recent_audit],
976
+ recent_alerts=[dict(r) for r in recent_alerts],
977
+ firing_alerts=firing_alerts,
978
+ open_poam=open_poam,
979
+ )
980
+ finally:
981
+ conn.close()
982
+
983
+ @app.route("/projects")
984
+ def projects_list():
985
+ """Project listing page."""
986
+ conn = _get_db()
987
+ try:
988
+ projects = conn.execute(
989
+ "SELECT id, name, type, status, classification, created_at "
990
+ "FROM projects ORDER BY created_at DESC"
991
+ ).fetchall()
992
+ return render_template("projects/list.html", projects=[dict(r) for r in projects])
993
+ finally:
994
+ conn.close()
995
+
996
+ @app.route("/projects/<project_id>")
997
+ def project_detail(project_id):
998
+ """Project detail page with tabs."""
999
+ conn = _get_db()
1000
+ try:
1001
+ # Project info
1002
+ project = conn.execute("SELECT * FROM projects WHERE id = ?", (project_id,)).fetchone()
1003
+ if not project:
1004
+ return render_template("404.html", message="Project not found"), 404
1005
+ project = dict(project)
1006
+
1007
+ # SSP documents
1008
+ ssps = conn.execute(
1009
+ "SELECT * FROM ssp_documents WHERE project_id = ? ORDER BY created_at DESC",
1010
+ (project_id,),
1011
+ ).fetchall()
1012
+
1013
+ # POAM items
1014
+ poams = conn.execute(
1015
+ "SELECT * FROM poam_items WHERE project_id = ? ORDER BY severity, created_at DESC",
1016
+ (project_id,),
1017
+ ).fetchall()
1018
+
1019
+ # STIG findings
1020
+ stigs = conn.execute(
1021
+ "SELECT * FROM stig_findings WHERE project_id = ? ORDER BY severity, created_at DESC",
1022
+ (project_id,),
1023
+ ).fetchall()
1024
+
1025
+ # SBOM records
1026
+ sboms = conn.execute(
1027
+ "SELECT * FROM sbom_records WHERE project_id = ? ORDER BY generated_at DESC",
1028
+ (project_id,),
1029
+ ).fetchall()
1030
+
1031
+ # Deployments
1032
+ deployments = conn.execute(
1033
+ "SELECT * FROM deployments WHERE project_id = ? ORDER BY created_at DESC",
1034
+ (project_id,),
1035
+ ).fetchall()
1036
+
1037
+ # Audit trail
1038
+ audit_entries = conn.execute(
1039
+ "SELECT * FROM audit_trail WHERE project_id = ? ORDER BY created_at DESC LIMIT 50",
1040
+ (project_id,),
1041
+ ).fetchall()
1042
+
1043
+ # Alerts
1044
+ alerts = conn.execute(
1045
+ "SELECT * FROM alerts WHERE project_id = ? ORDER BY created_at DESC LIMIT 20",
1046
+ (project_id,),
1047
+ ).fetchall()
1048
+
1049
+ # Summaries
1050
+ poam_open = sum(1 for p in poams if dict(p)["status"] == "open")
1051
+ stig_open = sum(1 for s in stigs if dict(s)["status"] == "Open")
1052
+
1053
+ stig_by_severity = {}
1054
+ for s in stigs:
1055
+ sd = dict(s)
1056
+ sev = sd.get("severity", "unknown")
1057
+ if sev not in stig_by_severity:
1058
+ stig_by_severity[sev] = {"open": 0, "closed": 0}
1059
+ if sd["status"] == "Open":
1060
+ stig_by_severity[sev]["open"] += 1
1061
+ else:
1062
+ stig_by_severity[sev]["closed"] += 1
1063
+
1064
+ return render_template(
1065
+ "projects/detail.html",
1066
+ project=project,
1067
+ ssps=[dict(r) for r in ssps],
1068
+ poams=[dict(r) for r in poams],
1069
+ poam_open=poam_open,
1070
+ stigs=[dict(r) for r in stigs],
1071
+ stig_open=stig_open,
1072
+ stig_by_severity=stig_by_severity,
1073
+ sboms=[dict(r) for r in sboms],
1074
+ deployments=[dict(r) for r in deployments],
1075
+ audit_entries=[dict(r) for r in audit_entries],
1076
+ alerts=[dict(r) for r in alerts],
1077
+ )
1078
+ finally:
1079
+ conn.close()
1080
+
1081
+ @app.route("/agents")
1082
+ def agents_list():
1083
+ """Agent status page."""
1084
+ conn = _get_db()
1085
+ try:
1086
+ rows = conn.execute(
1087
+ "SELECT * FROM agents ORDER BY name"
1088
+ ).fetchall()
1089
+ agents = []
1090
+ for r in rows:
1091
+ agent = dict(r)
1092
+ tc = conn.execute(
1093
+ "SELECT COUNT(*) as cnt FROM a2a_tasks "
1094
+ "WHERE target_agent_id = ? AND status IN ('submitted', 'working')",
1095
+ (agent["id"],),
1096
+ ).fetchone()
1097
+ agent["active_task_count"] = tc["cnt"] if tc else 0
1098
+ agents.append(agent)
1099
+
1100
+ active = sum(1 for a in agents if a["status"] == "active")
1101
+ inactive = len(agents) - active
1102
+
1103
+ return render_template(
1104
+ "agents/list.html",
1105
+ agents=agents,
1106
+ active_count=active,
1107
+ inactive_count=inactive,
1108
+ )
1109
+ finally:
1110
+ conn.close()
1111
+
1112
+ @app.route("/monitoring")
1113
+ def monitoring_overview():
1114
+ """Monitoring overview page."""
1115
+ conn = _get_db()
1116
+ try:
1117
+ # Recent alerts
1118
+ alerts = conn.execute(
1119
+ "SELECT * FROM alerts ORDER BY created_at DESC LIMIT 20"
1120
+ ).fetchall()
1121
+
1122
+ # Self-healing events
1123
+ healing_events = conn.execute(
1124
+ "SELECT she.*, kp.description as pattern_description "
1125
+ "FROM self_healing_events she "
1126
+ "LEFT JOIN knowledge_patterns kp ON she.pattern_id = kp.id "
1127
+ "ORDER BY she.created_at DESC LIMIT 20"
1128
+ ).fetchall()
1129
+
1130
+ # Health stats
1131
+ firing = conn.execute(
1132
+ "SELECT COUNT(*) as cnt FROM alerts WHERE status = 'firing'"
1133
+ ).fetchone()["cnt"]
1134
+ resolved = conn.execute(
1135
+ "SELECT COUNT(*) as cnt FROM alerts WHERE status = 'resolved'"
1136
+ ).fetchone()["cnt"]
1137
+ unresolved_failures = conn.execute(
1138
+ "SELECT COUNT(*) as cnt FROM failure_log WHERE resolved = 0"
1139
+ ).fetchone()["cnt"]
1140
+
1141
+ health = "healthy"
1142
+ if firing > 0 or unresolved_failures > 5:
1143
+ health = "degraded"
1144
+ if firing > 5:
1145
+ health = "critical"
1146
+
1147
+ return render_template(
1148
+ "monitoring/overview.html",
1149
+ alerts=[dict(r) for r in alerts],
1150
+ healing_events=[dict(r) for r in healing_events],
1151
+ firing_count=firing,
1152
+ resolved_count=resolved,
1153
+ unresolved_failures=unresolved_failures,
1154
+ health_status=health,
1155
+ )
1156
+ finally:
1157
+ conn.close()
1158
+
1159
+ # ---- Events & NLQ page routes ----
1160
+
1161
+ @app.route("/events")
1162
+ def events_page():
1163
+ """Real-time event timeline page (SSE-powered)."""
1164
+ conn = _get_db()
1165
+ try:
1166
+ recent_events = conn.execute(
1167
+ "SELECT * FROM hook_events ORDER BY created_at DESC LIMIT 50"
1168
+ ).fetchall()
1169
+ return render_template(
1170
+ "events/timeline.html",
1171
+ recent_events=[dict(r) for r in recent_events],
1172
+ )
1173
+ except Exception:
1174
+ return render_template("events/timeline.html", recent_events=[])
1175
+ finally:
1176
+ conn.close()
1177
+
1178
+ @app.route("/activity")
1179
+ def activity_page():
1180
+ """Activity feed — merged audit + hook events with real-time updates."""
1181
+ return render_template("activity.html")
1182
+
1183
+ @app.route("/usage")
1184
+ def usage_page():
1185
+ """Usage tracking + cost dashboard."""
1186
+ return render_template("usage.html")
1187
+
1188
+ @app.route("/wizard")
1189
+ def wizard_page():
1190
+ """Getting Started wizard — guides new users to the right workflow."""
1191
+ return render_template("wizard.html")
1192
+
1193
+ @app.route("/chat")
1194
+ def chat_new():
1195
+ """Start a new requirements chat — wizard params set context."""
1196
+ goal = flask_request.args.get("goal", "build")
1197
+ role = flask_request.args.get("role", "developer")
1198
+ classification = flask_request.args.get("classification", "il4")
1199
+ frameworks = flask_request.args.get("frameworks", "")
1200
+ custom_role_name = flask_request.args.get("custom_role_name", "")
1201
+ custom_role_desc = flask_request.args.get("custom_role_desc", "")
1202
+ return render_template(
1203
+ "chat.html",
1204
+ session_id=None,
1205
+ messages=[],
1206
+ wizard_goal=goal,
1207
+ wizard_role=role,
1208
+ wizard_classification=classification,
1209
+ wizard_frameworks=frameworks,
1210
+ wizard_custom_role_name=custom_role_name,
1211
+ wizard_custom_role_desc=custom_role_desc,
1212
+ )
1213
+
1214
+ @app.route("/chat/<session_id>")
1215
+ def chat_session(session_id):
1216
+ """Resume an existing requirements chat session."""
1217
+ conn = _get_db()
1218
+ try:
1219
+ try:
1220
+ session = conn.execute(
1221
+ "SELECT * FROM intake_sessions WHERE id = ?", (session_id,)
1222
+ ).fetchone()
1223
+ except sqlite3.OperationalError:
1224
+ session = None
1225
+ if not session:
1226
+ return render_template("404.html", message="Session not found"), 404
1227
+ messages = conn.execute(
1228
+ "SELECT turn_number, role, content, content_type, created_at "
1229
+ "FROM intake_conversation WHERE session_id = ? ORDER BY turn_number",
1230
+ (session_id,),
1231
+ ).fetchall()
1232
+ # Extract context for sidebar display
1233
+ import json as _json
1234
+ session_dict = dict(session)
1235
+ ctx = {}
1236
+ try:
1237
+ ctx = _json.loads(session_dict.get("context_summary") or "{}")
1238
+ except (ValueError, TypeError):
1239
+ pass
1240
+ return render_template(
1241
+ "chat.html",
1242
+ session_id=session_id,
1243
+ session=session_dict,
1244
+ messages=[dict(m) for m in messages],
1245
+ wizard_goal=None,
1246
+ wizard_role=None,
1247
+ wizard_classification=None,
1248
+ wizard_frameworks=",".join(ctx.get("selected_frameworks", [])),
1249
+ wizard_custom_role_name="",
1250
+ wizard_custom_role_desc="",
1251
+ session_context=ctx,
1252
+ )
1253
+ finally:
1254
+ conn.close()
1255
+
1256
+ @app.route("/quick-paths")
1257
+ def quick_paths_page():
1258
+ """Quick Path workflow templates — pre-built shortcuts for common tasks."""
1259
+ return render_template("quick_paths.html")
1260
+
1261
+ @app.route("/batch")
1262
+ def batch_page():
1263
+ """Batch operations — run multi-tool workflows from the dashboard."""
1264
+ return render_template("batch.html")
1265
+
1266
+ @app.route("/diagrams")
1267
+ def diagrams_page():
1268
+ """Interactive Mermaid diagrams — catalog, viewer, and editor."""
1269
+ return render_template("diagrams.html")
1270
+
1271
+ @app.route("/cicd")
1272
+ def cicd_page():
1273
+ """CI/CD pipeline status, conversations, and connector health."""
1274
+ return render_template("cicd.html")
1275
+
1276
+ @app.route("/gateway")
1277
+ def gateway_page():
1278
+ """Remote Command Gateway admin — bindings, command log, channel status."""
1279
+ import yaml as _yaml
1280
+
1281
+ # Load gateway config
1282
+ gateway_config_path = BASE_DIR / "args" / "remote_gateway_config.yaml"
1283
+ gw_config = {}
1284
+ if gateway_config_path.exists():
1285
+ with open(gateway_config_path) as f:
1286
+ gw_config = _yaml.safe_load(f) or {}
1287
+
1288
+ env_mode = gw_config.get("environment", {}).get("mode", "connected")
1289
+ channels = gw_config.get("channels", {})
1290
+
1291
+ # Determine active channels
1292
+ active_channels = []
1293
+ for name, ch in channels.items():
1294
+ enabled = ch.get("enabled", False)
1295
+ req_internet = ch.get("requires_internet", False)
1296
+ available = enabled and not (env_mode == "air_gapped" and req_internet)
1297
+ active_channels.append({
1298
+ "name": name,
1299
+ "enabled": enabled,
1300
+ "available": available,
1301
+ "max_il": ch.get("max_il", "IL4"),
1302
+ "description": ch.get("description", ""),
1303
+ })
1304
+
1305
+ # Load bindings and recent commands
1306
+ conn = _get_db()
1307
+ try:
1308
+ bindings = conn.execute(
1309
+ "SELECT * FROM remote_user_bindings ORDER BY created_at DESC LIMIT 50"
1310
+ ).fetchall()
1311
+ bindings = [dict(r) for r in bindings]
1312
+ except Exception:
1313
+ bindings = []
1314
+
1315
+ try:
1316
+ commands = conn.execute(
1317
+ "SELECT * FROM remote_command_log ORDER BY created_at DESC LIMIT 50"
1318
+ ).fetchall()
1319
+ commands = [dict(r) for r in commands]
1320
+ except Exception:
1321
+ commands = []
1322
+
1323
+ conn.close()
1324
+
1325
+ return render_template(
1326
+ "gateway.html",
1327
+ environment_mode=env_mode,
1328
+ channels=active_channels,
1329
+ bindings=bindings,
1330
+ commands=commands,
1331
+ command_allowlist=gw_config.get("command_allowlist", []),
1332
+ )
1333
+
1334
+ @app.route("/query")
1335
+ def query_page():
1336
+ """Natural language compliance query page."""
1337
+ conn = _get_db()
1338
+ try:
1339
+ recent_queries = conn.execute(
1340
+ "SELECT * FROM nlq_queries ORDER BY created_at DESC LIMIT 20"
1341
+ ).fetchall()
1342
+ return render_template(
1343
+ "query/nlq.html",
1344
+ recent_queries=[dict(r) for r in recent_queries],
1345
+ )
1346
+ except Exception:
1347
+ return render_template("query/nlq.html", recent_queries=[])
1348
+ finally:
1349
+ conn.close()
1350
+
1351
+ # ---- Tour configuration ----
1352
+
1353
+ @app.route("/api/tour/steps", methods=["GET"])
1354
+ def api_tour_steps():
1355
+ """Return tour step definitions for the onboarding walkthrough.
1356
+
1357
+ Steps are served from config so admins can customize content
1358
+ without modifying JavaScript source. tour.js fetches this
1359
+ endpoint on init and falls back to built-in defaults if
1360
+ the fetch fails (air-gap safe).
1361
+ """
1362
+ steps = [
1363
+ {
1364
+ "selector": ".navbar",
1365
+ "title": "Navigation Bar",
1366
+ "desc": (
1367
+ "Navigate between pages: Home, Projects, Agents, "
1368
+ "Monitoring, Quick Paths, Batch Operations, and "
1369
+ "the Getting Started wizard."
1370
+ ),
1371
+ },
1372
+ {
1373
+ "selector": ".kanban-board",
1374
+ "title": "Project Kanban Board",
1375
+ "desc": (
1376
+ "Projects organized by workflow stage: Planning, Active, "
1377
+ "Completed, and Inactive. Click any card to view details."
1378
+ ),
1379
+ },
1380
+ {
1381
+ "selector": ".chart-grid",
1382
+ "title": "Visual Dashboards",
1383
+ "desc": (
1384
+ "Visual dashboards: compliance posture, alert trends, "
1385
+ "project status, and agent health charts."
1386
+ ),
1387
+ },
1388
+ {
1389
+ "selector": ".table-container",
1390
+ "title": "Data Tables",
1391
+ "desc": (
1392
+ "Detailed data tables with search, sort, filter, "
1393
+ "and CSV export capabilities."
1394
+ ),
1395
+ },
1396
+ {
1397
+ "selector": "#role-select",
1398
+ "title": "Role Selector",
1399
+ "desc": (
1400
+ "Switch views: Program Manager, Developer, ISSO, or "
1401
+ "Contracting Officer to see role-relevant information."
1402
+ ),
1403
+ },
1404
+ {
1405
+ "selector": "a[href*='quick-paths'], a[href*='/quick-paths']",
1406
+ "title": "Quick Paths",
1407
+ "desc": (
1408
+ "Pre-built workflow shortcuts for common tasks like "
1409
+ "ATO generation, project creation, and security scanning."
1410
+ ),
1411
+ },
1412
+ {
1413
+ "selector": "a[href*='/batch']",
1414
+ "title": "Batch Operations",
1415
+ "desc": (
1416
+ "Run multi-step batch operations: Full ATO Package, "
1417
+ "Security Scan Suite, Multi-Framework Check, or "
1418
+ "Build & Validate from a single click."
1419
+ ),
1420
+ },
1421
+ {
1422
+ "selector": "a[href*='/events']",
1423
+ "title": "Live Events",
1424
+ "desc": (
1425
+ "Real-time event timeline showing hook events, "
1426
+ "agent activity, and system notifications with "
1427
+ "severity filtering."
1428
+ ),
1429
+ },
1430
+ ]
1431
+ return jsonify({
1432
+ "steps": steps,
1433
+ "version": 2,
1434
+ "classification": "CUI",
1435
+ })
1436
+
1437
+ # ---- Profile routes (D172, D175-D178) ----
1438
+
1439
+ @app.route("/profile")
1440
+ def profile_page():
1441
+ """User profile page with BYOK key management."""
1442
+ return render_template("profile.html")
1443
+
1444
+ @app.route("/profile/api/keys")
1445
+ def profile_api_keys():
1446
+ """List current user's dashboard API keys."""
1447
+ from icdev.tools.dashboard.auth import list_api_keys_for_user
1448
+ user = getattr(g, "current_user", None)
1449
+ if not user:
1450
+ return jsonify({"keys": []})
1451
+ keys = list_api_keys_for_user(user["id"])
1452
+ return jsonify({"keys": keys})
1453
+
1454
+ @app.route("/profile/api/llm-keys", methods=["GET"])
1455
+ def profile_llm_keys():
1456
+ """List current user's BYOK LLM keys."""
1457
+ from icdev.tools.dashboard.byok import list_llm_keys
1458
+ user = getattr(g, "current_user", None)
1459
+ if not user:
1460
+ return jsonify({"keys": []})
1461
+ keys = list_llm_keys(user["id"])
1462
+ return jsonify({"keys": keys})
1463
+
1464
+ @app.route("/profile/api/llm-keys", methods=["POST"])
1465
+ def profile_add_llm_key():
1466
+ """Store a new BYOK LLM key for the current user."""
1467
+ from icdev.tools.dashboard.byok import store_llm_key
1468
+ user = getattr(g, "current_user", None)
1469
+ if not user:
1470
+ return jsonify({"error": "Not authenticated"}), 401
1471
+ data = flask_request.get_json(force=True)
1472
+ provider = data.get("provider", "").strip()
1473
+ api_key = data.get("api_key", "").strip()
1474
+ label = data.get("label", "").strip()
1475
+ if not provider or not api_key:
1476
+ return jsonify({"error": "provider and api_key required"}), 400
1477
+ result = store_llm_key(user["id"], provider, api_key, key_label=label)
1478
+ return jsonify(result), 201
1479
+
1480
+ @app.route("/profile/api/llm-keys/<key_id>/revoke", methods=["POST"])
1481
+ def profile_revoke_llm_key(key_id):
1482
+ """Revoke a BYOK LLM key."""
1483
+ from icdev.tools.dashboard.byok import revoke_llm_key
1484
+ revoke_llm_key(key_id)
1485
+ return jsonify({"status": "revoked"})
1486
+
1487
+ # ---- Phase roadmap route ----
1488
+
1489
+ @app.route("/phases")
1490
+ def phases_page():
1491
+ """Phase roadmap — all ICDEV phases with status, categories, and progress."""
1492
+ from icdev.tools.dashboard.phase_loader import (
1493
+ load_phases, load_categories, load_statuses, get_phase_summary,
1494
+ )
1495
+ phases = load_phases()
1496
+ categories = load_categories()
1497
+ statuses = load_statuses()
1498
+ summary = get_phase_summary(phases)
1499
+
1500
+ # Optional category filter from query param
1501
+ cat_filter = flask_request.args.get("category", "")
1502
+ if cat_filter:
1503
+ phases = [p for p in phases if p.get("category") == cat_filter]
1504
+
1505
+ return render_template(
1506
+ "phases.html",
1507
+ phases=phases,
1508
+ categories=categories,
1509
+ statuses=statuses,
1510
+ summary=summary,
1511
+ category_filter=cat_filter,
1512
+ )
1513
+
1514
+ # ---- Dev profile routes (Phase 34, D183-D188) ----
1515
+
1516
+ @app.route("/dev-profiles")
1517
+ def dev_profiles_page():
1518
+ """Dev profile management — list, create, view profiles."""
1519
+ return render_template("dev_profiles.html")
1520
+
1521
+ # ---- Child application routes (Phase 19 + Evolutionary Intelligence) ----
1522
+
1523
+ @app.route("/children")
1524
+ def children_page():
1525
+ """Child application registry — health, genome, capabilities, heartbeats."""
1526
+ conn = _get_db()
1527
+ try:
1528
+ # Fetch all registered child applications
1529
+ try:
1530
+ children_rows = conn.execute(
1531
+ "SELECT * FROM child_app_registry ORDER BY created_at DESC"
1532
+ ).fetchall()
1533
+ children_rows = [dict(r) for r in children_rows]
1534
+ except sqlite3.OperationalError:
1535
+ children_rows = []
1536
+
1537
+ # Fetch latest heartbeat per child from telemetry
1538
+ heartbeat_map = {}
1539
+ try:
1540
+ heartbeats = conn.execute(
1541
+ "SELECT child_id, MAX(reported_at) as last_heartbeat "
1542
+ "FROM child_telemetry GROUP BY child_id"
1543
+ ).fetchall()
1544
+ for hb in heartbeats:
1545
+ hb_dict = dict(hb)
1546
+ heartbeat_map[hb_dict["child_id"]] = hb_dict["last_heartbeat"]
1547
+ except sqlite3.OperationalError:
1548
+ pass
1549
+
1550
+ # Fetch capability count per child
1551
+ capability_map = {}
1552
+ try:
1553
+ caps = conn.execute(
1554
+ "SELECT child_id, COUNT(*) as cnt FROM child_capabilities GROUP BY child_id"
1555
+ ).fetchall()
1556
+ for c in caps:
1557
+ c_dict = dict(c)
1558
+ capability_map[c_dict["child_id"]] = c_dict["cnt"]
1559
+ except sqlite3.OperationalError:
1560
+ pass
1561
+
1562
+ # Enrich children with heartbeat and capability data
1563
+ children = []
1564
+ for child in children_rows:
1565
+ child["last_heartbeat"] = heartbeat_map.get(child.get("id"), child.get("last_heartbeat"))
1566
+ child["capability_count"] = capability_map.get(child.get("id"), child.get("capability_count", 0))
1567
+ child["pending_upgrades"] = child.get("pending_upgrades", 0)
1568
+ child["genome_version"] = child.get("genome_version", None)
1569
+ child["health_status"] = child.get("health_status", "unhealthy")
1570
+ children.append(child)
1571
+
1572
+ # Compute summary counts
1573
+ healthy_count = sum(1 for c in children if c["health_status"] == "healthy")
1574
+ degraded_count = sum(1 for c in children if c["health_status"] == "degraded")
1575
+ unhealthy_count = sum(1 for c in children if c["health_status"] not in ("healthy", "degraded"))
1576
+
1577
+ return render_template(
1578
+ "children.html",
1579
+ children=children,
1580
+ total_count=len(children),
1581
+ healthy_count=healthy_count,
1582
+ degraded_count=degraded_count,
1583
+ unhealthy_count=unhealthy_count,
1584
+ )
1585
+ finally:
1586
+ conn.close()
1587
+
1588
+ @app.route("/dev-profiles/api/list")
1589
+ def dev_profiles_api_list():
1590
+ """List all dev profiles (JSON)."""
1591
+ conn = _get_db()
1592
+ try:
1593
+ rows = conn.execute(
1594
+ """SELECT id, scope, scope_id, version, is_active, inherits_from,
1595
+ created_by, created_at, change_summary
1596
+ FROM dev_profiles WHERE is_active = 1
1597
+ ORDER BY created_at DESC LIMIT 50"""
1598
+ ).fetchall()
1599
+ return jsonify({"profiles": [dict(r) for r in rows]})
1600
+ except Exception as e:
1601
+ return jsonify({"profiles": [], "error": str(e)})
1602
+ finally:
1603
+ conn.close()
1604
+
1605
+ @app.route("/dev-profiles/api/resolve/<scope>/<scope_id>")
1606
+ def dev_profiles_api_resolve(scope, scope_id):
1607
+ """Resolve 5-layer cascade for a scope (JSON)."""
1608
+ try:
1609
+ from icdev.tools.builder.dev_profile_manager import resolve_profile
1610
+ result = resolve_profile(scope, scope_id)
1611
+ return jsonify(result)
1612
+ except (ImportError, Exception) as e:
1613
+ return jsonify({"error": str(e)})
1614
+
1615
+ @app.route("/dev-profiles/api/templates")
1616
+ def dev_profiles_api_templates():
1617
+ """List available starter templates (JSON)."""
1618
+ templates = []
1619
+ templates_dir = Path(__file__).resolve().parent.parent.parent / "context" / "profiles"
1620
+ if templates_dir.exists():
1621
+ try:
1622
+ import yaml
1623
+ for f in sorted(templates_dir.glob("*.yaml")):
1624
+ with open(f, "r", encoding="utf-8") as fh:
1625
+ data = yaml.safe_load(fh)
1626
+ templates.append({
1627
+ "name": data.get("name", f.stem),
1628
+ "file": f.name,
1629
+ "description": data.get("description", ""),
1630
+ "impact_levels": data.get("impact_levels", []),
1631
+ })
1632
+ except Exception:
1633
+ pass
1634
+ return jsonify({"templates": templates})
1635
+
1636
+ @app.route("/dev-profiles/api/create", methods=["POST"])
1637
+ def dev_profiles_api_create():
1638
+ """Create a dev profile from template or data (JSON)."""
1639
+ try:
1640
+ from icdev.tools.builder.dev_profile_manager import create_profile
1641
+ data = flask_request.get_json(silent=True) or {}
1642
+ result = create_profile(
1643
+ scope=data.get("scope", "project"),
1644
+ scope_id=data.get("scope_id", ""),
1645
+ template_name=data.get("template"),
1646
+ created_by=data.get("created_by", "dashboard"),
1647
+ )
1648
+ return jsonify(result), 201 if "error" not in result else 400
1649
+ except (ImportError, Exception) as e:
1650
+ return jsonify({"error": str(e)}), 500
1651
+
1652
+ # ---- Auth routes (D169-D172) ----
1653
+
1654
+ @app.route("/login", methods=["GET", "POST"])
1655
+ def login_page():
1656
+ """Login page — accepts API key via form or header."""
1657
+ if flask_request.method == "POST":
1658
+ raw_key = flask_request.form.get("api_key", "").strip()
1659
+ user = validate_api_key(raw_key)
1660
+ if user:
1661
+ flask_session["user_id"] = user["id"]
1662
+ log_auth_event(
1663
+ user["id"], "login_success",
1664
+ ip_address=flask_request.remote_addr,
1665
+ user_agent=flask_request.headers.get("User-Agent", "")[:256],
1666
+ details="via_login_form",
1667
+ )
1668
+ return redirect(url_for("index"))
1669
+ else:
1670
+ log_auth_event(
1671
+ None, "login_failed",
1672
+ ip_address=flask_request.remote_addr,
1673
+ user_agent=flask_request.headers.get("User-Agent", "")[:256],
1674
+ details="via_login_form",
1675
+ )
1676
+ return render_template("login.html", error="Invalid API key. Please try again.")
1677
+ return render_template("login.html", error=None)
1678
+
1679
+ @app.route("/logout")
1680
+ def logout():
1681
+ """Clear session and redirect to login."""
1682
+ user_id = flask_session.get("user_id")
1683
+ if user_id:
1684
+ log_auth_event(
1685
+ user_id, "logout",
1686
+ ip_address=flask_request.remote_addr,
1687
+ )
1688
+ flask_session.clear()
1689
+ return redirect(url_for("login_page"))
1690
+
1691
+ # ---- Error handlers ----
1692
+
1693
+ # ---- Cross-Language Translation routes (Phase 43) ----
1694
+
1695
+ @app.route("/translations")
1696
+ def translations_page():
1697
+ """Translation jobs — list, status, validation scores."""
1698
+ conn = _get_db()
1699
+ try:
1700
+ try:
1701
+ jobs = conn.execute(
1702
+ """SELECT id, project_id, source_language, target_language,
1703
+ status, total_units, translated_units, mocked_units,
1704
+ failed_units, gate_result, llm_model, llm_tokens_input,
1705
+ llm_tokens_output, elapsed_seconds, created_at
1706
+ FROM translation_jobs ORDER BY created_at DESC LIMIT 100"""
1707
+ ).fetchall()
1708
+ jobs = [dict(r) for r in jobs]
1709
+ except sqlite3.OperationalError:
1710
+ jobs = []
1711
+
1712
+ # Summary stats
1713
+ total = len(jobs)
1714
+ completed = sum(1 for j in jobs if j.get("status") == "completed")
1715
+ in_progress = sum(1 for j in jobs if j.get("status") in ("pending", "extracting", "translating", "assembling", "validating"))
1716
+ failed = sum(1 for j in jobs if j.get("status") in ("failed", "partial"))
1717
+
1718
+ # Average API surface score from validations
1719
+ avg_api_score = None
1720
+ try:
1721
+ row = conn.execute(
1722
+ """SELECT AVG(score) as avg_score FROM translation_validations
1723
+ WHERE check_type = 'api_surface' AND passed = 1"""
1724
+ ).fetchone()
1725
+ if row and row["avg_score"]:
1726
+ avg_api_score = round(row["avg_score"] * 100, 1)
1727
+ except sqlite3.OperationalError:
1728
+ pass
1729
+
1730
+ return render_template(
1731
+ "translations.html",
1732
+ jobs=jobs,
1733
+ total=total,
1734
+ completed=completed,
1735
+ in_progress=in_progress,
1736
+ failed=failed,
1737
+ avg_api_score=avg_api_score,
1738
+ )
1739
+ finally:
1740
+ conn.close()
1741
+
1742
+ @app.route("/translations/<job_id>")
1743
+ def translation_detail_page(job_id):
1744
+ """Translation job detail — units, validations, dependencies."""
1745
+ conn = _get_db()
1746
+ try:
1747
+ # Fetch job
1748
+ try:
1749
+ job = conn.execute(
1750
+ "SELECT * FROM translation_jobs WHERE id = ?", (job_id,)
1751
+ ).fetchone()
1752
+ job = dict(job) if job else None
1753
+ except sqlite3.OperationalError:
1754
+ job = None
1755
+
1756
+ if not job:
1757
+ return render_template("404.html", message="Translation job not found"), 404
1758
+
1759
+ # Fetch units
1760
+ try:
1761
+ units = conn.execute(
1762
+ """SELECT unit_name, unit_kind, source_file, status,
1763
+ source_complexity, target_complexity,
1764
+ repair_count, candidate_selected, created_at
1765
+ FROM translation_units WHERE job_id = ?
1766
+ ORDER BY created_at""", (job_id,)
1767
+ ).fetchall()
1768
+ units = [dict(u) for u in units]
1769
+ except sqlite3.OperationalError:
1770
+ units = []
1771
+
1772
+ # Fetch validations
1773
+ try:
1774
+ validations = conn.execute(
1775
+ """SELECT check_type, passed, score, findings, created_at
1776
+ FROM translation_validations WHERE job_id = ?
1777
+ ORDER BY created_at""", (job_id,)
1778
+ ).fetchall()
1779
+ validations = [dict(v) for v in validations]
1780
+ except sqlite3.OperationalError:
1781
+ validations = []
1782
+
1783
+ # Fetch dependency mappings
1784
+ try:
1785
+ deps = conn.execute(
1786
+ """SELECT source_import, target_import, mapping_source,
1787
+ confidence, domain
1788
+ FROM translation_dependency_mappings WHERE job_id = ?
1789
+ ORDER BY domain, source_import""", (job_id,)
1790
+ ).fetchall()
1791
+ deps = [dict(d) for d in deps]
1792
+ except sqlite3.OperationalError:
1793
+ deps = []
1794
+
1795
+ return render_template(
1796
+ "translation_detail.html",
1797
+ job=job,
1798
+ units=units,
1799
+ validations=validations,
1800
+ deps=deps,
1801
+ )
1802
+ finally:
1803
+ conn.close()
1804
+
1805
+ @app.route("/api/charts/translations")
1806
+ def api_charts_translations():
1807
+ """Chart data for translations page."""
1808
+ conn = _get_db()
1809
+ try:
1810
+ # Status distribution
1811
+ status_dist = {}
1812
+ try:
1813
+ rows = conn.execute(
1814
+ "SELECT status, COUNT(*) as cnt FROM translation_jobs GROUP BY status"
1815
+ ).fetchall()
1816
+ for r in rows:
1817
+ r_dict = dict(r)
1818
+ status_dist[r_dict["status"]] = r_dict["cnt"]
1819
+ except sqlite3.OperationalError:
1820
+ pass
1821
+
1822
+ # Language pair frequency
1823
+ lang_pairs = {}
1824
+ try:
1825
+ rows = conn.execute(
1826
+ """SELECT source_language || ' → ' || target_language as pair,
1827
+ COUNT(*) as cnt
1828
+ FROM translation_jobs GROUP BY pair ORDER BY cnt DESC LIMIT 10"""
1829
+ ).fetchall()
1830
+ for r in rows:
1831
+ r_dict = dict(r)
1832
+ lang_pairs[r_dict["pair"]] = r_dict["cnt"]
1833
+ except sqlite3.OperationalError:
1834
+ pass
1835
+
1836
+ return jsonify({
1837
+ "status_distribution": status_dist,
1838
+ "language_pair_frequency": lang_pairs,
1839
+ })
1840
+ finally:
1841
+ conn.close()
1842
+
1843
+ # ---- Phase 46: Observability pages ----
1844
+
1845
+ @app.route("/traces")
1846
+ def traces_page():
1847
+ """Trace explorer — distributed tracing across MCP, A2A, LLM."""
1848
+ return render_template("traces.html")
1849
+
1850
+ @app.route("/provenance")
1851
+ def provenance_page():
1852
+ """Provenance graph — W3C PROV-AGENT artifact lineage."""
1853
+ return render_template("provenance.html")
1854
+
1855
+ @app.route("/xai")
1856
+ def xai_page():
1857
+ """XAI dashboard — explainability, SHAP attribution, compliance."""
1858
+ return render_template("xai.html")
1859
+
1860
+ # ---- OSCAL & Production Audit pages ----
1861
+
1862
+ @app.route("/oscal")
1863
+ def oscal_page():
1864
+ """OSCAL ecosystem — validation, catalog, format conversion (D302-D306)."""
1865
+ return render_template("oscal.html")
1866
+
1867
+ @app.route("/prod-audit")
1868
+ def prod_audit_page():
1869
+ """Production readiness audit — 30 checks, 6 categories (D291-D300)."""
1870
+ return render_template("prod_audit.html")
1871
+
1872
+ @app.route("/ai-transparency")
1873
+ def ai_transparency_page():
1874
+ """AI Transparency — OMB M-25-21, M-26-04, NIST AI 600-1, GAO-21-519SP (Phase 48, D307-D315)."""
1875
+ return render_template("ai_transparency.html")
1876
+
1877
+ @app.route("/ai-accountability")
1878
+ def ai_accountability_page():
1879
+ """AI Accountability — oversight, appeals, CAIO, incidents, ethics (Phase 49, D316-D321)."""
1880
+ return render_template("ai_accountability.html")
1881
+
1882
+ @app.route("/code-quality")
1883
+ def code_quality_page():
1884
+ """Code Quality Intelligence — AST analysis, smells, maintainability, runtime feedback (Phase 52, D331-D337)."""
1885
+ return render_template("code_quality.html")
1886
+
1887
+ @app.route("/fedramp-20x")
1888
+ def fedramp_20x_page():
1889
+ """FedRAMP 20x KSI Dashboard — KSI evidence generation, maturity levels, authorization package (Phase 53, D338)."""
1890
+ return render_template("fedramp_20x.html")
1891
+
1892
+ @app.route("/evidence")
1893
+ def evidence_page():
1894
+ """Evidence Collection — universal evidence auto-collection across all frameworks (Phase 56, D347)."""
1895
+ from icdev.tools.compliance.evidence_collector import FRAMEWORK_EVIDENCE_MAP, _get_connection, _table_exists
1896
+ stats = {"total_frameworks": len(FRAMEWORK_EVIDENCE_MAP), "required_frameworks": 0, "frameworks": []}
1897
+ try:
1898
+ conn = _get_connection()
1899
+ for fw_id, fw_config in FRAMEWORK_EVIDENCE_MAP.items():
1900
+ if fw_config["required"]:
1901
+ stats["required_frameworks"] += 1
1902
+ total = 0
1903
+ for table_name in fw_config["tables"]:
1904
+ if _table_exists(conn, table_name):
1905
+ row = conn.execute(f"SELECT COUNT(*) FROM {table_name}").fetchone()
1906
+ total += row[0]
1907
+ stats["frameworks"].append({
1908
+ "id": fw_id,
1909
+ "description": fw_config["description"],
1910
+ "required": fw_config["required"],
1911
+ "total_records": total,
1912
+ })
1913
+ conn.close()
1914
+ except Exception:
1915
+ pass
1916
+ return render_template("evidence.html", stats=stats)
1917
+
1918
+ @app.route("/lineage")
1919
+ def lineage_page():
1920
+ """Artifact Lineage — unified DAG visualization of digital thread, provenance, audit trail, SBOM (Phase 56, D348)."""
1921
+ return render_template("lineage.html")
1922
+
1923
+ # ---- CPMP / Proposals / GovCon Pages (D-CHILD-6: guarded) ----
1924
+ if _HAS_GOVCON:
1925
+ _register_govcon_pages(app, _get_db)
1926
+
1927
+ # ---- Phase 61: Orchestration Dashboard ----
1928
+
1929
+ @app.route("/orchestration")
1930
+ def orchestration_dashboard():
1931
+ """Real-time multi-agent orchestration dashboard — agent grid, DAG, mailbox (Phase 61)."""
1932
+ return render_template("orchestration/dashboard.html")
1933
+
1934
+ @app.errorhandler(401)
1935
+ def unauthorized(e):
1936
+ if flask_request.is_json or flask_request.path.startswith("/api/"):
1937
+ return jsonify({"error": "Unauthorized", "message": "Valid API key required"}), 401
1938
+ return redirect(url_for("login_page"))
1939
+
1940
+ @app.errorhandler(403)
1941
+ def forbidden(e):
1942
+ if flask_request.is_json or flask_request.path.startswith("/api/"):
1943
+ return jsonify({"error": "Forbidden", "message": "Insufficient permissions"}), 403
1944
+ return render_template("404.html", message="You do not have permission to access this page."), 403
1945
+
1946
+ @app.errorhandler(404)
1947
+ def not_found(e):
1948
+ return render_template("404.html", message="Page not found"), 404
1949
+
1950
+ return app
1951
+
1952
+
1953
+ # ---------------------------------------------------------------------------
1954
+ # Database helper
1955
+ # ---------------------------------------------------------------------------
1956
+
1957
+
1958
+ def _get_db():
1959
+ conn = sqlite3.connect(DB_PATH)
1960
+ conn.row_factory = sqlite3.Row
1961
+ return conn
1962
+
1963
+
1964
+ # ---------------------------------------------------------------------------
1965
+ # CLI entry point
1966
+ # ---------------------------------------------------------------------------
1967
+
1968
+ if __name__ == "__main__":
1969
+ parser = argparse.ArgumentParser(description="ICDEV Dashboard")
1970
+ parser.add_argument("--port", type=int, default=PORT, help="Port to run on (default: 5000)")
1971
+ parser.add_argument("--debug", action="store_true", default=DEBUG, help="Enable debug mode")
1972
+ args = parser.parse_args()
1973
+
1974
+ app = create_app()
1975
+ print(f"[ICDEV Dashboard] Starting on http://127.0.0.1:{args.port}")
1976
+ print(f"[ICDEV Dashboard] Database: {DB_PATH}")
1977
+ print(f"[ICDEV Dashboard] CUI Marking: {CUI_BANNER_TOP}")
1978
+
1979
+ # Use SocketIO runner if available (D170), otherwise plain Flask
1980
+ socketio = get_socketio()
1981
+ if socketio:
1982
+ print("[ICDEV Dashboard] WebSocket enabled (Flask-SocketIO)")
1983
+ socketio.run(app, host="0.0.0.0", port=args.port, debug=args.debug)
1984
+ else:
1985
+ print("[ICDEV Dashboard] WebSocket not available — using HTTP polling")
1986
+ app.run(host="0.0.0.0", port=args.port, debug=args.debug)