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,2188 @@
1
+ #!/usr/bin/env python3
2
+ # CUI // SP-CTI
3
+ # Controlled by: Department of Defense
4
+ # CUI Category: CTI
5
+ # Distribution: D
6
+ # POC: ICDEV System Administrator
7
+ """Conversational requirements intake engine.
8
+
9
+ Creates and manages intake sessions, processes customer turns, extracts
10
+ requirements, detects gaps/ambiguities, and scores readiness.
11
+
12
+ Usage:
13
+ # Create new session
14
+ python tools/requirements/intake_engine.py --project-id proj-123 \\
15
+ --customer-name "Jane Smith" --customer-org "PEO IEW&S" --impact-level IL4 --json
16
+
17
+ # Process a customer turn
18
+ python tools/requirements/intake_engine.py --session-id sess-abc \\
19
+ --message "We need a mission planning tool with 200 users" --json
20
+
21
+ # Resume paused session
22
+ python tools/requirements/intake_engine.py --session-id sess-abc --resume --json
23
+
24
+ # Score readiness
25
+ python tools/requirements/intake_engine.py --session-id sess-abc --score-readiness --json
26
+
27
+ # Export requirements
28
+ python tools/requirements/intake_engine.py --session-id sess-abc --export --json
29
+ """
30
+
31
+ import argparse
32
+ import json
33
+ import re
34
+ import sqlite3
35
+ import uuid
36
+ from datetime import datetime, timezone
37
+ from pathlib import Path
38
+ from icdev._paths import get_project_root
39
+
40
+ BASE_DIR = get_project_root()
41
+ DB_PATH = BASE_DIR / "data" / "icdev.db"
42
+
43
+ # Graceful import of audit logger
44
+ try:
45
+ from icdev.tools.audit.audit_logger import log_event
46
+ _HAS_AUDIT = True
47
+ except ImportError:
48
+ _HAS_AUDIT = False
49
+ def log_event(**kwargs) -> int:
50
+ return -1
51
+
52
+
53
+ def _get_connection(db_path=None):
54
+ """Get database connection with dict-like row access."""
55
+ path = db_path or DB_PATH
56
+ if not path.exists():
57
+ raise FileNotFoundError(
58
+ f"Database not found: {path}\nRun: python tools/db/init_icdev_db.py"
59
+ )
60
+ conn = sqlite3.connect(str(path))
61
+ conn.row_factory = sqlite3.Row
62
+ return conn
63
+
64
+
65
+ def _generate_id(prefix="sess"):
66
+ """Generate a unique ID with prefix."""
67
+ return f"{prefix}-{uuid.uuid4().hex[:12]}"
68
+
69
+
70
+ def _load_config():
71
+ """Load RICOAS configuration."""
72
+ config_path = BASE_DIR / "args" / "ricoas_config.yaml"
73
+ if config_path.exists():
74
+ try:
75
+ import yaml
76
+ with open(config_path, "r", encoding="utf-8") as f:
77
+ return yaml.safe_load(f)
78
+ except ImportError:
79
+ pass
80
+ # Fallback defaults
81
+ return {
82
+ "ricoas": {
83
+ "readiness_threshold": 0.7,
84
+ "readiness_weights": {
85
+ "completeness": 0.25,
86
+ "clarity": 0.25,
87
+ "feasibility": 0.20,
88
+ "compliance": 0.15,
89
+ "testability": 0.15,
90
+ },
91
+ "intake_agent": {
92
+ "max_conversation_turns": 200,
93
+ "auto_readiness_score_interval": 3,
94
+ },
95
+ }
96
+ }
97
+
98
+
99
+ def _load_persona(role, custom_role_description=None):
100
+ """Load persona definition for a given role from role_personas.yaml.
101
+
102
+ Args:
103
+ role: The role key (e.g. 'developer', 'pm', 'isso').
104
+ custom_role_description: Optional description for custom roles.
105
+
106
+ Returns:
107
+ dict with persona fields (system_prompt, opening_question, etc.)
108
+ or None if persona file is missing.
109
+ """
110
+ persona_path = BASE_DIR / "args" / "role_personas.yaml"
111
+ if not persona_path.exists():
112
+ return None
113
+ try:
114
+ import yaml
115
+ with open(persona_path, "r", encoding="utf-8") as f:
116
+ data = yaml.safe_load(f) or {}
117
+ except ImportError:
118
+ return None
119
+
120
+ personas = data.get("personas", {})
121
+
122
+ # Check for built-in persona
123
+ if role in personas:
124
+ return personas[role]
125
+
126
+ # Custom role — synthesize persona from meta template
127
+ if custom_role_description:
128
+ custom_cfg = data.get("custom_role", {})
129
+ meta_prompt = custom_cfg.get("meta_system_prompt", "")
130
+ opening_prompt = custom_cfg.get("opening_prompt", "")
131
+ return {
132
+ "display_name": role.replace("_", " ").title(),
133
+ "system_prompt": meta_prompt.replace("{role_name}", role).replace(
134
+ "{role_description}", custom_role_description
135
+ ),
136
+ "opening_question": opening_prompt.replace("{role_name}", role).replace(
137
+ "{role_description}", custom_role_description
138
+ ),
139
+ "priority_topics": [],
140
+ "follow_up_patterns": [],
141
+ }
142
+
143
+ # Fallback to developer persona
144
+ return personas.get("developer")
145
+
146
+
147
+ # ---------------------------------------------------------------------------
148
+ # LLM-powered persona response generation
149
+ # ---------------------------------------------------------------------------
150
+
151
+ # Conditional LLM imports — LLM may not be available in air-gapped envs
152
+ _HAS_LLM = False
153
+ try:
154
+ from icdev.tools.llm import get_router
155
+ from icdev.tools.llm.provider import LLMRequest as _LLMRequest
156
+ _HAS_LLM = True
157
+ except ImportError:
158
+ pass
159
+
160
+
161
+ def _generate_persona_response(session_data, message, signals, conn):
162
+ """Generate an LLM-powered persona response for the intake conversation.
163
+
164
+ Builds a system prompt from the session's persona, conversation history,
165
+ and current turn signals, then calls the LLM router.
166
+
167
+ Args:
168
+ session_data: dict of the intake_sessions row.
169
+ message: The customer message for this turn.
170
+ signals: dict with keys like extracted_reqs, ambiguities,
171
+ boundary_flags, gap_signals, devsecops_signals,
172
+ zta_signals, mosa_signals, readiness_update.
173
+ conn: Active database connection.
174
+
175
+ Returns:
176
+ str with the persona response, or None if LLM is unavailable
177
+ or any error occurs (caller should fall back to deterministic response).
178
+ """
179
+ if not _HAS_LLM:
180
+ return None
181
+
182
+ try:
183
+ # Load context from session
184
+ context_raw = session_data.get("context_summary") or "{}"
185
+ try:
186
+ ctx = json.loads(context_raw)
187
+ except (json.JSONDecodeError, TypeError):
188
+ ctx = {}
189
+
190
+ role = ctx.get("role", "developer")
191
+ custom_desc = ctx.get("custom_role_description", "")
192
+ persona = _load_persona(role, custom_desc)
193
+ if not persona:
194
+ return None
195
+
196
+ # Build conversation history (last 10 turns)
197
+ session_id = session_data.get("id", "")
198
+ history_rows = conn.execute(
199
+ """SELECT turn_number, role, content
200
+ FROM intake_conversation
201
+ WHERE session_id = ?
202
+ ORDER BY turn_number DESC LIMIT 10""",
203
+ (session_id,),
204
+ ).fetchall()
205
+ history_rows = list(reversed(history_rows))
206
+
207
+ conversation_messages = []
208
+ for row in history_rows:
209
+ r = dict(row)
210
+ msg_role = "assistant" if r["role"] == "analyst" else "user"
211
+ if r["role"] == "system":
212
+ continue
213
+ conversation_messages.append({
214
+ "role": msg_role,
215
+ "content": r["content"],
216
+ })
217
+ # Add current customer message
218
+ conversation_messages.append({
219
+ "role": "user",
220
+ "content": message,
221
+ })
222
+
223
+ # Build system prompt with persona + session context
224
+ goal = ctx.get("goal", "build")
225
+ selected_fw = ctx.get("selected_frameworks", [])
226
+ req_count = signals.get("total_requirements", 0)
227
+ readiness = signals.get("readiness_update")
228
+
229
+ system_parts = [
230
+ persona.get("system_prompt", ""),
231
+ "",
232
+ "--- Session Context ---",
233
+ f"Goal: {goal}",
234
+ f"Classification: {session_data.get('classification', 'CUI')}",
235
+ f"Impact Level: {session_data.get('impact_level', 'IL5')}",
236
+ ]
237
+ if selected_fw:
238
+ system_parts.append(f"Selected Frameworks: {', '.join(selected_fw)}")
239
+ system_parts.append(f"Requirements captured so far: {req_count}")
240
+
241
+ # Inject active elicitation technique (BMAD pattern)
242
+ active_tech_prompt = ctx.get("active_technique_prompt")
243
+ if active_tech_prompt:
244
+ system_parts.append("")
245
+ system_parts.append("--- Active Elicitation Technique ---")
246
+ system_parts.append(active_tech_prompt)
247
+ system_parts.append(
248
+ "IMPORTANT: Frame your response using the active technique above. "
249
+ "Ask questions that align with the technique's approach."
250
+ )
251
+
252
+ if readiness:
253
+ system_parts.append(
254
+ f"Readiness score: {readiness.get('overall', 0):.0%}"
255
+ )
256
+ # Show per-dimension scores so the agent targets weak areas
257
+ dims = {
258
+ "completeness": readiness.get("completeness", 0),
259
+ "clarity": readiness.get("clarity", 0),
260
+ "feasibility": readiness.get("feasibility", 0),
261
+ "compliance": readiness.get("compliance", 0),
262
+ "testability": readiness.get("testability", 0),
263
+ }
264
+ dim_strs = [f" {k}: {v:.0%}" for k, v in dims.items()]
265
+ system_parts.append("Readiness by dimension:")
266
+ system_parts.extend(dim_strs)
267
+ # Identify the weakest dimension and hint what to ask
268
+ weakest = min(dims, key=dims.get)
269
+ dim_probes = {
270
+ "completeness": (
271
+ "Completeness is low — ask about requirement types not yet "
272
+ "covered (e.g., performance, security, data, integration, "
273
+ "usability, deployment). Probe for missing user roles, "
274
+ "workflows, or edge cases."
275
+ ),
276
+ "clarity": (
277
+ "Clarity is low — some requirements use vague language. "
278
+ "Ask the customer to quantify terms (e.g., 'how many users?', "
279
+ "'what response time?', 'what does success look like?')."
280
+ ),
281
+ "feasibility": (
282
+ "Feasibility is low — ask about constraints: available "
283
+ "timeline, team size, technology limitations, existing "
284
+ "systems to integrate with, hosting environment."
285
+ ),
286
+ "compliance": (
287
+ "Compliance is low — ask about security requirements: "
288
+ "authentication (CAC/PIV, MFA), encryption (FIPS 140-2), "
289
+ "audit logging, access controls, data handling rules, "
290
+ "or any specific NIST/STIG/FedRAMP controls."
291
+ ),
292
+ "testability": (
293
+ "Testability is low — ask the customer to define acceptance "
294
+ "criteria: 'How would you verify this works?', 'What does "
295
+ "a successful outcome look like?', 'What are the pass/fail "
296
+ "conditions?'"
297
+ ),
298
+ }
299
+ system_parts.append("")
300
+ system_parts.append(f"PRIORITY: {dim_probes.get(weakest, '')}")
301
+
302
+ # Add conversation coverage analysis
303
+ cov = signals.get("coverage")
304
+ if cov:
305
+ system_parts.append("")
306
+ system_parts.append("--- Conversation Coverage ---")
307
+ system_parts.append(cov["summary"])
308
+ system_parts.append(
309
+ "IMPORTANT: Do NOT ask generic questions. Analyze what the customer "
310
+ "has already told you and ask about a SPECIFIC missing topic from "
311
+ "the list above. Reference what they said to show you were listening."
312
+ )
313
+
314
+ # Add URL content fetched from customer message
315
+ url_contents = signals.get("url_contents", [])
316
+ if url_contents:
317
+ system_parts.append("")
318
+ system_parts.append("--- URLs Referenced by Customer ---")
319
+ for uc in url_contents:
320
+ system_parts.append(f"URL: {uc['url']}")
321
+ if uc.get("title"):
322
+ system_parts.append(f"Title: {uc['title']}")
323
+ system_parts.append(f"Content: {uc['summary']}")
324
+ system_parts.append("")
325
+ system_parts.append(
326
+ "IMPORTANT: The customer shared URL(s). Review the content above and "
327
+ "reference relevant details in your response. Extract any requirements "
328
+ "or context from the linked content. Show the customer you reviewed "
329
+ "their link."
330
+ )
331
+
332
+ # Add uploaded document context
333
+ doc_rows = conn.execute(
334
+ "SELECT file_name, document_type, extracted_requirements_count, "
335
+ "extracted_sections FROM intake_documents WHERE session_id = ?",
336
+ (session_id,),
337
+ ).fetchall()
338
+ if doc_rows:
339
+ system_parts.append("")
340
+ system_parts.append("--- Uploaded Documents ---")
341
+ for dr in doc_rows:
342
+ d = dict(dr)
343
+ system_parts.append(
344
+ f"Document: {d['file_name']} (type: {d['document_type']}, "
345
+ f"{d['extracted_requirements_count']} requirements extracted)"
346
+ )
347
+ if d.get("extracted_sections"):
348
+ try:
349
+ sections = json.loads(d["extracted_sections"])
350
+ if isinstance(sections, dict):
351
+ if sections.get("description"):
352
+ system_parts.append(
353
+ f" Content: {sections['description'][:300]}"
354
+ )
355
+ if sections.get("category"):
356
+ system_parts.append(
357
+ f" Category: {sections['category']}"
358
+ )
359
+ except (json.JSONDecodeError, TypeError):
360
+ pass
361
+ # Include document-extracted requirements as context
362
+ doc_reqs = conn.execute(
363
+ "SELECT raw_text, requirement_type FROM intake_requirements "
364
+ "WHERE session_id = ? AND source_document IS NOT NULL "
365
+ "ORDER BY created_at LIMIT 20",
366
+ (session_id,),
367
+ ).fetchall()
368
+ if doc_reqs:
369
+ system_parts.append("Requirements from documents:")
370
+ for dr in doc_reqs:
371
+ d = dict(dr)
372
+ system_parts.append(
373
+ f" - [{d['requirement_type'].upper()}] {d['raw_text'][:120]}"
374
+ )
375
+ system_parts.append(
376
+ "Reference the uploaded document content when asking follow-up "
377
+ "questions. Use extracted requirements as context to ask deeper, "
378
+ "more specific questions about the customer's needs."
379
+ )
380
+
381
+ # Add signal summary for this turn
382
+ signal_notes = []
383
+ extracted_reqs = signals.get("extracted_reqs", [])
384
+ if extracted_reqs:
385
+ signal_notes.append(
386
+ f"Extracted {len(extracted_reqs)} requirement(s) this turn."
387
+ )
388
+ ambiguities = signals.get("ambiguities", [])
389
+ if ambiguities:
390
+ terms = [a["phrase"] for a in ambiguities]
391
+ signal_notes.append(
392
+ f"Ambiguous terms detected: {', '.join(terms)}"
393
+ )
394
+ boundary_flags = signals.get("boundary_flags", [])
395
+ if boundary_flags:
396
+ tiers = [f["tier"] for f in boundary_flags]
397
+ signal_notes.append(
398
+ f"ATO boundary flags: {', '.join(tiers)}"
399
+ )
400
+ gap_signals = signals.get("gap_signals", [])
401
+ if gap_signals:
402
+ signal_notes.append(
403
+ f"Gap signals: {'; '.join(gap_signals[:3])}"
404
+ )
405
+ if signal_notes:
406
+ system_parts.append("")
407
+ system_parts.append("--- This Turn ---")
408
+ system_parts.extend(signal_notes)
409
+
410
+ # Structured clarification questions (D159, spec-kit Pattern 4)
411
+ clarifications = signals.get("clarification_signals", [])
412
+ if clarifications:
413
+ system_parts.append("")
414
+ system_parts.append("--- Priority Clarification Questions ---")
415
+ for cq in clarifications[:3]:
416
+ system_parts.append(
417
+ f" [P{cq.get('priority', '?')}] {cq.get('question', '')}"
418
+ )
419
+ system_parts.append(
420
+ "IMPORTANT: Weave ONE of these clarification questions into your "
421
+ "response naturally. Do not ask all at once."
422
+ )
423
+
424
+ # Parallel execution opportunities (D161, spec-kit Pattern 7)
425
+ parallel_opps = signals.get("parallel_opportunities", [])
426
+ if parallel_opps:
427
+ system_parts.append("")
428
+ system_parts.append("--- Parallel Execution Opportunities ---")
429
+ system_parts.append(
430
+ f"Detected {len(parallel_opps)} group(s) of independent tasks "
431
+ "that could run concurrently."
432
+ )
433
+ system_parts.append(
434
+ "Mention this when discussing implementation timeline."
435
+ )
436
+
437
+ system_parts.append("")
438
+ system_parts.append(
439
+ "Respond in character. Acknowledge what the customer said, reference "
440
+ "any extracted requirements or issues, and ask a follow-up question "
441
+ "that drives toward completeness. Keep the response concise (2-4 paragraphs)."
442
+ )
443
+
444
+ system_prompt = "\n".join(system_parts)
445
+
446
+ router = get_router()
447
+ request = _LLMRequest(
448
+ messages=conversation_messages,
449
+ system_prompt=system_prompt,
450
+ max_tokens=1024,
451
+ temperature=0.7,
452
+ agent_id="icdev-requirements-analyst",
453
+ project_id=session_data.get("project_id", ""),
454
+ classification=session_data.get("classification", "CUI"),
455
+ )
456
+ response = router.invoke("intake_persona_response", request)
457
+ if response and response.content:
458
+ return response.content.strip()
459
+ return None
460
+ except Exception:
461
+ return None
462
+
463
+
464
+ # ---------------------------------------------------------------------------
465
+ # Session management
466
+ # ---------------------------------------------------------------------------
467
+
468
+ def create_session(
469
+ project_id: str,
470
+ customer_name: str,
471
+ customer_org: str = None,
472
+ impact_level: str = "IL5",
473
+ classification: str = None,
474
+ created_by: str = "icdev-requirements-analyst",
475
+ db_path=None,
476
+ role: str = "developer",
477
+ goal: str = "build",
478
+ selected_frameworks=None,
479
+ custom_role_description: str = "",
480
+ ) -> dict:
481
+ """Create a new intake session. Returns session data dict.
482
+
483
+ Classification is resolved dynamically (ADR D132):
484
+ - If provided explicitly, use that value.
485
+ - If None, resolve from project metadata (classification + impact_level).
486
+ - Public / IL2 -> "PUBLIC" (no marking required).
487
+ - IL4/IL5 -> "CUI", IL6 -> "SECRET" (backward compat per ADR D54).
488
+ """
489
+ session_id = _generate_id("sess")
490
+ conn = _get_connection(db_path)
491
+
492
+ # Validate project exists if provided
493
+ if project_id:
494
+ row = conn.execute(
495
+ "SELECT id, classification, impact_level FROM projects WHERE id = ?",
496
+ (project_id,),
497
+ ).fetchone()
498
+ if not row:
499
+ conn.close()
500
+ raise ValueError(f"Project '{project_id}' not found in database.")
501
+
502
+ # Resolve classification from project if not provided
503
+ if classification is None:
504
+ proj = dict(row) if hasattr(row, "keys") else {"classification": row[1], "impact_level": row[2]}
505
+ cls_val = (proj.get("classification") or "").upper()
506
+ il_val = (proj.get("impact_level") or "").upper()
507
+ if cls_val == "PUBLIC" or il_val == "IL2":
508
+ classification = "PUBLIC"
509
+ elif cls_val in ("SECRET", "TOP SECRET", "TOP_SECRET") or il_val == "IL6":
510
+ classification = "SECRET"
511
+ else:
512
+ classification = "CUI"
513
+ else:
514
+ if classification is None:
515
+ classification = "CUI"
516
+
517
+ conn.execute(
518
+ """INSERT INTO intake_sessions
519
+ (id, project_id, customer_name, customer_org, session_status,
520
+ classification, impact_level, created_by)
521
+ VALUES (?, ?, ?, ?, 'active', ?, ?, ?)""",
522
+ (session_id, project_id, customer_name, customer_org,
523
+ classification, impact_level, created_by),
524
+ )
525
+
526
+ # Store session context (role, goal, frameworks, custom description)
527
+ context = {
528
+ "role": role,
529
+ "goal": goal,
530
+ "selected_frameworks": selected_frameworks or [],
531
+ "custom_role_description": custom_role_description,
532
+ }
533
+ conn.execute("UPDATE intake_sessions SET context_summary = ? WHERE id = ?",
534
+ (json.dumps(context), session_id))
535
+
536
+ # Insert initial system turn
537
+ conn.execute(
538
+ """INSERT INTO intake_conversation
539
+ (session_id, turn_number, role, content, content_type)
540
+ VALUES (?, 0, 'system', ?, 'text')""",
541
+ (session_id, json.dumps({
542
+ "event": "session_created",
543
+ "project_id": project_id,
544
+ "customer_name": customer_name,
545
+ "impact_level": impact_level,
546
+ })),
547
+ )
548
+
549
+ # Generate persona-appropriate welcome message
550
+ default_welcome = (
551
+ f"Session created. Welcome, {customer_name}. "
552
+ f"I'm the ICDEV Requirements Analyst. I'll help capture and "
553
+ f"structure your requirements for a {impact_level} system. "
554
+ f"Let's start with the mission context — what problem does "
555
+ f"this system need to solve?"
556
+ )
557
+ welcome_message = default_welcome
558
+
559
+ persona = _load_persona(role, custom_role_description)
560
+ if persona:
561
+ # Try LLM-powered welcome
562
+ llm_welcome = None
563
+ if _HAS_LLM:
564
+ try:
565
+ fw_text = ""
566
+ if selected_frameworks:
567
+ fw_text = f" Compliance frameworks: {', '.join(selected_frameworks)}."
568
+ opening_system = (
569
+ f"{persona.get('system_prompt', '')}\n\n"
570
+ f"You are starting a requirements intake session with "
571
+ f"{customer_name} from {customer_org or 'their organization'}. "
572
+ f"Impact level: {impact_level}. Classification: {classification}. "
573
+ f"Goal: {goal}.{fw_text}\n\n"
574
+ f"Introduce yourself briefly in your role and ask your opening "
575
+ f"question. Keep it to 2-3 sentences."
576
+ )
577
+ router = get_router()
578
+ request = _LLMRequest(
579
+ messages=[{"role": "user", "content": "Begin the intake session."}],
580
+ system_prompt=opening_system,
581
+ max_tokens=512,
582
+ temperature=0.7,
583
+ agent_id="icdev-requirements-analyst",
584
+ project_id=project_id,
585
+ classification=classification or "CUI",
586
+ )
587
+ resp = router.invoke("intake_persona_response", request)
588
+ if resp and resp.content:
589
+ llm_welcome = resp.content.strip()
590
+ except Exception:
591
+ pass
592
+
593
+ if llm_welcome:
594
+ welcome_message = llm_welcome
595
+ elif persona.get("opening_question"):
596
+ welcome_message = persona["opening_question"].strip()
597
+
598
+ # Store welcome as first analyst turn (turn_number=1)
599
+ conn.execute(
600
+ """INSERT INTO intake_conversation
601
+ (session_id, turn_number, role, content, content_type, classification)
602
+ VALUES (?, 1, 'analyst', ?, 'text', ?)""",
603
+ (session_id, welcome_message, classification or "CUI"),
604
+ )
605
+
606
+ conn.commit()
607
+ conn.close()
608
+
609
+ if _HAS_AUDIT:
610
+ log_event(
611
+ event_type="intake_session_created",
612
+ actor=created_by,
613
+ action=f"Created intake session {session_id} for {customer_name}",
614
+ project_id=project_id,
615
+ details={"session_id": session_id, "impact_level": impact_level},
616
+ )
617
+
618
+ return {
619
+ "status": "ok",
620
+ "session_id": session_id,
621
+ "project_id": project_id,
622
+ "customer_name": customer_name,
623
+ "customer_org": customer_org,
624
+ "impact_level": impact_level,
625
+ "session_status": "active",
626
+ "readiness_score": 0.0,
627
+ "message": welcome_message,
628
+ }
629
+
630
+
631
+ def get_session(session_id: str, db_path=None) -> dict:
632
+ """Get session status and summary."""
633
+ conn = _get_connection(db_path)
634
+ row = conn.execute(
635
+ "SELECT * FROM intake_sessions WHERE id = ?", (session_id,)
636
+ ).fetchone()
637
+ if not row:
638
+ conn.close()
639
+ raise ValueError(f"Session '{session_id}' not found.")
640
+
641
+ session = dict(row)
642
+
643
+ # Get counts
644
+ req_count = conn.execute(
645
+ "SELECT COUNT(*) as cnt FROM intake_requirements WHERE session_id = ?",
646
+ (session_id,),
647
+ ).fetchone()["cnt"]
648
+
649
+ turn_count = conn.execute(
650
+ "SELECT COUNT(*) as cnt FROM intake_conversation WHERE session_id = ?",
651
+ (session_id,),
652
+ ).fetchone()["cnt"]
653
+
654
+ decomp_count = conn.execute(
655
+ "SELECT COUNT(*) as cnt FROM safe_decomposition WHERE session_id = ?",
656
+ (session_id,),
657
+ ).fetchone()["cnt"]
658
+
659
+ doc_count = conn.execute(
660
+ "SELECT COUNT(*) as cnt FROM intake_documents WHERE session_id = ?",
661
+ (session_id,),
662
+ ).fetchone()["cnt"]
663
+
664
+ conn.close()
665
+
666
+ session["requirement_count"] = req_count
667
+ session["turn_count"] = turn_count
668
+ session["decomposition_count"] = decomp_count
669
+ session["document_count"] = doc_count
670
+
671
+ return session
672
+
673
+
674
+ def resume_session(session_id: str, db_path=None) -> dict:
675
+ """Resume a paused session. Returns context summary and last state."""
676
+ conn = _get_connection(db_path)
677
+ row = conn.execute(
678
+ "SELECT * FROM intake_sessions WHERE id = ?", (session_id,)
679
+ ).fetchone()
680
+ if not row:
681
+ conn.close()
682
+ raise ValueError(f"Session '{session_id}' not found.")
683
+
684
+ session = dict(row)
685
+ if session["session_status"] not in ("active", "paused"):
686
+ conn.close()
687
+ raise ValueError(
688
+ f"Session '{session_id}' is {session['session_status']}, cannot resume."
689
+ )
690
+
691
+ # Get last 5 conversation turns for context
692
+ recent_turns = conn.execute(
693
+ """SELECT turn_number, role, content, content_type
694
+ FROM intake_conversation
695
+ WHERE session_id = ?
696
+ ORDER BY turn_number DESC LIMIT 5""",
697
+ (session_id,),
698
+ ).fetchall()
699
+ recent_turns = [dict(t) for t in reversed(recent_turns)]
700
+
701
+ # Get requirement summary
702
+ reqs = conn.execute(
703
+ """SELECT id, raw_text, requirement_type, priority, status
704
+ FROM intake_requirements
705
+ WHERE session_id = ?
706
+ ORDER BY created_at""",
707
+ (session_id,),
708
+ ).fetchall()
709
+ req_summary = [dict(r) for r in reqs]
710
+
711
+ # Update status to active
712
+ conn.execute(
713
+ "UPDATE intake_sessions SET session_status = 'active', updated_at = ? WHERE id = ?",
714
+ (datetime.now(timezone.utc).isoformat(), session_id),
715
+ )
716
+ conn.commit()
717
+ conn.close()
718
+
719
+ if _HAS_AUDIT:
720
+ log_event(
721
+ event_type="intake_session_resumed",
722
+ actor="icdev-requirements-analyst",
723
+ action=f"Resumed intake session {session_id}",
724
+ project_id=session.get("project_id"),
725
+ details={"session_id": session_id},
726
+ )
727
+
728
+ return {
729
+ "status": "ok",
730
+ "session_id": session_id,
731
+ "session_status": "active",
732
+ "readiness_score": session.get("readiness_score", 0.0),
733
+ "context_summary": session.get("context_summary", ""),
734
+ "requirement_count": len(req_summary),
735
+ "recent_turns": recent_turns,
736
+ "requirements": req_summary,
737
+ "message": f"Session resumed. You have {len(req_summary)} requirements captured "
738
+ f"with readiness score {session.get('readiness_score', 0.0):.1%}. "
739
+ f"Where would you like to continue?",
740
+ }
741
+
742
+
743
+ def pause_session(session_id: str, db_path=None) -> dict:
744
+ """Pause a session for later resumption."""
745
+ conn = _get_connection(db_path)
746
+ conn.execute(
747
+ "UPDATE intake_sessions SET session_status = 'paused', updated_at = ? WHERE id = ?",
748
+ (datetime.now(timezone.utc).isoformat(), session_id),
749
+ )
750
+ conn.commit()
751
+ conn.close()
752
+ return {"status": "ok", "session_id": session_id, "session_status": "paused"}
753
+
754
+
755
+ # ---------------------------------------------------------------------------
756
+ # Conversation processing
757
+ # ---------------------------------------------------------------------------
758
+
759
+ def process_turn(
760
+ session_id: str,
761
+ customer_message: str,
762
+ db_path=None,
763
+ ) -> dict:
764
+ """Process a customer message turn. Extracts requirements, detects gaps,
765
+ and generates analyst response.
766
+
767
+ This is the core function that the agent chat calls on each turn.
768
+ It stores the customer message, analyzes it for requirements and issues,
769
+ and returns a structured response.
770
+ """
771
+ conn = _get_connection(db_path)
772
+
773
+ # Verify session exists and is active
774
+ session = conn.execute(
775
+ "SELECT * FROM intake_sessions WHERE id = ?", (session_id,)
776
+ ).fetchone()
777
+ if not session:
778
+ conn.close()
779
+ raise ValueError(f"Session '{session_id}' not found.")
780
+ if dict(session)["session_status"] != "active":
781
+ conn.close()
782
+ raise ValueError(f"Session is {dict(session)['session_status']}, not active.")
783
+
784
+ session_data = dict(session)
785
+
786
+ # Get current turn number
787
+ last_turn = conn.execute(
788
+ "SELECT MAX(turn_number) as max_turn FROM intake_conversation WHERE session_id = ?",
789
+ (session_id,),
790
+ ).fetchone()
791
+ turn_number = (last_turn["max_turn"] or 0) + 1
792
+
793
+ # Store customer turn
794
+ conn.execute(
795
+ """INSERT INTO intake_conversation
796
+ (session_id, turn_number, role, content, content_type, classification)
797
+ VALUES (?, ?, 'customer', ?, 'text', ?)""",
798
+ (session_id, turn_number, customer_message, session_data.get("classification", "CUI")),
799
+ )
800
+
801
+ # --- Requirement extraction (deterministic keyword analysis) ---
802
+ extracted_reqs = _extract_requirements_from_text(
803
+ customer_message, session_id, turn_number, conn
804
+ )
805
+
806
+ # --- URL detection and content fetching ---
807
+ url_contents = _extract_and_fetch_urls(customer_message)
808
+
809
+ # --- Ambiguity detection (with dedup across turns) ---
810
+ raw_ambiguities = _detect_ambiguities_in_text(customer_message)
811
+
812
+ # Load previously flagged terms from context so we don't re-flag them
813
+ context = {}
814
+ try:
815
+ context = json.loads(session_data.get("context_summary") or "{}")
816
+ except (ValueError, TypeError):
817
+ pass
818
+ flagged_terms = set(context.get("flagged_ambiguities", []))
819
+ ambiguities = [a for a in raw_ambiguities if a["phrase"].lower() not in flagged_terms]
820
+
821
+ # Record newly flagged terms so future turns skip them
822
+ if ambiguities:
823
+ for a in ambiguities:
824
+ flagged_terms.add(a["phrase"].lower())
825
+ context["flagged_ambiguities"] = sorted(flagged_terms)
826
+ conn.execute(
827
+ "UPDATE intake_sessions SET context_summary = ? WHERE id = ?",
828
+ (json.dumps(context), session_id),
829
+ )
830
+
831
+ # --- Gap signals ---
832
+ gap_signals = _detect_gap_signals(customer_message, session_id, conn)
833
+
834
+ # --- Boundary flags ---
835
+ boundary_flags = _detect_boundary_signals(customer_message, session_data)
836
+
837
+ # --- DevSecOps / ZTA signals (Phase 24) ---
838
+ devsecops_signals = _detect_devsecops_signals(customer_message)
839
+ zta_signals = _detect_zta_signals(customer_message)
840
+
841
+ # --- MOSA signals (Phase 26, D125) ---
842
+ mosa_signals = _detect_mosa_signals(customer_message, session_data)
843
+
844
+ # --- Dev profile signals (Phase 34, D184-D188) ---
845
+ dev_profile_signals = _detect_dev_profile_signals(customer_message, session_data)
846
+
847
+ # --- AI governance signals (Phase 50, D322) ---
848
+ ai_governance_signals = _detect_ai_governance_signals(customer_message, session_data)
849
+
850
+ # --- Structured clarification (D159, spec-kit Pattern 4) ---
851
+ clarification_signals = []
852
+ try:
853
+ from icdev.tools.requirements.clarification_engine import analyze_requirements_clarity
854
+ db_path_resolved = db_path or DB_PATH
855
+ clarity_result = analyze_requirements_clarity(
856
+ session_id, max_questions=3, db_path=db_path_resolved,
857
+ )
858
+ clarification_signals = clarity_result.get("questions", [])
859
+ except (ImportError, Exception):
860
+ pass
861
+
862
+ # --- Detect parallel opportunities (D161, spec-kit Pattern 7) ---
863
+ parallel_opportunities = []
864
+ try:
865
+ from icdev.tools.requirements.decomposition_engine import detect_parallel_groups
866
+ db_path_resolved = db_path or DB_PATH
867
+ parallel_opportunities = detect_parallel_groups(session_id, db_path=db_path_resolved)
868
+ except (ImportError, Exception):
869
+ pass
870
+
871
+ # --- Update session counters ---
872
+ req_count = conn.execute(
873
+ "SELECT COUNT(*) as cnt FROM intake_requirements WHERE session_id = ?",
874
+ (session_id,),
875
+ ).fetchone()["cnt"]
876
+
877
+ conn.execute(
878
+ """UPDATE intake_sessions
879
+ SET total_requirements = ?,
880
+ ambiguity_count = ambiguity_count + ?,
881
+ updated_at = ?
882
+ WHERE id = ?""",
883
+ (req_count, len(ambiguities), datetime.now(timezone.utc).isoformat(), session_id),
884
+ )
885
+
886
+ # --- BDD preview generation + store as acceptance criteria ---
887
+ # Must run BEFORE readiness so testability score reflects BDD criteria
888
+ bdd_previews = []
889
+ try:
890
+ from icdev.tools.requirements.decomposition_engine import generate_bdd_criteria
891
+ for req in extracted_reqs:
892
+ gherkin = generate_bdd_criteria(req["raw_text"], req["requirement_type"])
893
+ bdd_previews.append({"requirement": req["raw_text"][:80], "gherkin": gherkin})
894
+ # Store BDD as acceptance criteria so testability score reflects it
895
+ if gherkin and req.get("id"):
896
+ conn.execute(
897
+ "UPDATE intake_requirements SET acceptance_criteria = ? WHERE id = ?",
898
+ (gherkin, req["id"]),
899
+ )
900
+ except ImportError:
901
+ pass
902
+
903
+ # Flush BDD + requirement writes so the sidebar readiness poller
904
+ # (which opens its own connection) can see them immediately.
905
+ conn.commit()
906
+
907
+ # --- Conversation coverage analysis (what topics are covered vs missing) ---
908
+ coverage = _analyze_conversation_coverage(session_id, conn)
909
+
910
+ # --- Readiness update (computed every turn, after BDD storage) ---
911
+ readiness_update = _quick_readiness_estimate(session_id, conn)
912
+
913
+ # --- Try LLM-powered persona response ---
914
+ analyst_turn = turn_number + 1
915
+ persona_signals = {
916
+ "extracted_reqs": extracted_reqs,
917
+ "ambiguities": ambiguities,
918
+ "boundary_flags": boundary_flags,
919
+ "gap_signals": gap_signals,
920
+ "devsecops_signals": devsecops_signals,
921
+ "zta_signals": zta_signals,
922
+ "mosa_signals": mosa_signals,
923
+ "ai_governance_signals": ai_governance_signals,
924
+ "readiness_update": readiness_update,
925
+ "total_requirements": req_count,
926
+ "coverage": coverage,
927
+ "url_contents": url_contents,
928
+ "clarification_signals": clarification_signals,
929
+ "parallel_opportunities": parallel_opportunities,
930
+ }
931
+ persona_response = _generate_persona_response(
932
+ session_data, customer_message, persona_signals, conn
933
+ )
934
+
935
+ if persona_response is not None:
936
+ analyst_response = persona_response
937
+ else:
938
+ # --- Fallback: deterministic analyst response ---
939
+ response_parts = []
940
+
941
+ if extracted_reqs:
942
+ response_parts.append(
943
+ f"I captured {len(extracted_reqs)} requirement(s) from what you described."
944
+ )
945
+ for req in extracted_reqs:
946
+ response_parts.append(
947
+ f" - [{req['requirement_type'].upper()}] {req['raw_text'][:100]}"
948
+ )
949
+
950
+ if url_contents:
951
+ response_parts.append("\nI reviewed the link(s) you shared:")
952
+ for uc in url_contents:
953
+ title_part = f" ({uc['title']})" if uc.get("title") else ""
954
+ response_parts.append(f" - {uc['url']}{title_part}")
955
+ if uc.get("summary") and not uc["summary"].startswith("("):
956
+ # Show a brief excerpt of the fetched content
957
+ summary_short = uc["summary"][:300]
958
+ response_parts.append(f" Content: {summary_short}")
959
+
960
+ if ambiguities:
961
+ response_parts.append(
962
+ f"\nI noticed {len(ambiguities)} term(s) that need clarification:"
963
+ )
964
+ for amb in ambiguities:
965
+ response_parts.append(f" - '{amb['phrase']}': {amb['clarification']}")
966
+
967
+ if boundary_flags:
968
+ response_parts.append("\nATO Boundary flags:")
969
+ for flag in boundary_flags:
970
+ response_parts.append(f" - [{flag['tier']}] {flag['description']}")
971
+
972
+ if gap_signals:
973
+ response_parts.append("\nPotential gaps detected:")
974
+ for gap in gap_signals:
975
+ response_parts.append(f" - {gap}")
976
+
977
+ if devsecops_signals.get("detected_stages"):
978
+ stages = devsecops_signals["detected_stages"]
979
+ maturity = devsecops_signals.get("maturity_estimate", "unknown")
980
+ response_parts.append(
981
+ f"\nDevSecOps signals detected: {', '.join(stages)} "
982
+ f"(estimated maturity: {maturity})"
983
+ )
984
+ elif devsecops_signals.get("greenfield"):
985
+ response_parts.append(
986
+ "\nNo existing DevSecOps tooling detected — "
987
+ "ICDEV will configure pipeline security stages based on impact level."
988
+ )
989
+
990
+ if zta_signals.get("zta_detected"):
991
+ pillars = zta_signals.get("detected_pillars", [])
992
+ response_parts.append(
993
+ "\nZero Trust Architecture requirement detected"
994
+ + (f" (pillars: {', '.join(pillars)})" if pillars else "")
995
+ + ". NIST SP 800-207 framework will be included in compliance assessment."
996
+ )
997
+
998
+ if mosa_signals.get("mosa_detected"):
999
+ mosa_pillars = mosa_signals.get("detected_pillars", [])
1000
+ if mosa_signals.get("dod_ic_detected"):
1001
+ response_parts.append(
1002
+ "\nDoD/IC customer detected — MOSA (Modular Open Systems Approach) "
1003
+ "is required per 10 U.S.C. §4401. ICDEV will enforce modular architecture, "
1004
+ "open standards, and interface control documentation."
1005
+ )
1006
+ else:
1007
+ response_parts.append(
1008
+ "\nMOSA (Modular Open Systems Approach) signals detected. "
1009
+ "MOSA framework will be included in compliance assessment."
1010
+ )
1011
+ if mosa_pillars:
1012
+ response_parts.append(
1013
+ f" MOSA pillars identified: {', '.join(p.replace('_', ' ') for p in mosa_pillars)}"
1014
+ )
1015
+ # Probe for missing MOSA pillars
1016
+ all_pillars = {"modular_architecture", "open_standards", "open_interfaces",
1017
+ "data_rights", "competitive_sourcing", "continuous_assessment"}
1018
+ missing = all_pillars - set(mosa_pillars)
1019
+ if missing and len(mosa_pillars) < 4:
1020
+ probes = {
1021
+ "open_interfaces": "Do you have existing Interface Control Documents (ICDs) or API specifications?",
1022
+ "data_rights": "What are the government data rights requirements? (GPR, unlimited rights, etc.)",
1023
+ "competitive_sourcing": "Is multi-vendor replaceability a requirement?",
1024
+ "open_standards": "Which standard protocols/data formats will be used? (REST/OpenAPI, gRPC, JSON, Protobuf)",
1025
+ "modular_architecture": "Is the system designed with modular, loosely-coupled components?",
1026
+ "continuous_assessment": "Will there be ongoing architecture reviews and modularity metrics?",
1027
+ }
1028
+ probe_q = [probes[p] for p in sorted(missing) if p in probes][:2]
1029
+ if probe_q:
1030
+ response_parts.append("\nTo complete MOSA assessment, please clarify:")
1031
+ for q in probe_q:
1032
+ response_parts.append(f" - {q}")
1033
+
1034
+ if ai_governance_signals.get("ai_governance_detected"):
1035
+ gov_pillars = ai_governance_signals.get("detected_pillars", [])
1036
+ if ai_governance_signals.get("federal_agency_detected"):
1037
+ response_parts.append(
1038
+ "\nFederal agency detected — AI governance requirements apply per OMB M-25-21. "
1039
+ "ICDEV will track AI inventory, model documentation, human oversight, "
1040
+ "impact assessments, transparency, and accountability."
1041
+ )
1042
+ else:
1043
+ response_parts.append(
1044
+ "\nAI/ML system usage detected. AI governance framework will be "
1045
+ "included in compliance assessment."
1046
+ )
1047
+ if gov_pillars:
1048
+ response_parts.append(
1049
+ f" AI governance pillars identified: {', '.join(p.replace('_', ' ') for p in gov_pillars)}"
1050
+ )
1051
+ # Probe for missing governance pillars
1052
+ all_gov_pillars = {"ai_inventory", "model_documentation", "human_oversight",
1053
+ "impact_assessment", "transparency", "accountability"}
1054
+ missing_gov = all_gov_pillars - set(gov_pillars)
1055
+ if missing_gov and len(gov_pillars) < 4:
1056
+ gov_probes = {
1057
+ "ai_inventory": "Does this system use AI/ML models? If so, what types (classification, NLP, recommendation, generation)?",
1058
+ "model_documentation": "Are there existing model cards or documentation for the AI models used?",
1059
+ "human_oversight": "What human oversight is in place for AI decisions? Is there an appeal process?",
1060
+ "impact_assessment": "Has an algorithmic impact assessment been conducted? Does the AI make rights-impacting decisions?",
1061
+ "transparency": "Are users notified when AI is making or supporting decisions?",
1062
+ "accountability": "Is there a designated Chief AI Officer (CAIO) or responsible official?",
1063
+ }
1064
+ probe_q = [gov_probes[p] for p in sorted(missing_gov) if p in gov_probes][:2]
1065
+ if probe_q:
1066
+ response_parts.append("\nTo complete AI governance assessment, please clarify:")
1067
+ for q in probe_q:
1068
+ response_parts.append(f" - {q}")
1069
+
1070
+ # Add readiness update and targeted follow-up question
1071
+ if readiness_update:
1072
+ response_parts.append(
1073
+ f"\nReadiness: {readiness_update['overall']:.0%} "
1074
+ f"(completeness={readiness_update['completeness']:.0%}, "
1075
+ f"clarity={readiness_update['clarity']:.0%}, "
1076
+ f"feasibility={readiness_update['feasibility']:.0%}, "
1077
+ f"compliance={readiness_update['compliance']:.0%}, "
1078
+ f"testability={readiness_update['testability']:.0%})"
1079
+ )
1080
+
1081
+ # Ask a targeted question to improve the weakest dimension
1082
+ dims = {
1083
+ "completeness": readiness_update.get("completeness", 0),
1084
+ "clarity": readiness_update.get("clarity", 0),
1085
+ "feasibility": readiness_update.get("feasibility", 0),
1086
+ "compliance": readiness_update.get("compliance", 0),
1087
+ "testability": readiness_update.get("testability", 0),
1088
+ }
1089
+ weakest = min(dims, key=dims.get)
1090
+
1091
+ # Use coverage-based targeted questions for completeness
1092
+ # instead of generic "describe user roles, workflows..."
1093
+ cov = persona_signals.get("coverage", {})
1094
+ missing_qs = cov.get("missing_questions", [])
1095
+
1096
+ followup_questions = {
1097
+ "completeness": (
1098
+ missing_qs[0] if missing_qs else
1099
+ "What other capabilities or workflows should this system support?"
1100
+ ),
1101
+ "clarity": (
1102
+ "Could you quantify some of the requirements? "
1103
+ "For example, expected number of users, response times, or data volumes."
1104
+ ),
1105
+ "feasibility": (
1106
+ "What's the target timeline, team size, "
1107
+ "and hosting environment? Any technology constraints?"
1108
+ ),
1109
+ "compliance": (
1110
+ "What security requirements apply? "
1111
+ "For example: authentication method (CAC/PIV, MFA), encryption "
1112
+ "standards, audit logging, or access control policies."
1113
+ ),
1114
+ "testability": (
1115
+ "How would you verify each requirement works? "
1116
+ "What are the pass/fail conditions or acceptance criteria?"
1117
+ ),
1118
+ }
1119
+ if dims[weakest] < 0.7:
1120
+ response_parts.append(f"\n{followup_questions[weakest]}")
1121
+
1122
+ # Structured clarification from Impact × Uncertainty matrix (D159)
1123
+ if clarification_signals:
1124
+ top_q = clarification_signals[0]
1125
+ question_text = top_q.get("question", "")
1126
+ if question_text:
1127
+ response_parts.append(f"\nTo help me clarify: {question_text}")
1128
+
1129
+ # Parallel execution opportunities (D161)
1130
+ if parallel_opportunities:
1131
+ response_parts.append(
1132
+ f"\nNote: I've identified {len(parallel_opportunities)} group(s) of "
1133
+ "independent tasks that could run in parallel to speed up delivery."
1134
+ )
1135
+
1136
+ analyst_response = "\n".join(response_parts) if response_parts else (
1137
+ "Thank you. Could you tell me more about the specific capabilities "
1138
+ "you need? For example, what are the key user workflows?"
1139
+ )
1140
+
1141
+ # Store analyst turn
1142
+ conn.execute(
1143
+ """INSERT INTO intake_conversation
1144
+ (session_id, turn_number, role, content, content_type,
1145
+ extracted_requirements, metadata, classification)
1146
+ VALUES (?, ?, 'analyst', ?, 'text', ?, ?, ?)""",
1147
+ (
1148
+ session_id,
1149
+ analyst_turn,
1150
+ analyst_response,
1151
+ json.dumps([r["id"] for r in extracted_reqs]) if extracted_reqs else None,
1152
+ json.dumps({
1153
+ "ambiguities_found": len(ambiguities),
1154
+ "requirements_extracted": len(extracted_reqs),
1155
+ "boundary_flags": len(boundary_flags),
1156
+ "devsecops_stages_detected": devsecops_signals.get("detected_stages", []),
1157
+ "devsecops_maturity_estimate": devsecops_signals.get("maturity_estimate"),
1158
+ "zta_detected": zta_signals.get("zta_detected", False),
1159
+ "zta_pillars_detected": zta_signals.get("detected_pillars", []),
1160
+ "mosa_detected": mosa_signals.get("mosa_detected", False),
1161
+ "mosa_dod_ic_detected": mosa_signals.get("dod_ic_detected", False),
1162
+ "mosa_pillars_detected": mosa_signals.get("detected_pillars", []),
1163
+ "ai_governance_detected": ai_governance_signals.get("ai_governance_detected", False),
1164
+ "ai_governance_pillars_detected": ai_governance_signals.get("detected_pillars", []),
1165
+ "ai_governance_federal_agency": ai_governance_signals.get("federal_agency_detected", False),
1166
+ "clarification_questions": len(clarification_signals),
1167
+ "parallel_groups": len(parallel_opportunities),
1168
+ }),
1169
+ session_data.get("classification", "CUI"),
1170
+ ),
1171
+ )
1172
+
1173
+ conn.commit()
1174
+ conn.close()
1175
+
1176
+ # Audit log
1177
+ if _HAS_AUDIT and extracted_reqs:
1178
+ log_event(
1179
+ event_type="requirement_captured",
1180
+ actor="icdev-requirements-analyst",
1181
+ action=f"Extracted {len(extracted_reqs)} requirement(s) from turn {turn_number}",
1182
+ project_id=session_data.get("project_id"),
1183
+ details={
1184
+ "session_id": session_id,
1185
+ "turn": turn_number,
1186
+ "count": len(extracted_reqs),
1187
+ },
1188
+ )
1189
+
1190
+ return {
1191
+ "status": "ok",
1192
+ "session_id": session_id,
1193
+ "turn_number": analyst_turn,
1194
+ "analyst_response": analyst_response,
1195
+ "extracted_requirements": extracted_reqs,
1196
+ "ambiguities": ambiguities,
1197
+ "boundary_flags": boundary_flags,
1198
+ "gap_signals": gap_signals,
1199
+ "readiness_update": readiness_update,
1200
+ "total_requirements": req_count + len(extracted_reqs),
1201
+ "bdd_previews": bdd_previews,
1202
+ "url_contents": url_contents,
1203
+ }
1204
+
1205
+
1206
+ # ---------------------------------------------------------------------------
1207
+ # Requirement extraction helpers
1208
+ # ---------------------------------------------------------------------------
1209
+
1210
+ # Requirement type detection keywords
1211
+ _REQ_TYPE_KEYWORDS = {
1212
+ "security": [
1213
+ "authenticate", "authorize", "encrypt", "CAC", "PIV", "MFA",
1214
+ "FIPS", "STIG", "access control", "audit log", "credential",
1215
+ "certificate", "PKI", "RBAC", "permission", "classification",
1216
+ ],
1217
+ "performance": [
1218
+ "response time", "latency", "throughput", "concurrent",
1219
+ "availability", "uptime", "SLA", "load", "capacity",
1220
+ ],
1221
+ "interface": [
1222
+ "integrate", "interface", "API", "REST", "SOAP", "feed",
1223
+ "import", "export", "connect", "external system", "third-party",
1224
+ ],
1225
+ "data": [
1226
+ "database", "data store", "retention", "backup", "archive",
1227
+ "migrate data", "data format", "schema", "CUI data",
1228
+ ],
1229
+ "compliance": [
1230
+ "NIST", "FedRAMP", "CMMC", "ATO", "SSP", "POAM",
1231
+ "STIG", "RMF", "accreditation", "authorization boundary",
1232
+ ],
1233
+ "non_functional": [
1234
+ "scalab", "reliab", "maintainab", "portab", "usab",
1235
+ "accessibility", "WCAG", "Section 508", "i18n", "l10n",
1236
+ ],
1237
+ }
1238
+
1239
+ # Priority detection
1240
+ _PRIORITY_KEYWORDS = {
1241
+ "critical": ["must", "shall", "critical", "mandatory", "required", "essential"],
1242
+ "high": ["should", "important", "needed", "key", "primary"],
1243
+ "medium": ["could", "nice to have", "desirable", "want"],
1244
+ "low": ["may", "optional", "future", "nice", "wish"],
1245
+ }
1246
+
1247
+
1248
+ def _extract_requirements_from_text(text, session_id, turn_number, conn):
1249
+ """Extract structured requirements from customer text using keyword analysis."""
1250
+ extracted = []
1251
+ # Split on sentence boundaries
1252
+ sentences = [s.strip() for s in text.replace("\n", ". ").split(".") if s.strip() and len(s.strip()) > 10]
1253
+
1254
+ for sentence in sentences:
1255
+ lower = sentence.lower()
1256
+
1257
+ # Check if this sentence contains requirement-like language
1258
+ has_req_signal = any(
1259
+ kw in lower
1260
+ for kw in ["need", "want", "must", "shall", "should", "require",
1261
+ "able to", "capability", "feature", "support", "provide",
1262
+ "enable", "allow", "system will", "system shall"]
1263
+ )
1264
+ if not has_req_signal:
1265
+ continue
1266
+
1267
+ # Detect type
1268
+ req_type = "functional" # default
1269
+ for rtype, keywords in _REQ_TYPE_KEYWORDS.items():
1270
+ if any(kw.lower() in lower for kw in keywords):
1271
+ req_type = rtype
1272
+ break
1273
+
1274
+ # Detect priority
1275
+ priority = "medium" # default
1276
+ for prio, keywords in _PRIORITY_KEYWORDS.items():
1277
+ if any(kw in lower for kw in keywords):
1278
+ priority = prio
1279
+ break
1280
+
1281
+ # Create requirement record — classification inherited from session
1282
+ req_id = _generate_id("req")
1283
+ sess_row = conn.execute(
1284
+ "SELECT classification FROM intake_sessions WHERE id = ?",
1285
+ (session_id,),
1286
+ ).fetchone()
1287
+ req_classification = sess_row[0] if sess_row else "CUI"
1288
+ conn.execute(
1289
+ """INSERT INTO intake_requirements
1290
+ (id, session_id, source_turn, raw_text, requirement_type,
1291
+ priority, status, classification)
1292
+ VALUES (?, ?, ?, ?, ?, ?, 'draft', ?)""",
1293
+ (req_id, session_id, turn_number, sentence.strip(), req_type,
1294
+ priority, req_classification),
1295
+ )
1296
+
1297
+ extracted.append({
1298
+ "id": req_id,
1299
+ "raw_text": sentence.strip(),
1300
+ "requirement_type": req_type,
1301
+ "priority": priority,
1302
+ })
1303
+
1304
+ return extracted
1305
+
1306
+
1307
+ def _analyze_conversation_coverage(session_id, conn):
1308
+ """Analyze conversation history to identify covered topics and specific gaps.
1309
+
1310
+ Returns dict with 'covered' (set of topic keys), 'missing' (list of
1311
+ specific gap questions), and 'summary' (string for LLM context).
1312
+ """
1313
+ # Gather all customer messages
1314
+ rows = conn.execute(
1315
+ "SELECT content FROM intake_conversation "
1316
+ "WHERE session_id = ? AND role = 'customer' ORDER BY turn_number",
1317
+ (session_id,),
1318
+ ).fetchall()
1319
+ all_text = " ".join(dict(r)["content"] for r in rows).lower()
1320
+
1321
+ # Also include requirements extracted from uploaded documents
1322
+ doc_reqs = conn.execute(
1323
+ "SELECT raw_text FROM intake_requirements "
1324
+ "WHERE session_id = ? AND source_document IS NOT NULL",
1325
+ (session_id,),
1326
+ ).fetchall()
1327
+ if doc_reqs:
1328
+ doc_text = " ".join(dict(r)["raw_text"] for r in doc_reqs).lower()
1329
+ all_text += " " + doc_text
1330
+
1331
+ # Topic detection with specific follow-up questions
1332
+ topics = {
1333
+ "users_roles": {
1334
+ "keywords": ["user", "role", "agent", "admin", "operator", "analyst",
1335
+ "viewer", "customer", "personnel", "staff"],
1336
+ "covered_question": None,
1337
+ "gap_question": "Who will use this system? What are the distinct user roles and their permissions?",
1338
+ },
1339
+ "workflow": {
1340
+ "keywords": ["workflow", "process", "step", "flow", "sequence",
1341
+ "procedure", "pipeline", "task"],
1342
+ "covered_question": None,
1343
+ "gap_question": "What's the primary user workflow from start to finish?",
1344
+ },
1345
+ "data_model": {
1346
+ "keywords": ["data", "database", "record", "field", "store", "table",
1347
+ "schema", "entity", "model", "input", "output"],
1348
+ "covered_question": None,
1349
+ "gap_question": "What data does the system manage? What are the key entities and their relationships?",
1350
+ },
1351
+ "integration": {
1352
+ "keywords": ["integrate", "api", "rest", "connect", "external",
1353
+ "third-party", "system", "mcp", "soap", "feed"],
1354
+ "covered_question": None,
1355
+ "gap_question": "What external systems does this integrate with? What protocols (REST, MCP, file)?",
1356
+ },
1357
+ "performance": {
1358
+ "keywords": ["performance", "sla", "uptime", "latency", "response time",
1359
+ "concurrent", "throughput", "availability", "99"],
1360
+ "covered_question": None,
1361
+ "gap_question": "What are the performance requirements? (SLA, response times, concurrent users)",
1362
+ },
1363
+ "security_auth": {
1364
+ "keywords": ["security", "auth", "login", "cac", "piv", "mfa",
1365
+ "encrypt", "fips", "access control", "rbac", "permission"],
1366
+ "covered_question": None,
1367
+ "gap_question": "How do users authenticate? (CAC/PIV, MFA, username/password) What access controls are needed?",
1368
+ },
1369
+ "error_handling": {
1370
+ "keywords": ["error", "fail", "exception", "retry", "fallback",
1371
+ "validation", "invalid", "reject", "deny"],
1372
+ "covered_question": None,
1373
+ "gap_question": "What happens when something goes wrong? (validation failures, system errors, invalid inputs)",
1374
+ },
1375
+ "reporting": {
1376
+ "keywords": ["report", "dashboard", "metric", "analytics", "audit",
1377
+ "log", "history", "export", "csv", "pdf"],
1378
+ "covered_question": None,
1379
+ "gap_question": "Does the system need reporting, audit trails, or dashboards? What metrics matter?",
1380
+ },
1381
+ "deployment": {
1382
+ "keywords": ["deploy", "host", "cloud", "aws", "govcloud", "on-prem",
1383
+ "environment", "staging", "production", "docker", "k8s"],
1384
+ "covered_question": None,
1385
+ "gap_question": "Where will this be deployed? (AWS GovCloud, on-prem, hybrid) What environments are needed?",
1386
+ },
1387
+ "ui_ux": {
1388
+ "keywords": ["ui", "ux", "interface", "screen", "page", "form",
1389
+ "button", "design", "mobile", "responsive", "intuitive"],
1390
+ "covered_question": None,
1391
+ "gap_question": "What should the user interface look like? (web app, mobile, desktop) Any specific UX requirements?",
1392
+ },
1393
+ "ai_governance": {
1394
+ "keywords": ["ai system", "machine learning", "ml model", "deep learning",
1395
+ "neural network", "nlp", "computer vision", "recommendation engine",
1396
+ "predictive model", "automated decision", "algorithmic", "chatbot",
1397
+ "generative ai", "llm", "foundation model", "model card",
1398
+ "human oversight", "impact assessment", "ai governance",
1399
+ "responsible ai", "caio", "chief ai officer"],
1400
+ "covered_question": None,
1401
+ "gap_question": "Does this system use AI/ML? If so, what governance is needed (model documentation, human oversight, impact assessments)?",
1402
+ },
1403
+ }
1404
+
1405
+ covered = set()
1406
+ missing_questions = []
1407
+ for topic_key, topic in topics.items():
1408
+ if any(kw in all_text for kw in topic["keywords"]):
1409
+ covered.add(topic_key)
1410
+ else:
1411
+ missing_questions.append(topic["gap_question"])
1412
+
1413
+ # Build summary for LLM context
1414
+ summary_parts = [f"Topics covered ({len(covered)}/{len(topics)}): {', '.join(sorted(covered)) or 'none'}"]
1415
+ if missing_questions:
1416
+ summary_parts.append(f"Topics NOT covered: {', '.join(sorted(set(topics.keys()) - covered))}")
1417
+ summary_parts.append("Ask about ONE of these specific gaps (pick the most important):")
1418
+ for q in missing_questions[:3]:
1419
+ summary_parts.append(f" - {q}")
1420
+
1421
+ return {
1422
+ "covered": covered,
1423
+ "total_topics": len(topics),
1424
+ "missing_questions": missing_questions,
1425
+ "summary": "\n".join(summary_parts),
1426
+ }
1427
+
1428
+
1429
+ def _extract_and_fetch_urls(text):
1430
+ """Detect URLs in customer message and fetch page content/summaries.
1431
+
1432
+ Returns a list of dicts: [{"url": "...", "title": "...", "summary": "..."}]
1433
+ Only fetches HTTP/HTTPS URLs. Best-effort — failures return a note.
1434
+ """
1435
+ url_pattern = re.compile(
1436
+ r'https?://[^\s<>\"\')]+', re.IGNORECASE
1437
+ )
1438
+ urls = url_pattern.findall(text)
1439
+ if not urls:
1440
+ return []
1441
+
1442
+ results = []
1443
+ try:
1444
+ import requests as _requests
1445
+ except ImportError:
1446
+ for u in urls:
1447
+ results.append({"url": u, "title": "", "summary": "(requests library not available)"})
1448
+ return results
1449
+
1450
+ for url in urls[:3]: # limit to 3 URLs per message
1451
+ try:
1452
+ resp = _requests.get(url, timeout=10, headers={
1453
+ "User-Agent": "ICDEV-Intake-Agent/1.0",
1454
+ "Accept": "text/html,application/json,text/plain",
1455
+ })
1456
+ resp.raise_for_status()
1457
+ content_type = resp.headers.get("Content-Type", "")
1458
+
1459
+ if "application/json" in content_type:
1460
+ # JSON API — summarize top-level keys
1461
+ try:
1462
+ data = resp.json()
1463
+ if isinstance(data, dict):
1464
+ summary = f"JSON with keys: {', '.join(list(data.keys())[:15])}"
1465
+ title = data.get("name", data.get("full_name", data.get("title", "")))
1466
+ desc = data.get("description", "")
1467
+ if desc:
1468
+ summary += f". Description: {desc}"
1469
+ elif isinstance(data, list):
1470
+ summary = f"JSON array with {len(data)} items"
1471
+ title = ""
1472
+ else:
1473
+ summary = str(data)[:300]
1474
+ title = ""
1475
+ except (ValueError, TypeError):
1476
+ summary = resp.text[:500]
1477
+ title = ""
1478
+ else:
1479
+ # HTML — extract title and meta description / first text
1480
+ body = resp.text[:50000]
1481
+ title_match = re.search(r'<title[^>]*>([^<]+)</title>', body, re.I)
1482
+ title = title_match.group(1).strip() if title_match else ""
1483
+
1484
+ # Try meta description
1485
+ meta_match = re.search(
1486
+ r'<meta\s+[^>]*name=["\']description["\']\s+content=["\']([^"\']+)',
1487
+ body, re.I
1488
+ )
1489
+ if not meta_match:
1490
+ meta_match = re.search(
1491
+ r'<meta\s+[^>]*content=["\']([^"\']+)["\'][^>]*name=["\']description',
1492
+ body, re.I
1493
+ )
1494
+ desc = meta_match.group(1).strip() if meta_match else ""
1495
+
1496
+ # Try README or about-section text for GitHub-like pages
1497
+ readme_match = re.search(
1498
+ r'<article[^>]*class="[^"]*markdown-body[^"]*"[^>]*>(.*?)</article>',
1499
+ body, re.I | re.S
1500
+ )
1501
+ readme_text = ""
1502
+ if readme_match:
1503
+ # Strip HTML tags for plain text
1504
+ raw = re.sub(r'<[^>]+>', ' ', readme_match.group(1))
1505
+ raw = re.sub(r'\s+', ' ', raw).strip()
1506
+ readme_text = raw[:800]
1507
+
1508
+ if readme_text:
1509
+ summary = f"{desc}. README: {readme_text}" if desc else f"README: {readme_text}"
1510
+ elif desc:
1511
+ summary = desc
1512
+ else:
1513
+ # Fallback: strip tags from first visible text
1514
+ stripped = re.sub(r'<script[^>]*>.*?</script>', '', body, flags=re.S | re.I)
1515
+ stripped = re.sub(r'<style[^>]*>.*?</style>', '', stripped, flags=re.S | re.I)
1516
+ stripped = re.sub(r'<[^>]+>', ' ', stripped)
1517
+ stripped = re.sub(r'\s+', ' ', stripped).strip()
1518
+ summary = stripped[:500] if stripped else "(no readable content)"
1519
+
1520
+ results.append({"url": url, "title": title, "summary": summary[:1000]})
1521
+
1522
+ except Exception as exc:
1523
+ results.append({"url": url, "title": "", "summary": f"(could not fetch: {exc})"})
1524
+
1525
+ return results
1526
+
1527
+
1528
+ def _detect_ambiguities_in_text(text):
1529
+ """Detect ambiguous terms using pattern matching."""
1530
+ ambiguities = []
1531
+ lower = text.lower()
1532
+
1533
+ # Load patterns from context file if available
1534
+ patterns_path = BASE_DIR / "context" / "requirements" / "ambiguity_patterns.json"
1535
+ if patterns_path.exists():
1536
+ with open(patterns_path, "r", encoding="utf-8") as f:
1537
+ data = json.load(f)
1538
+ patterns = data.get("ambiguity_patterns", [])
1539
+ else:
1540
+ # Fallback minimal patterns
1541
+ patterns = [
1542
+ {"phrase": "as needed", "severity": "high",
1543
+ "clarification": "Define specific conditions that trigger this action."},
1544
+ {"phrase": "appropriate", "severity": "high",
1545
+ "clarification": "Define measurable criteria."},
1546
+ {"phrase": "timely", "severity": "high",
1547
+ "clarification": "Specify an exact time threshold."},
1548
+ {"phrase": "user-friendly", "severity": "medium",
1549
+ "clarification": "Define specific usability criteria."},
1550
+ {"phrase": "fast", "severity": "high",
1551
+ "clarification": "Specify a measurable target."},
1552
+ {"phrase": "secure", "severity": "critical",
1553
+ "clarification": "Specify security requirements: FIPS, STIG, controls."},
1554
+ {"phrase": "scalable", "severity": "medium",
1555
+ "clarification": "Define target scale: users, data volume."},
1556
+ ]
1557
+
1558
+ for pattern in patterns:
1559
+ if pattern["phrase"].lower() in lower:
1560
+ ambiguities.append({
1561
+ "phrase": pattern["phrase"],
1562
+ "severity": pattern.get("severity", "medium"),
1563
+ "clarification": pattern.get("clarification", "Please clarify this term."),
1564
+ })
1565
+
1566
+ return ambiguities
1567
+
1568
+
1569
+ def _detect_gap_signals(text, session_id, conn):
1570
+ """Detect signals that may indicate requirement gaps."""
1571
+ signals = []
1572
+ lower = text.lower()
1573
+
1574
+ # Check for external system mentions without interface detail
1575
+ interface_terms = ["integrate", "connect", "interface", "external", "feed", "third-party"]
1576
+ protocol_terms = ["rest", "api", "soap", "message queue", "file", "isa", "mou"]
1577
+ if any(t in lower for t in interface_terms) and not any(t in lower for t in protocol_terms):
1578
+ signals.append(
1579
+ "External system mentioned without interface protocol — "
1580
+ "ask about REST/SOAP/MQ and ISA/MOU requirements"
1581
+ )
1582
+
1583
+ # Check for security without specifics
1584
+ if any(t in lower for t in ["secure", "security", "protect"]) and not any(
1585
+ t in lower for t in ["fips", "stig", "nist", "cac", "piv", "encrypt", "mfa"]
1586
+ ):
1587
+ signals.append(
1588
+ "Security mentioned without specifics — "
1589
+ "ask about FIPS encryption, CAC/PIV auth, STIG compliance"
1590
+ )
1591
+
1592
+ # Check for data mentions without classification
1593
+ if any(t in lower for t in ["data", "information", "records"]) and not any(
1594
+ t in lower for t in ["cui", "classified", "unclassified", "fouo", "secret"]
1595
+ ):
1596
+ signals.append(
1597
+ "Data mentioned without classification — "
1598
+ "ask about CUI categories and data handling requirements"
1599
+ )
1600
+
1601
+ return signals
1602
+
1603
+
1604
+ def _detect_boundary_signals(text, session_data):
1605
+ """Detect potential ATO boundary impact signals."""
1606
+ flags = []
1607
+ lower = text.lower()
1608
+ impact_level = session_data.get("impact_level", "IL5")
1609
+
1610
+ # Classification upgrade signals
1611
+ if impact_level in ("IL4", "IL5") and any(
1612
+ t in lower for t in ["secret", "ts/sci", "top secret", "classified"]
1613
+ ):
1614
+ flags.append({
1615
+ "tier": "RED",
1616
+ "description": f"Classification upgrade detected — current system is {impact_level} "
1617
+ f"but SECRET/TS data mentioned. This would invalidate the current ATO.",
1618
+ })
1619
+
1620
+ # New external interface
1621
+ if any(t in lower for t in ["new system", "new interface", "new connection", "new integration"]):
1622
+ flags.append({
1623
+ "tier": "ORANGE",
1624
+ "description": "New external interface — requires ISA/MOU and SSP Section 9 update.",
1625
+ })
1626
+
1627
+ # BYOD/mobile
1628
+ if any(t in lower for t in ["mobile", "byod", "personal device", "phone", "tablet"]):
1629
+ flags.append({
1630
+ "tier": "ORANGE",
1631
+ "description": "Mobile/BYOD access — requires AC-19, MDM solution, SSP boundary update.",
1632
+ })
1633
+
1634
+ # Cloud service change
1635
+ if any(t in lower for t in ["aws commercial", "azure", "gcp", "public cloud"]):
1636
+ flags.append({
1637
+ "tier": "ORANGE",
1638
+ "description": "Non-GovCloud service mentioned — current boundary is AWS GovCloud only.",
1639
+ })
1640
+
1641
+ return flags
1642
+
1643
+
1644
+ def _detect_devsecops_signals(text):
1645
+ """Detect DevSecOps maturity signals from customer text (Phase 24).
1646
+
1647
+ Uses keyword matching from args/devsecops_config.yaml to identify existing
1648
+ security tooling and estimate maturity level.
1649
+ """
1650
+ try:
1651
+ from icdev.tools.devsecops.profile_manager import detect_maturity_from_text
1652
+ return detect_maturity_from_text(text)
1653
+ except (ImportError, Exception):
1654
+ # Fallback: inline minimal detection
1655
+ lower = text.lower()
1656
+ detected = []
1657
+ keyword_map = {
1658
+ "sast": ["static analysis", "code scanning", "bandit", "sonarqube", "fortify"],
1659
+ "sca": ["dependency scan", "pip-audit", "snyk", "npm audit"],
1660
+ "secret_detection": ["secret scanning", "gitleaks", "detect-secrets"],
1661
+ "container_scan": ["container scanning", "trivy", "grype", "image scanning"],
1662
+ "policy_as_code": ["policy as code", "opa", "gatekeeper", "kyverno"],
1663
+ "image_signing": ["image signing", "cosign", "sigstore"],
1664
+ }
1665
+ for stage, keywords in keyword_map.items():
1666
+ if any(kw in lower for kw in keywords):
1667
+ detected.append(stage)
1668
+ greenfield = any(s in lower for s in [
1669
+ "no security scanning", "greenfield", "starting from scratch",
1670
+ ])
1671
+ return {
1672
+ "detected_stages": sorted(set(detected)),
1673
+ "maturity_estimate": "level_1_initial" if greenfield else (
1674
+ "level_3_defined" if len(detected) >= 4 else
1675
+ "level_2_managed" if len(detected) >= 2 else
1676
+ "level_1_initial"
1677
+ ),
1678
+ "zta_detected": False,
1679
+ "greenfield": greenfield,
1680
+ "stage_count": len(detected),
1681
+ }
1682
+
1683
+
1684
+ def _detect_zta_signals(text):
1685
+ """Detect Zero Trust Architecture signals from customer text (Phase 24-25).
1686
+
1687
+ Identifies ZTA-relevant keywords and maps them to ZTA pillars.
1688
+ """
1689
+ lower = text.lower()
1690
+ zta_detected = False
1691
+ detected_pillars = []
1692
+
1693
+ # General ZTA indicators
1694
+ general_keywords = [
1695
+ "zero trust", "nist 800-207", "never trust always verify",
1696
+ "zero trust architecture",
1697
+ ]
1698
+ if any(kw in lower for kw in general_keywords):
1699
+ zta_detected = True
1700
+
1701
+ # Pillar-specific keywords
1702
+ pillar_keywords = {
1703
+ "user_identity": ["mfa", "multi-factor", "cac", "piv", "identity provider",
1704
+ "sso", "single sign-on", "continuous auth", "icam"],
1705
+ "device": ["device posture", "mdm", "endpoint detection", "device trust",
1706
+ "device compliance", "edr"],
1707
+ "network": ["micro-segmentation", "microsegmentation", "mtls", "mutual tls",
1708
+ "service mesh", "istio", "linkerd", "network policy",
1709
+ "software-defined perimeter", "ztna"],
1710
+ "application_workload": ["workload identity", "container hardening",
1711
+ "admission control", "signed images"],
1712
+ "data": ["data classification", "encryption at rest", "dlp",
1713
+ "data loss prevention", "tokenization"],
1714
+ "visibility_analytics": ["siem", "continuous monitoring", "anomaly detection",
1715
+ "threat intelligence", "security analytics"],
1716
+ "automation_orchestration": ["soar", "auto-remediation", "security orchestration",
1717
+ "automated response", "self-healing"],
1718
+ }
1719
+
1720
+ for pillar, keywords in pillar_keywords.items():
1721
+ if any(kw in lower for kw in keywords):
1722
+ detected_pillars.append(pillar)
1723
+ zta_detected = True
1724
+
1725
+ return {
1726
+ "zta_detected": zta_detected,
1727
+ "detected_pillars": sorted(detected_pillars),
1728
+ "pillar_count": len(detected_pillars),
1729
+ }
1730
+
1731
+
1732
+ def _detect_mosa_signals(text, session_data=None):
1733
+ """Detect MOSA (Modular Open Systems Approach) signals (Phase 26, D125).
1734
+
1735
+ Auto-triggers for DoD/IC customers per 10 U.S.C. §4401. Also detects
1736
+ MOSA pillar keywords for targeted follow-up questions.
1737
+ """
1738
+ lower = text.lower()
1739
+ mosa_detected = False
1740
+ detected_pillars = []
1741
+ dod_ic_detected = False
1742
+
1743
+ # DoD/IC customer keywords — auto-trigger MOSA (D125)
1744
+ dod_ic_keywords = [
1745
+ "department of defense", "dod", "air force", "army", "navy",
1746
+ "marine corps", "space force", "intelligence community",
1747
+ "combatant command", "acquisition program", "mdap", "acat",
1748
+ "program of record", "warfighter", "nsa", "dia", "nro", "nga",
1749
+ "military", "defense information systems",
1750
+ ]
1751
+ if any(kw in lower for kw in dod_ic_keywords):
1752
+ dod_ic_detected = True
1753
+ mosa_detected = True
1754
+
1755
+ # Also check session customer_org for DoD/IC indicators
1756
+ if session_data:
1757
+ org = (session_data.get("customer_org") or "").lower()
1758
+ il = (session_data.get("impact_level") or "").upper()
1759
+ if any(kw in org for kw in ["dod", "defense", "military", "ic", "intelligence"]):
1760
+ dod_ic_detected = True
1761
+ mosa_detected = True
1762
+ if il in ("IL4", "IL5", "IL6"):
1763
+ mosa_detected = True
1764
+
1765
+ # MOSA pillar keywords (from mosa_config.yaml intake_detection)
1766
+ pillar_keywords = {
1767
+ "modular_architecture": ["modular", "loosely coupled", "microservice",
1768
+ "component-based", "plugin", "module boundary",
1769
+ "encapsulation"],
1770
+ "open_standards": ["openapi", "rest api", "grpc", "protobuf",
1771
+ "standard protocol", "open standard", "json schema"],
1772
+ "open_interfaces": ["interface control", "icd", "api versioning",
1773
+ "backward compatible", "interface specification",
1774
+ "integration spec"],
1775
+ "data_rights": ["data rights", "government purpose", "license tracking",
1776
+ "source escrow", "intellectual property", "gpr",
1777
+ "unlimited rights"],
1778
+ "competitive_sourcing": ["vendor lock-in", "vendor neutral", "competitive",
1779
+ "replaceability", "build vs buy", "multi-vendor",
1780
+ "plug-and-play"],
1781
+ "continuous_assessment": ["architecture review", "modularity metrics",
1782
+ "design review", "architecture evolution",
1783
+ "technology refresh"],
1784
+ }
1785
+
1786
+ for pillar, keywords in pillar_keywords.items():
1787
+ if any(kw in lower for kw in keywords):
1788
+ detected_pillars.append(pillar)
1789
+ mosa_detected = True
1790
+
1791
+ return {
1792
+ "mosa_detected": mosa_detected,
1793
+ "dod_ic_detected": dod_ic_detected,
1794
+ "detected_pillars": sorted(detected_pillars),
1795
+ "pillar_count": len(detected_pillars),
1796
+ }
1797
+
1798
+
1799
+ def _detect_dev_profile_signals(text, session_data=None):
1800
+ """Detect development profile signals from customer text (Phase 34, D184-D188).
1801
+
1802
+ Identifies coding standards, tooling preferences, and development methodology
1803
+ signals to recommend or auto-apply a development profile template.
1804
+ """
1805
+ try:
1806
+ from icdev.tools.builder.profile_detector import detect_from_text
1807
+ raw = detect_from_text(text)
1808
+ # Normalize to expected shape
1809
+ signals = raw.get("detected_signals", {})
1810
+ return {
1811
+ "profile_detected": raw.get("signal_count", 0) > 0,
1812
+ "detected_dimensions": sorted(signals.keys()),
1813
+ "dimension_count": raw.get("signal_count", 0),
1814
+ "suggested_templates": [],
1815
+ "raw_signals": signals,
1816
+ }
1817
+ except (ImportError, Exception):
1818
+ pass
1819
+
1820
+ # Fallback: inline minimal keyword detection
1821
+ lower = text.lower()
1822
+ detected_dimensions = []
1823
+
1824
+ dimension_keywords = {
1825
+ "language": ["python", "java", "go", "golang", "rust", "typescript", "c#",
1826
+ "csharp", ".net", "flask", "fastapi", "spring boot", "express"],
1827
+ "style": ["snake_case", "camelcase", "camel case", "naming convention",
1828
+ "code style", "indent", "line length", "prettier", "black",
1829
+ "eslint", "ruff", "gofmt", "formatting", "linter"],
1830
+ "testing": ["tdd", "bdd", "test driven", "test coverage", "unit test",
1831
+ "e2e test", "cucumber", "behave", "jest", "pytest"],
1832
+ "architecture": ["microservice", "monolith", "api gateway", "rest",
1833
+ "graphql", "event driven", "hexagonal", "layered"],
1834
+ "security": ["fips", "encryption", "secret management", "sast",
1835
+ "container hardening", "stig", "vulnerability"],
1836
+ "operations": ["kubernetes", "k8s", "docker", "docker compose",
1837
+ "gitlab ci", "github actions", "jenkins", "air-gapped"],
1838
+ "git": ["trunk-based", "gitflow", "github flow", "squash merge",
1839
+ "conventional commits", "branch naming"],
1840
+ "ai": ["bedrock", "openai", "ollama", "byok", "token budget",
1841
+ "llm", "ai model", "code generation model"],
1842
+ }
1843
+
1844
+ for dim, keywords in dimension_keywords.items():
1845
+ if any(kw in lower for kw in keywords):
1846
+ detected_dimensions.append(dim)
1847
+
1848
+ # Check for template-matching signals
1849
+ template_signals = {
1850
+ "dod_baseline": ["dod", "department of defense", "il4", "il5", "il6",
1851
+ "cmmc", "stig"],
1852
+ "fedramp_baseline": ["fedramp", "fed ramp", "jab", "3pao"],
1853
+ "healthcare_baseline": ["hipaa", "hitrust", "phi", "health"],
1854
+ "financial_baseline": ["pci dss", "pci", "sox", "financial"],
1855
+ "law_enforcement_baseline": ["cjis", "law enforcement", "fbi"],
1856
+ "startup": ["startup", "mvp", "lean", "fast iteration"],
1857
+ }
1858
+
1859
+ suggested_templates = []
1860
+ for template, keywords in template_signals.items():
1861
+ if any(kw in lower for kw in keywords):
1862
+ suggested_templates.append(template)
1863
+
1864
+ return {
1865
+ "profile_detected": len(detected_dimensions) > 0,
1866
+ "detected_dimensions": sorted(detected_dimensions),
1867
+ "dimension_count": len(detected_dimensions),
1868
+ "suggested_templates": suggested_templates,
1869
+ }
1870
+
1871
+
1872
+ def _detect_ai_governance_signals(text, session_data=None):
1873
+ """Detect AI governance signals from customer text (D322).
1874
+
1875
+ Auto-triggers for federal agencies per OMB M-25-21 and any AI/ML mention.
1876
+ Detects 6 governance pillar keywords for targeted follow-up questions.
1877
+ """
1878
+ lower = text.lower()
1879
+ ai_governance_detected = False
1880
+ detected_pillars = []
1881
+ federal_agency_detected = False
1882
+
1883
+ # AI/ML mention keywords — auto-trigger governance (D322)
1884
+ ai_ml_keywords = [
1885
+ "ai system", "machine learning", "ml model", "deep learning",
1886
+ "neural network", "natural language processing", "nlp",
1887
+ "computer vision", "recommendation engine", "predictive model",
1888
+ "automated decision", "algorithmic", "chatbot", "virtual assistant",
1889
+ "generative ai", "large language model", "llm", "foundation model",
1890
+ ]
1891
+ if any(kw in lower for kw in ai_ml_keywords):
1892
+ ai_governance_detected = True
1893
+
1894
+ # Federal agency keywords — auto-trigger per OMB M-25-21
1895
+ federal_keywords = [
1896
+ "federal agency", "omb", "executive order", "federal government",
1897
+ "government agency", "gsa", "irs", "fda", "epa", "usda",
1898
+ "hhs", "dhs", "dot", "hud", "ed.gov", "va ", "opm",
1899
+ ]
1900
+ if any(kw in lower for kw in federal_keywords):
1901
+ federal_agency_detected = True
1902
+ ai_governance_detected = True
1903
+
1904
+ # Also check session customer_org for federal indicators
1905
+ if session_data:
1906
+ org = (session_data.get("customer_org") or "").lower()
1907
+ if any(kw in org for kw in ["federal", "agency", "government", "gsa",
1908
+ "omb", "dod", "defense", "military"]):
1909
+ federal_agency_detected = True
1910
+ ai_governance_detected = True
1911
+
1912
+ # Governance pillar keywords (from ai_governance_config.yaml)
1913
+ pillar_keywords = {
1914
+ "ai_inventory": [
1915
+ "ai system", "machine learning", "ml model", "deep learning",
1916
+ "neural network", "nlp", "computer vision", "recommendation engine",
1917
+ "predictive model", "automated decision", "algorithmic", "chatbot",
1918
+ "generative ai", "llm", "foundation model",
1919
+ ],
1920
+ "model_documentation": [
1921
+ "model card", "model documentation", "training data",
1922
+ "model performance", "model accuracy", "model bias",
1923
+ "model validation", "model versioning",
1924
+ ],
1925
+ "human_oversight": [
1926
+ "human oversight", "human in the loop", "human on the loop",
1927
+ "manual review", "human approval", "override capability",
1928
+ "escalation", "appeal process",
1929
+ ],
1930
+ "impact_assessment": [
1931
+ "impact assessment", "rights impacting", "safety critical",
1932
+ "high risk ai", "algorithmic impact", "disparate impact",
1933
+ "bias assessment", "fairness",
1934
+ ],
1935
+ "transparency": [
1936
+ "transparency", "explainability", "interpretability",
1937
+ "notice", "disclosure", "ai disclosure",
1938
+ ],
1939
+ "accountability": [
1940
+ "accountability", "responsible ai", "caio",
1941
+ "chief ai officer", "ai governance", "ethics review",
1942
+ "incident response",
1943
+ ],
1944
+ }
1945
+
1946
+ for pillar, keywords in pillar_keywords.items():
1947
+ if any(kw in lower for kw in keywords):
1948
+ detected_pillars.append(pillar)
1949
+ ai_governance_detected = True
1950
+
1951
+ return {
1952
+ "ai_governance_detected": ai_governance_detected,
1953
+ "federal_agency_detected": federal_agency_detected,
1954
+ "detected_pillars": sorted(detected_pillars),
1955
+ "pillar_count": len(detected_pillars),
1956
+ }
1957
+
1958
+
1959
+ def _quick_readiness_estimate(session_id, conn):
1960
+ """Quick readiness estimate based on requirement counts and quality."""
1961
+ reqs = conn.execute(
1962
+ "SELECT * FROM intake_requirements WHERE session_id = ?",
1963
+ (session_id,),
1964
+ ).fetchall()
1965
+
1966
+ total = len(reqs)
1967
+ if total == 0:
1968
+ return {"overall": 0.0, "completeness": 0.0, "clarity": 1.0,
1969
+ "feasibility": 0.5, "compliance": 0.0, "testability": 0.0}
1970
+
1971
+ # Completeness: check if we have multiple types
1972
+ types = set(dict(r)["requirement_type"] for r in reqs)
1973
+ type_coverage = len(types) / 6.0 # 6 major types
1974
+ completeness = min(1.0, type_coverage * (min(total, 20) / 20.0))
1975
+
1976
+ # Clarity: based on unresolved ambiguities vs total requirements
1977
+ # Resolved = flagged but user has continued the conversation (addressed it)
1978
+ sess_row = conn.execute(
1979
+ "SELECT ambiguity_count, context_summary FROM intake_sessions WHERE id = ?",
1980
+ (session_id,),
1981
+ ).fetchone()
1982
+ sess_dict = dict(sess_row) if sess_row else {}
1983
+ amb_count = sess_dict.get("ambiguity_count", 0)
1984
+ ctx = {}
1985
+ try:
1986
+ ctx = json.loads(sess_dict.get("context_summary") or "{}")
1987
+ except (ValueError, TypeError):
1988
+ pass
1989
+ flagged = ctx.get("flagged_ambiguities", [])
1990
+ # Count user turns after ambiguities were first flagged as clarification
1991
+ turn_count = conn.execute(
1992
+ "SELECT COUNT(*) as cnt FROM intake_conversation "
1993
+ "WHERE session_id = ? AND role = 'customer'",
1994
+ (session_id,),
1995
+ ).fetchone()["cnt"]
1996
+ # Each user turn after the first resolves ambiguity somewhat
1997
+ resolved_credit = min(len(flagged), max(0, turn_count - 1)) if flagged else 0
1998
+ unresolved = max(0, len(flagged) - resolved_credit)
1999
+ # Clarity starts at 50% (baseline for having requirements), penalized by
2000
+ # unresolved ambiguities, boosted by conversation depth
2001
+ clarity_base = 0.50
2002
+ penalty = min(0.40, unresolved * 0.15)
2003
+ depth_bonus = min(0.50, turn_count * 0.05) # each turn adds 5%, up to 50%
2004
+ clarity = min(1.0, max(0.0, clarity_base - penalty + depth_bonus))
2005
+
2006
+ # Feasibility: assume 0.5 without architect review
2007
+ feasibility = 0.5
2008
+
2009
+ # Compliance: check selected frameworks + security-type requirements
2010
+ context = {}
2011
+ try:
2012
+ ctx_row = conn.execute(
2013
+ "SELECT context_summary FROM intake_sessions WHERE id = ?",
2014
+ (session_id,),
2015
+ ).fetchone()
2016
+ if ctx_row:
2017
+ context = json.loads(dict(ctx_row).get("context_summary") or "{}")
2018
+ except (ValueError, TypeError):
2019
+ pass
2020
+ selected_fw = context.get("selected_frameworks", [])
2021
+ sec_reqs = sum(1 for r in reqs if dict(r)["requirement_type"] in ("security", "compliance"))
2022
+
2023
+ if selected_fw:
2024
+ # Selecting frameworks IS the compliance declaration — full credit.
2025
+ compliance = 1.0
2026
+ else:
2027
+ compliance = min(1.0, sec_reqs / max(3, 1))
2028
+
2029
+ # Testability: check for acceptance criteria (BDD/Gherkin stored during turn)
2030
+ with_criteria = 0
2031
+ for r in reqs:
2032
+ rd = dict(r)
2033
+ ac = rd.get("acceptance_criteria") or ""
2034
+ if ac.strip():
2035
+ with_criteria += 1
2036
+ testability = with_criteria / max(total, 1)
2037
+
2038
+ config = _load_config()
2039
+ weights = config.get("ricoas", {}).get("readiness_weights", {
2040
+ "completeness": 0.25, "clarity": 0.25, "feasibility": 0.20,
2041
+ "compliance": 0.15, "testability": 0.15,
2042
+ })
2043
+
2044
+ overall = (
2045
+ completeness * weights.get("completeness", 0.25) +
2046
+ clarity * weights.get("clarity", 0.25) +
2047
+ feasibility * weights.get("feasibility", 0.20) +
2048
+ compliance * weights.get("compliance", 0.15) +
2049
+ testability * weights.get("testability", 0.15)
2050
+ )
2051
+
2052
+ return {
2053
+ "overall": round(overall, 3),
2054
+ "completeness": round(completeness, 3),
2055
+ "clarity": round(clarity, 3),
2056
+ "feasibility": round(feasibility, 3),
2057
+ "compliance": round(compliance, 3),
2058
+ "testability": round(testability, 3),
2059
+ }
2060
+
2061
+
2062
+ # ---------------------------------------------------------------------------
2063
+ # Export
2064
+ # ---------------------------------------------------------------------------
2065
+
2066
+ def export_requirements(session_id: str, db_path=None) -> dict:
2067
+ """Export all requirements from a session as structured JSON."""
2068
+ conn = _get_connection(db_path)
2069
+ reqs = conn.execute(
2070
+ "SELECT * FROM intake_requirements WHERE session_id = ? ORDER BY created_at",
2071
+ (session_id,),
2072
+ ).fetchall()
2073
+
2074
+ session = conn.execute(
2075
+ "SELECT * FROM intake_sessions WHERE id = ?", (session_id,)
2076
+ ).fetchone()
2077
+ conn.close()
2078
+
2079
+ if not session:
2080
+ raise ValueError(f"Session '{session_id}' not found.")
2081
+
2082
+ return {
2083
+ "status": "ok",
2084
+ "session_id": session_id,
2085
+ "project_id": dict(session).get("project_id"),
2086
+ "customer_name": dict(session).get("customer_name"),
2087
+ "impact_level": dict(session).get("impact_level"),
2088
+ "readiness_score": dict(session).get("readiness_score", 0.0),
2089
+ "total_requirements": len(reqs),
2090
+ "requirements": [dict(r) for r in reqs],
2091
+ "exported_at": datetime.now(timezone.utc).isoformat(),
2092
+ }
2093
+
2094
+
2095
+ # ---------------------------------------------------------------------------
2096
+ # CLI
2097
+ # ---------------------------------------------------------------------------
2098
+
2099
+ def main():
2100
+ parser = argparse.ArgumentParser(
2101
+ description="ICDEV Requirements Intake Engine"
2102
+ )
2103
+ parser.add_argument("--project-id", help="ICDEV project ID")
2104
+ parser.add_argument("--session-id", help="Existing session ID")
2105
+ parser.add_argument("--customer-name", help="Customer name (for new session)")
2106
+ parser.add_argument("--customer-org", help="Customer organization")
2107
+ parser.add_argument(
2108
+ "--impact-level",
2109
+ choices=["IL2", "IL4", "IL5", "IL6"],
2110
+ default="IL5",
2111
+ help="Classification impact level",
2112
+ )
2113
+ parser.add_argument(
2114
+ "--classification",
2115
+ choices=["CUI", "FOUO", "Public", "SECRET", "TOP_SECRET", "NONE"],
2116
+ default=None,
2117
+ help="Data classification override (default: resolved from project)",
2118
+ )
2119
+ parser.add_argument("--message", help="Customer message (single turn)")
2120
+ parser.add_argument("--resume", action="store_true", help="Resume paused session")
2121
+ parser.add_argument("--pause", action="store_true", help="Pause active session")
2122
+ parser.add_argument("--score-readiness", action="store_true", help="Score readiness")
2123
+ parser.add_argument("--export", action="store_true", help="Export requirements")
2124
+ parser.add_argument("--status", action="store_true", help="Get session status")
2125
+ parser.add_argument("--json", action="store_true", help="JSON output")
2126
+ args = parser.parse_args()
2127
+
2128
+ try:
2129
+ result = None
2130
+
2131
+ if args.session_id and args.resume:
2132
+ result = resume_session(args.session_id)
2133
+
2134
+ elif args.session_id and args.pause:
2135
+ result = pause_session(args.session_id)
2136
+
2137
+ elif args.session_id and args.message:
2138
+ result = process_turn(args.session_id, args.message)
2139
+
2140
+ elif args.session_id and args.score_readiness:
2141
+ conn = _get_connection()
2142
+ readiness = _quick_readiness_estimate(args.session_id, conn)
2143
+ conn.close()
2144
+ result = {"status": "ok", "session_id": args.session_id, "readiness": readiness}
2145
+
2146
+ elif args.session_id and args.export:
2147
+ result = export_requirements(args.session_id)
2148
+
2149
+ elif args.session_id and args.status:
2150
+ result = get_session(args.session_id)
2151
+
2152
+ elif args.customer_name and args.project_id:
2153
+ # Resolve classification: NONE -> "PUBLIC", None -> resolve from project
2154
+ cls_override = args.classification
2155
+ if cls_override == "NONE":
2156
+ cls_override = "PUBLIC"
2157
+ result = create_session(
2158
+ project_id=args.project_id,
2159
+ customer_name=args.customer_name,
2160
+ customer_org=args.customer_org,
2161
+ impact_level=args.impact_level,
2162
+ classification=cls_override,
2163
+ )
2164
+
2165
+ else:
2166
+ parser.print_help()
2167
+ return
2168
+
2169
+ if args.json:
2170
+ print(json.dumps(result, indent=2, default=str))
2171
+ else:
2172
+ if "message" in result:
2173
+ print(result["message"])
2174
+ elif "analyst_response" in result:
2175
+ print(result["analyst_response"])
2176
+ else:
2177
+ print(json.dumps(result, indent=2, default=str))
2178
+
2179
+ except (ValueError, FileNotFoundError) as e:
2180
+ if args.json:
2181
+ print(json.dumps({"error": str(e)}, indent=2))
2182
+ else:
2183
+ print(f"Error: {e}")
2184
+ raise SystemExit(1)
2185
+
2186
+
2187
+ if __name__ == "__main__":
2188
+ main()