icdev 0.0.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1214) hide show
  1. args/agent_config.yaml +113 -0
  2. args/audit_regimes/cisa_sbd.json +381 -0
  3. args/audit_regimes/cmmc_l2.json +906 -0
  4. args/audit_regimes/dod_cssp.json +393 -0
  5. args/audit_regimes/dodi_5000_87.json +297 -0
  6. args/audit_regimes/fedramp_moderate.json +650 -0
  7. args/audit_regimes/ieee_1012.json +373 -0
  8. args/audit_regimes/nist_800_171.json +624 -0
  9. args/audit_regimes/nist_800_53.json +907 -0
  10. args/cloudforge_blueprints/aws_commercial.yaml +29 -0
  11. args/cloudforge_blueprints/aws_govcloud_il4.yaml +34 -0
  12. args/cloudforge_blueprints/aws_govcloud_il5.yaml +38 -0
  13. args/cloudforge_blueprints/azure_commercial.yaml +28 -0
  14. args/cloudforge_blueprints/azure_gov_il4.yaml +32 -0
  15. args/cloudforge_blueprints/azure_gov_il5.yaml +36 -0
  16. args/cloudforge_blueprints/gcp_commercial.yaml +28 -0
  17. args/cloudforge_blueprints/oci_commercial.yaml +28 -0
  18. args/cloudforge_config.yaml +231 -0
  19. args/cloudforge_runbook_templates/backup_verify.yaml +98 -0
  20. args/cloudforge_runbook_templates/dr_failover.yaml +107 -0
  21. args/cloudforge_runbook_templates/health_check.yaml +97 -0
  22. args/cloudforge_runbook_templates/incident_response.yaml +101 -0
  23. args/cloudforge_runbook_templates/migration_cutover.yaml +105 -0
  24. args/cloudforge_runbook_templates/patch_rollout.yaml +92 -0
  25. args/cloudforge_runbook_templates/zone_provision.yaml +93 -0
  26. args/code_pattern_config.yaml +151 -0
  27. args/code_quality_config.yaml +47 -0
  28. args/compliance_config.yaml +17 -0
  29. args/control_inheritance.yaml +177 -0
  30. args/csp_mcp_config.yaml +41 -0
  31. args/cui_markings.yaml +35 -0
  32. args/databridge_config.yaml +232 -0
  33. args/db_config.yaml +116 -0
  34. args/decision_tables/agent_trust_decision.yaml +143 -0
  35. args/decision_tables/ato_boundary_impact.yaml +132 -0
  36. args/decision_tables/deployment_approval.yaml +152 -0
  37. args/degradation_matrix.yaml +163 -0
  38. args/devsecops_config.yaml +286 -0
  39. args/endpoint_security_config.yaml +207 -0
  40. args/exit_criteria.yaml +102 -0
  41. args/feature_flags.yaml +235 -0
  42. args/file_access_tiers.yaml +88 -0
  43. args/forge_studio/blueprint_config.yaml +27 -0
  44. args/forge_studio/component_catalog.json +411 -0
  45. args/forge_studio/workflow_templates.yaml +103 -0
  46. args/govcon_config.yaml +41 -0
  47. args/harness_config.yaml +67 -0
  48. args/innovation_config.yaml +321 -0
  49. args/knowledge_graph_config.yaml +113 -0
  50. args/llm_config.yaml +222 -0
  51. args/marketplace_config.yaml +260 -0
  52. args/monitoring_config.yaml +127 -0
  53. args/mosa_config.yaml +190 -0
  54. args/observability_tracing_config.yaml +170 -0
  55. args/owasp_agentic_config.yaml +171 -0
  56. args/pipeline_gates.yaml +197 -0
  57. args/project_defaults.yaml +235 -0
  58. args/prompt_chains.yaml +163 -0
  59. args/rag_config.yaml +167 -0
  60. args/research_config.yaml +89 -0
  61. args/resilience_config.yaml +197 -0
  62. args/ricoas_config.yaml +191 -0
  63. args/security_gates.yaml +763 -0
  64. args/storage_config.yaml +63 -0
  65. args/writeguard_config.yaml +131 -0
  66. args/zta_config.yaml +247 -0
  67. context/__init__.py +6 -0
  68. context/agent/__init__.py +6 -0
  69. context/agent/response_schemas/__init__.py +6 -0
  70. context/agent/response_schemas/debate_position.json +46 -0
  71. context/agent/response_schemas/fitness_scorecard.json +74 -0
  72. context/agent/response_schemas/review_decision.json +39 -0
  73. context/agent/response_schemas/task_decomposition.json +82 -0
  74. context/agent/response_schemas/veto_decision.json +40 -0
  75. context/agentic/__init__.py +6 -0
  76. context/agentic/architecture_patterns.md +269 -0
  77. context/agentic/capability_registry.yaml +223 -0
  78. context/agentic/csp_integration.md +30 -0
  79. context/agentic/csp_mcp_registry.yaml +280 -0
  80. context/agentic/fitness_rubric.md +56 -0
  81. context/agentic/governance_baseline.md +205 -0
  82. context/ci/__init__.py +6 -0
  83. context/ci/worktree_templates.json +44 -0
  84. context/cloud/__init__.py +6 -0
  85. context/cloud/csp_service_registry.json +739 -0
  86. context/compliance/__init__.py +6 -0
  87. context/compliance/ai_rmf_crosswalk.yaml +226 -0
  88. context/compliance/atlas_mitigations.json +293 -0
  89. context/compliance/atlas_techniques.json +833 -0
  90. context/compliance/cisa_sbd_requirements.json +477 -0
  91. context/compliance/cjis_security_policy.json +522 -0
  92. context/compliance/cmmc_practices.json +2494 -0
  93. context/compliance/cmmc_report_template.md +142 -0
  94. context/compliance/cnssi_1253_overlay.json +109 -0
  95. context/compliance/control_crosswalk.json +1914 -0
  96. context/compliance/control_families/__init__.py +6 -0
  97. context/compliance/csp_certifications.json +251 -0
  98. context/compliance/cssp_report_template.md +193 -0
  99. context/compliance/cui_templates/__init__.py +6 -0
  100. context/compliance/cui_templates/banner_block.txt +4 -0
  101. context/compliance/cui_templates/code_header.txt +8 -0
  102. context/compliance/cui_templates/document_template.md +35 -0
  103. context/compliance/data_type_framework_map.json +321 -0
  104. context/compliance/data_type_registry.json +147 -0
  105. context/compliance/dod_cssp_8530.json +463 -0
  106. context/compliance/eu_ai_act_annex_iii.json +108 -0
  107. context/compliance/export_templates/__init__.py +6 -0
  108. context/compliance/export_templates/emass_controls.csv.j2 +4 -0
  109. context/compliance/export_templates/evidence_package.md.j2 +39 -0
  110. context/compliance/export_templates/executive_summary.md.j2 +55 -0
  111. context/compliance/export_templates/poam_tracking.csv.j2 +4 -0
  112. context/compliance/fedramp_20x_ksi_schemas.json +133 -0
  113. context/compliance/fedramp_high_baseline.json +4370 -0
  114. context/compliance/fedramp_moderate_baseline.json +2183 -0
  115. context/compliance/fedramp_report_template.md +181 -0
  116. context/compliance/fips_200_areas.json +362 -0
  117. context/compliance/gao_ai_accountability.json +262 -0
  118. context/compliance/hipaa_security_rule.json +720 -0
  119. context/compliance/hitrust_csf_v11.json +930 -0
  120. context/compliance/impact_level_profiles.json +251 -0
  121. context/compliance/incident_response_template.md +1110 -0
  122. context/compliance/iso27001_2022_controls.json +750 -0
  123. context/compliance/iso27001_nist_bridge.json +382 -0
  124. context/compliance/iso42001_controls.json +254 -0
  125. context/compliance/ivv_checklist_template.md +80 -0
  126. context/compliance/ivv_report_template.md +116 -0
  127. context/compliance/ivv_requirements.json +372 -0
  128. context/compliance/mosa_crosswalk.json +327 -0
  129. context/compliance/mosa_framework.json +250 -0
  130. context/compliance/narrative_templates/AC.md.j2 +101 -0
  131. context/compliance/narrative_templates/AU.md.j2 +106 -0
  132. context/compliance/narrative_templates/IA.md.j2 +104 -0
  133. context/compliance/narrative_templates/SC.md.j2 +102 -0
  134. context/compliance/narrative_templates/SI.md.j2 +111 -0
  135. context/compliance/narrative_templates/__init__.py +6 -0
  136. context/compliance/narrative_templates/default.md.j2 +50 -0
  137. context/compliance/narrative_templates/executive_summary.j2 +27 -0
  138. context/compliance/narrative_templates/poam_milestone.j2 +19 -0
  139. context/compliance/narrative_templates/ssp_section.j2 +11 -0
  140. context/compliance/nist_800_171_controls.json +1552 -0
  141. context/compliance/nist_800_207_crosswalk.json +399 -0
  142. context/compliance/nist_800_207_zta.json +258 -0
  143. context/compliance/nist_800_53.json +324 -0
  144. context/compliance/nist_ai_600_1_genai.json +326 -0
  145. context/compliance/nist_ai_rmf.json +206 -0
  146. context/compliance/nist_sp_800_60_types.json +1667 -0
  147. context/compliance/omb_m25_21_high_impact_ai.json +248 -0
  148. context/compliance/omb_m26_04_unbiased_ai.json +262 -0
  149. context/compliance/owasp_agentic_asi.json +133 -0
  150. context/compliance/owasp_agentic_threats.json +285 -0
  151. context/compliance/owasp_llm_top10.json +274 -0
  152. context/compliance/pci_dss_v4.json +510 -0
  153. context/compliance/poam_template.md +117 -0
  154. context/compliance/safeai_controls.json +512 -0
  155. context/compliance/sbd_report_template.md +77 -0
  156. context/compliance/siem_config_templates/__init__.py +6 -0
  157. context/compliance/siem_config_templates/filebeat.yml +213 -0
  158. context/compliance/siem_config_templates/log_sources.json +208 -0
  159. context/compliance/soc2_trust_criteria.json +661 -0
  160. context/compliance/ssp_template.md +432 -0
  161. context/compliance/stig_templates/__init__.py +6 -0
  162. context/compliance/stig_templates/webapp_stig.json +139 -0
  163. context/compliance/xai_requirements.json +108 -0
  164. context/dashboard/__init__.py +6 -0
  165. context/dashboard/nlq_examples.json +50 -0
  166. context/dashboard/schema_descriptions.json +23 -0
  167. context/icdev_methodology.md +100 -0
  168. context/integration/__init__.py +6 -0
  169. context/integration/approval_workflows.json +32 -0
  170. context/integration/gitlab_field_mappings.json +33 -0
  171. context/integration/jira_field_mappings.json +32 -0
  172. context/integration/reqif_export_schema.json +23 -0
  173. context/integration/servicenow_field_mappings.json +22 -0
  174. context/languages/__init__.py +6 -0
  175. context/languages/framework_patterns.json +205 -0
  176. context/languages/language_registry.json +279 -0
  177. context/llm/__init__.py +6 -0
  178. context/llm/example_provider.py +89 -0
  179. context/marketplace/assets/writeguard-core.yaml +100 -0
  180. context/marketplace/assets/writeguard-govcon.yaml +45 -0
  181. context/marketplace/assets/writeguard-style-guides.yaml +44 -0
  182. context/mbse/__init__.py +6 -0
  183. context/mbse/des_report_template.md +162 -0
  184. context/mbse/des_requirements.json +411 -0
  185. context/mbse/digital_thread_patterns.json +403 -0
  186. context/mbse/reqif_schema.json +280 -0
  187. context/mbse/sysml_element_types.json +432 -0
  188. context/oscal/NIST_SP-800-53_rev5_catalog.json +254987 -0
  189. context/oscal/README.md +43 -0
  190. context/patterns/__init__.py +6 -0
  191. context/profiles/__init__.py +6 -0
  192. context/profiles/dod_baseline_v1.yaml +145 -0
  193. context/profiles/fedramp_baseline_v1.yaml +143 -0
  194. context/profiles/financial_baseline_v1.yaml +142 -0
  195. context/profiles/healthcare_baseline_v1.yaml +135 -0
  196. context/profiles/law_enforcement_v1.yaml +129 -0
  197. context/profiles/startup_v1.yaml +134 -0
  198. context/rag/source_mappings.json +42 -0
  199. context/requirements/__init__.py +6 -0
  200. context/requirements/ambiguity_patterns.json +97 -0
  201. context/requirements/boundary_impact_rules.json +123 -0
  202. context/requirements/default_constitutions.json +67 -0
  203. context/requirements/document_extraction_rules.json +58 -0
  204. context/requirements/gap_patterns.json +108 -0
  205. context/requirements/readiness_rubric.json +78 -0
  206. context/requirements/red_alternative_patterns.json +210 -0
  207. context/requirements/safe_templates.json +72 -0
  208. context/requirements/spec_quality_checklist.json +122 -0
  209. context/research/regulatory_registry.json +114 -0
  210. context/research/verticals/cybersecurity.json +127 -0
  211. context/research/verticals/defense.json +104 -0
  212. context/research/verticals/fintech.json +125 -0
  213. context/research/verticals/healthcare.json +118 -0
  214. context/research/verticals/logistics.json +117 -0
  215. context/research/verticals/trading.json +145 -0
  216. context/simulation/__init__.py +6 -0
  217. context/simulation/architecture_patterns.json +36 -0
  218. context/simulation/coa_templates.json +38 -0
  219. context/simulation/cost_models.json +23 -0
  220. context/simulation/risk_categories.json +46 -0
  221. context/supply_chain/__init__.py +6 -0
  222. context/supply_chain/isa_templates.json +129 -0
  223. context/supply_chain/nist_800_161_controls.json +247 -0
  224. context/supply_chain/scrm_risk_matrix.json +147 -0
  225. context/templates/__init__.py +6 -0
  226. context/templates/ansible/__init__.py +6 -0
  227. context/templates/ansible/playbooks/__init__.py +6 -0
  228. context/templates/ansible/roles/__init__.py +6 -0
  229. context/templates/gitlab_ci/__init__.py +6 -0
  230. context/templates/grafana/__init__.py +6 -0
  231. context/templates/kubernetes/__init__.py +6 -0
  232. context/templates/project/__init__.py +6 -0
  233. context/templates/project/api/__init__.py +6 -0
  234. context/templates/project/cli/__init__.py +6 -0
  235. context/templates/project/data_pipeline/__init__.py +6 -0
  236. context/templates/project/iac/__init__.py +6 -0
  237. context/templates/project/javascript_frontend/__init__.py +6 -0
  238. context/templates/project/javascript_frontend/src/__init__.py +6 -0
  239. context/templates/project/javascript_frontend/tests/__init__.py +6 -0
  240. context/templates/project/microservice/__init__.py +6 -0
  241. context/templates/project/python_backend/__init__.py +6 -0
  242. context/templates/project/python_backend/src/__init__.py +6 -0
  243. context/templates/project/python_backend/tests/__init__.py +6 -0
  244. context/templates/project/python_backend/tests/features/__init__.py +6 -0
  245. context/templates/project/python_backend/tests/steps/__init__.py +6 -0
  246. context/templates/terraform/__init__.py +6 -0
  247. context/templates/terraform/govcloud_base/__init__.py +6 -0
  248. context/templates/terraform/modules/__init__.py +6 -0
  249. context/tone/__init__.py +6 -0
  250. context/writing/grammar_rules/common_errors.json +306 -0
  251. context/writing/grammar_rules/govcon_vocabulary.json +113 -0
  252. context/writing/style_guides/academic.yaml +43 -0
  253. context/writing/style_guides/business.yaml +42 -0
  254. context/writing/style_guides/government.yaml +59 -0
  255. context/writing/style_guides/proposal.yaml +58 -0
  256. context/writing/style_guides/technical.yaml +43 -0
  257. docs/adr/README.md +66 -0
  258. docs/adr/connector-forge-decisions.md +318 -0
  259. docs/adr/core-decisions.md +289 -0
  260. docs/adr/db-decisions.md +94 -0
  261. docs/adr/harness-decisions.md +122 -0
  262. docs/adr/innovation-decisions.md +262 -0
  263. docs/adr/marketplace-decisions.md +109 -0
  264. docs/adr/sbd-decisions.md +109 -0
  265. docs/adr/scale-engine-decisions.md +108 -0
  266. docs/adr/writeguard-decisions.md +136 -0
  267. docs/architecture/bounded-contexts.md +1032 -0
  268. docs/features/phase-65-writeguard.md +139 -0
  269. docs/features/phase-66-marketplace-commerce.md +79 -0
  270. docs/features/phase-67-knowledge-ingestion-rag-autodraft.md +97 -0
  271. docs/features/phase-68-enhanced-autodraft-pipeline.md +109 -0
  272. docs/features/phase-69-proposalai-marketplace-module.md +131 -0
  273. docs/features/phase-70-databridge.md +214 -0
  274. docs/features/phase-71-databridge-messaging.md +102 -0
  275. docs/implementation-plan-architecture-evolution.md +614 -0
  276. docs/marketplace/CONTRIBUTING.md +124 -0
  277. docs/marketplace/module_manifest_schema.yaml +83 -0
  278. docs/research/ai-architecture-patterns-2024-2026.md +1236 -0
  279. docs/research/app-builder-platform-analysis.md +582 -0
  280. docs/research/architecture-patterns-c4-ddd-agentic.md +871 -0
  281. docs/research/flowable-boat-competitive-analysis.md +426 -0
  282. docs/research/modern-dev-practices-2024-2026.md +1615 -0
  283. docs/research/secure-by-design-cloudyrion-adaptation.md +270 -0
  284. goals/agent_management.md +144 -0
  285. goals/ai_accountability.md +90 -0
  286. goals/ai_narratives.md +79 -0
  287. goals/ai_transparency.md +76 -0
  288. goals/ato_simulator.md +78 -0
  289. goals/audit_engine.md +177 -0
  290. goals/bite_sized_plans.md +225 -0
  291. goals/boundary_supply_chain.md +206 -0
  292. goals/brainstorming_gate.md +186 -0
  293. goals/build_app.md +604 -0
  294. goals/cato_live_evidence.md +77 -0
  295. goals/cloudforge.md +106 -0
  296. goals/code_intelligence.md +197 -0
  297. goals/compliance_workflow.md +858 -0
  298. goals/connector_forge.md +133 -0
  299. goals/databridge.md +128 -0
  300. goals/deploy_workflow.md +390 -0
  301. goals/developer_scorecard.md +78 -0
  302. goals/devsecops_workflow.md +408 -0
  303. goals/firmware_sbom.md +79 -0
  304. goals/forge_hub.md +78 -0
  305. goals/golden_path.md +77 -0
  306. goals/harness_engineering.md +91 -0
  307. goals/integration_testing.md +189 -0
  308. goals/knowledge_graph.md +128 -0
  309. goals/maintenance_audit.md +196 -0
  310. goals/manifest.md +50 -0
  311. goals/monitoring.md +126 -0
  312. goals/mosa_workflow.md +463 -0
  313. goals/multi_agent_orchestration.md +68 -0
  314. goals/observability_traceability_xai.md +154 -0
  315. goals/owasp_agentic_security.md +395 -0
  316. goals/pr_intelligence.md +78 -0
  317. goals/requirements_intake.md +213 -0
  318. goals/secure_by_design.md +135 -0
  319. goals/security_scan.md +381 -0
  320. goals/self_healing.md +120 -0
  321. goals/simulation_engine.md +111 -0
  322. goals/subagent_review.md +205 -0
  323. goals/systematic_debugging.md +257 -0
  324. goals/tdd_workflow.md +403 -0
  325. goals/template_exchange.md +77 -0
  326. goals/thread_heatmap.md +77 -0
  327. goals/threat_modeler.md +77 -0
  328. goals/verification_iron_law.md +192 -0
  329. goals/vsm_dashboard.md +76 -0
  330. goals/writeguard.md +89 -0
  331. goals/zero_trust_architecture.md +403 -0
  332. hardprompts/__init__.py +6 -0
  333. hardprompts/agent/__init__.py +6 -0
  334. hardprompts/agent/agentic_architect.md +100 -0
  335. hardprompts/agent/debate_prompt.md +32 -0
  336. hardprompts/agent/fitness_evaluation.md +48 -0
  337. hardprompts/agent/governance_review.md +214 -0
  338. hardprompts/agent/reviewer_prompt.md +34 -0
  339. hardprompts/agent/skill_design.md +172 -0
  340. hardprompts/agent/task_decomposition.md +275 -0
  341. hardprompts/agent/veto_check_prompt.md +33 -0
  342. hardprompts/architect/__init__.py +6 -0
  343. hardprompts/architect/api_design.md +283 -0
  344. hardprompts/architect/data_model.md +277 -0
  345. hardprompts/architect/system_design.md +180 -0
  346. hardprompts/builder/__init__.py +6 -0
  347. hardprompts/builder/code_generation.md +59 -0
  348. hardprompts/builder/refactor.md +58 -0
  349. hardprompts/builder/scaffold_project.md +69 -0
  350. hardprompts/builder/test_generation.md +87 -0
  351. hardprompts/ci/__init__.py +6 -0
  352. hardprompts/ci/worktree_setup.md +35 -0
  353. hardprompts/compliance/__init__.py +6 -0
  354. hardprompts/compliance/cmmc_assessment.md +63 -0
  355. hardprompts/compliance/cssp_assessment.md +75 -0
  356. hardprompts/compliance/cui_marking.md +86 -0
  357. hardprompts/compliance/fedramp_assessment.md +55 -0
  358. hardprompts/compliance/ivv_assessment.md +96 -0
  359. hardprompts/compliance/poam_generation.md +57 -0
  360. hardprompts/compliance/sbd_assessment.md +101 -0
  361. hardprompts/compliance/security_categorization.md +74 -0
  362. hardprompts/compliance/ssp_generation.md +56 -0
  363. hardprompts/compliance/stig_evaluation.md +63 -0
  364. hardprompts/dashboard/__init__.py +6 -0
  365. hardprompts/dashboard/nlq_system_prompt.md +26 -0
  366. hardprompts/infra/__init__.py +6 -0
  367. hardprompts/infra/k8s_manifests.md +118 -0
  368. hardprompts/infra/pipeline_generation.md +160 -0
  369. hardprompts/infra/terraform_generation.md +92 -0
  370. hardprompts/integration/__init__.py +6 -0
  371. hardprompts/integration/approval_review.md +17 -0
  372. hardprompts/integration/jira_mapping.md +25 -0
  373. hardprompts/integration/servicenow_mapping.md +14 -0
  374. hardprompts/knowledge/__init__.py +6 -0
  375. hardprompts/knowledge/pattern_detection.md +73 -0
  376. hardprompts/knowledge/recommendation_engine.md +90 -0
  377. hardprompts/knowledge/root_cause_analysis.md +91 -0
  378. hardprompts/maintenance/__init__.py +6 -0
  379. hardprompts/maintenance/maintenance_assessment.md +82 -0
  380. hardprompts/mbse/__init__.py +6 -0
  381. hardprompts/mbse/digital_thread.md +67 -0
  382. hardprompts/mbse/model_import.md +62 -0
  383. hardprompts/mbse/model_to_code.md +65 -0
  384. hardprompts/modernization/__init__.py +6 -0
  385. hardprompts/modernization/legacy_analysis.md +93 -0
  386. hardprompts/modernization/migration_planning.md +150 -0
  387. hardprompts/modernization/seven_r_assessment.md +107 -0
  388. hardprompts/proposal_draft.md +53 -0
  389. hardprompts/rag_citation.md +12 -0
  390. hardprompts/rag_rerank.md +31 -0
  391. hardprompts/requirements/__init__.py +6 -0
  392. hardprompts/requirements/bdd_generation.md +35 -0
  393. hardprompts/requirements/clarification_prioritization.md +29 -0
  394. hardprompts/requirements/decomposition.md +60 -0
  395. hardprompts/requirements/document_extraction.md +45 -0
  396. hardprompts/requirements/gap_detection.md +70 -0
  397. hardprompts/requirements/intake_conversation.md +101 -0
  398. hardprompts/requirements/readiness_assessment.md +39 -0
  399. hardprompts/requirements/spec_quality.md +33 -0
  400. hardprompts/requirements/traceability_analysis.md +23 -0
  401. hardprompts/security/__init__.py +6 -0
  402. hardprompts/security/endpoint_security.md +78 -0
  403. hardprompts/security/threat_model.md +70 -0
  404. hardprompts/security/vulnerability_assessment.md +81 -0
  405. hardprompts/simulation/__init__.py +6 -0
  406. hardprompts/simulation/architecture_impact.md +27 -0
  407. hardprompts/simulation/coa_alternative.md +27 -0
  408. hardprompts/simulation/coa_generation.md +25 -0
  409. hardprompts/simulation/compliance_impact.md +28 -0
  410. hardprompts/simulation/cost_estimation.md +33 -0
  411. hardprompts/simulation/risk_assessment.md +28 -0
  412. hardprompts/translation/code_translation.md +68 -0
  413. hardprompts/translation/dependency_suggestion.md +44 -0
  414. hardprompts/translation/test_translation.md +64 -0
  415. hardprompts/translation/translation_repair.md +59 -0
  416. icdev-0.0.3.dist-info/METADATA +909 -0
  417. icdev-0.0.3.dist-info/RECORD +1214 -0
  418. icdev-0.0.3.dist-info/WHEEL +5 -0
  419. icdev-0.0.3.dist-info/entry_points.txt +9 -0
  420. icdev-0.0.3.dist-info/licenses/LICENSE +201 -0
  421. icdev-0.0.3.dist-info/licenses/NOTICE +11 -0
  422. icdev-0.0.3.dist-info/top_level.txt +7 -0
  423. memory/MEMORY.md +52 -0
  424. memory/logs/2026-02-14.md +17 -0
  425. memory/logs/2026-03-03.md +2 -0
  426. memory/logs/__init__.py +1 -0
  427. tools/a2a/icdev_callback_client.py +210 -0
  428. tools/agent/cards/architect_card.json +29 -0
  429. tools/agent/cards/builder_card.json +34 -0
  430. tools/agent/cards/compliance_card.json +29 -0
  431. tools/agent/cards/connector_forge_card.json +49 -0
  432. tools/agent/cards/devsecops_zta_card.json +24 -0
  433. tools/agent/cards/knowledge_card.json +29 -0
  434. tools/agent/cards/monitor_card.json +29 -0
  435. tools/agent/cards/orchestrator_card.json +29 -0
  436. tools/agent/cards/requirements_analyst_card.json +24 -0
  437. tools/agent/cards/security_card.json +29 -0
  438. tools/agent/cards/simulation_card.json +24 -0
  439. tools/agent/cards/supply_chain_card.json +24 -0
  440. tools/analysis/__init__.py +1 -0
  441. tools/analysis/code_analyzer.py +770 -0
  442. tools/analysis/runtime_feedback.py +379 -0
  443. tools/analytics/__init__.py +2 -0
  444. tools/analytics/scorecard.py +538 -0
  445. tools/analytics/vsm_engine.py +612 -0
  446. tools/architecture/__init__.py +2 -0
  447. tools/architecture/adr_extractor.py +393 -0
  448. tools/audit/__init__.py +1 -0
  449. tools/audit/audit_logger.py +199 -0
  450. tools/audit/audit_query.py +153 -0
  451. tools/audit/decision_recorder.py +73 -0
  452. tools/audit_engine/__init__.py +12 -0
  453. tools/audit_engine/ai_advisor.py +906 -0
  454. tools/audit_engine/cli.py +286 -0
  455. tools/audit_engine/comparator.py +305 -0
  456. tools/audit_engine/eject_scaffolder.py +399 -0
  457. tools/audit_engine/engine.py +614 -0
  458. tools/audit_engine/git_fetcher.py +341 -0
  459. tools/audit_engine/regime_loader.py +200 -0
  460. tools/audit_engine/regime_updater.py +325 -0
  461. tools/audit_engine/report_card.py +289 -0
  462. tools/audit_engine/scanner.py +684 -0
  463. tools/audit_engine/self_heal.py +1042 -0
  464. tools/ci/__init__.py +2 -0
  465. tools/ci/connectors/__init__.py +2 -0
  466. tools/ci/connectors/base_connector.py +80 -0
  467. tools/ci/connectors/connector_registry.py +188 -0
  468. tools/ci/connectors/mattermost_connector.py +159 -0
  469. tools/ci/connectors/slack_connector.py +197 -0
  470. tools/ci/core/__init__.py +2 -0
  471. tools/ci/core/air_gap_detector.py +115 -0
  472. tools/ci/core/comment_handler.py +192 -0
  473. tools/ci/core/conversation_manager.py +480 -0
  474. tools/ci/core/event_envelope.py +500 -0
  475. tools/ci/core/event_router.py +444 -0
  476. tools/ci/core/failure_parser.py +397 -0
  477. tools/ci/core/recovery_engine.py +527 -0
  478. tools/ci/gate_enforcer.py +361 -0
  479. tools/ci/modules/__init__.py +2 -0
  480. tools/ci/modules/agent.py +271 -0
  481. tools/ci/modules/git_ops.py +175 -0
  482. tools/ci/modules/state.py +117 -0
  483. tools/ci/modules/vcs.py +303 -0
  484. tools/ci/modules/workflow_ops.py +295 -0
  485. tools/ci/modules/worktree.py +337 -0
  486. tools/ci/pipeline_config_generator.py +558 -0
  487. tools/ci/pr_intelligence.py +485 -0
  488. tools/ci/triggers/__init__.py +2 -0
  489. tools/ci/triggers/gitlab_task_monitor.py +327 -0
  490. tools/ci/triggers/poll_trigger.py +237 -0
  491. tools/ci/triggers/webhook_server.py +356 -0
  492. tools/ci/workflows/__init__.py +2 -0
  493. tools/ci/workflows/icdev_build.py +140 -0
  494. tools/ci/workflows/icdev_comply.py +284 -0
  495. tools/ci/workflows/icdev_document.py +152 -0
  496. tools/ci/workflows/icdev_e2e.py +188 -0
  497. tools/ci/workflows/icdev_patch.py +186 -0
  498. tools/ci/workflows/icdev_plan.py +202 -0
  499. tools/ci/workflows/icdev_plan_build.py +41 -0
  500. tools/ci/workflows/icdev_plan_build_test.py +46 -0
  501. tools/ci/workflows/icdev_plan_build_test_review.py +47 -0
  502. tools/ci/workflows/icdev_review.py +126 -0
  503. tools/ci/workflows/icdev_sdlc.py +261 -0
  504. tools/ci/workflows/icdev_test.py +240 -0
  505. tools/cli/__init__.py +1 -0
  506. tools/cli/output_formatter.py +756 -0
  507. tools/cloudforge/__init__.py +12 -0
  508. tools/cloudforge/airgap/__init__.py +2 -0
  509. tools/cloudforge/airgap/il_classifier.py +70 -0
  510. tools/cloudforge/airgap/offline_validator.py +42 -0
  511. tools/cloudforge/airgap/shift_emulator.py +155 -0
  512. tools/cloudforge/airgap/sneakernet.py +91 -0
  513. tools/cloudforge/cd_hub/__init__.py +2 -0
  514. tools/cloudforge/cd_hub/canary_deployer.py +88 -0
  515. tools/cloudforge/cd_hub/gitops_renderer.py +123 -0
  516. tools/cloudforge/cd_hub/hub_controller.py +143 -0
  517. tools/cloudforge/cd_hub/pipeline_bridge.py +30 -0
  518. tools/cloudforge/cd_hub/rollback_engine.py +29 -0
  519. tools/cloudforge/cd_hub/spoke_agent.py +51 -0
  520. tools/cloudforge/compliance/__init__.py +2 -0
  521. tools/cloudforge/compliance/ato_accelerator.py +272 -0
  522. tools/cloudforge/compliance/control_inheritor.py +127 -0
  523. tools/cloudforge/compliance/evidence_generator.py +129 -0
  524. tools/cloudforge/compliance/poam_bridge.py +41 -0
  525. tools/cloudforge/compliance/ssp_bridge.py +52 -0
  526. tools/cloudforge/compliance/stig_bridge.py +41 -0
  527. tools/cloudforge/container_forge/__init__.py +2 -0
  528. tools/cloudforge/container_forge/bigbang_renderer.py +85 -0
  529. tools/cloudforge/container_forge/hardener.py +169 -0
  530. tools/cloudforge/container_forge/image_scanner_bridge.py +33 -0
  531. tools/cloudforge/container_forge/runtime_policy.py +87 -0
  532. tools/cloudforge/container_forge/sbom_bridge.py +42 -0
  533. tools/cloudforge/finops/__init__.py +2 -0
  534. tools/cloudforge/finops/anomaly_detector.py +78 -0
  535. tools/cloudforge/finops/budget_tracker.py +96 -0
  536. tools/cloudforge/finops/chargeback.py +69 -0
  537. tools/cloudforge/finops/cost_collector.py +141 -0
  538. tools/cloudforge/finops/optimizer.py +55 -0
  539. tools/cloudforge/hybrid/__init__.py +2 -0
  540. tools/cloudforge/hybrid/connection_manager.py +141 -0
  541. tools/cloudforge/hybrid/dns_federator.py +56 -0
  542. tools/cloudforge/hybrid/health_monitor.py +108 -0
  543. tools/cloudforge/hybrid/identity_federator.py +53 -0
  544. tools/cloudforge/hybrid/network_bridge.py +68 -0
  545. tools/cloudforge/hybrid/topology_manager.py +147 -0
  546. tools/cloudforge/hybrid/workload_abstractor.py +92 -0
  547. tools/cloudforge/iac/__init__.py +2 -0
  548. tools/cloudforge/iac/drift_detector.py +154 -0
  549. tools/cloudforge/iac/module_library.py +265 -0
  550. tools/cloudforge/iac/opentofu_adapter.py +89 -0
  551. tools/cloudforge/iac/pulumi_renderer.py +292 -0
  552. tools/cloudforge/iac/state_backend.py +146 -0
  553. tools/cloudforge/iac/terraform_renderer.py +626 -0
  554. tools/cloudforge/landing_zone/__init__.py +2 -0
  555. tools/cloudforge/landing_zone/blueprint_loader.py +98 -0
  556. tools/cloudforge/landing_zone/blueprint_validator.py +113 -0
  557. tools/cloudforge/landing_zone/zone_provisioner.py +306 -0
  558. tools/cloudforge/landing_zone/zone_state.py +143 -0
  559. tools/cloudforge/mbse_thread/__init__.py +2 -0
  560. tools/cloudforge/mbse_thread/ato_thread_weaver.py +111 -0
  561. tools/cloudforge/mbse_thread/control_tracer.py +68 -0
  562. tools/cloudforge/mbse_thread/system_boundary.py +83 -0
  563. tools/cloudforge/metastore/__init__.py +2 -0
  564. tools/cloudforge/metastore/dependency_graph.py +202 -0
  565. tools/cloudforge/metastore/discovery.py +192 -0
  566. tools/cloudforge/metastore/registry.py +185 -0
  567. tools/cloudforge/metastore/rto_tracker.py +92 -0
  568. tools/cloudforge/metastore/runbook_linker.py +82 -0
  569. tools/cloudforge/migration/__init__.py +2 -0
  570. tools/cloudforge/migration/assessor.py +187 -0
  571. tools/cloudforge/migration/cutover_orchestrator.py +117 -0
  572. tools/cloudforge/migration/databridge_bridge.py +92 -0
  573. tools/cloudforge/migration/planner.py +98 -0
  574. tools/cloudforge/migration/risk_scorer.py +97 -0
  575. tools/cloudforge/migration/validation_runner.py +45 -0
  576. tools/cloudforge/migration/workload_inventory.py +107 -0
  577. tools/cloudforge/provider.py +319 -0
  578. tools/cloudforge/providers/__init__.py +2 -0
  579. tools/cloudforge/providers/aws_commercial.py +92 -0
  580. tools/cloudforge/providers/aws_govcloud.py +229 -0
  581. tools/cloudforge/providers/aws_secret.py +83 -0
  582. tools/cloudforge/providers/azure_commercial.py +80 -0
  583. tools/cloudforge/providers/azure_gov.py +91 -0
  584. tools/cloudforge/providers/azure_secret.py +71 -0
  585. tools/cloudforge/providers/gcp.py +102 -0
  586. tools/cloudforge/providers/oci.py +102 -0
  587. tools/cloudforge/registry.py +140 -0
  588. tools/cloudforge/runbooks/__init__.py +2 -0
  589. tools/cloudforge/runbooks/ai_generator.py +119 -0
  590. tools/cloudforge/runbooks/dag_validator.py +219 -0
  591. tools/cloudforge/runbooks/engine.py +470 -0
  592. tools/cloudforge/runbooks/models.py +99 -0
  593. tools/cloudforge/runbooks/snippet_library.py +158 -0
  594. tools/cloudforge/runbooks/template_loader.py +122 -0
  595. tools/cloudforge/runbooks/visualization.py +108 -0
  596. tools/cloudforge/siem/__init__.py +2 -0
  597. tools/cloudforge/siem/alert_rules.py +86 -0
  598. tools/cloudforge/siem/correlation_engine.py +61 -0
  599. tools/cloudforge/siem/log_aggregator.py +113 -0
  600. tools/cloudforge/siem/siem_dashboard_data.py +28 -0
  601. tools/cloudforge/supply_chain/__init__.py +2 -0
  602. tools/cloudforge/supply_chain/bridge.py +33 -0
  603. tools/cloudforge/supply_chain/iac_dependency_scanner.py +36 -0
  604. tools/cloudforge/supply_chain/provider_trust_scorer.py +54 -0
  605. tools/compat/__init__.py +21 -0
  606. tools/compat/cli_harmonizer.py +251 -0
  607. tools/compat/datetime_utils.py +18 -0
  608. tools/compat/db_utils.py +190 -0
  609. tools/compat/platform_utils.py +123 -0
  610. tools/compliance/__init__.py +1 -0
  611. tools/compliance/accountability_manager.py +391 -0
  612. tools/compliance/ai_accountability_audit.py +287 -0
  613. tools/compliance/ai_impact_assessor.py +267 -0
  614. tools/compliance/ai_incident_response.py +295 -0
  615. tools/compliance/ai_inventory_manager.py +233 -0
  616. tools/compliance/ai_reassessment_scheduler.py +250 -0
  617. tools/compliance/ai_transparency_audit.py +247 -0
  618. tools/compliance/atlas_assessor.py +276 -0
  619. tools/compliance/atlas_report_generator.py +1199 -0
  620. tools/compliance/base_assessor.py +591 -0
  621. tools/compliance/cato_live_engine.py +607 -0
  622. tools/compliance/cato_monitor.py +1371 -0
  623. tools/compliance/cato_scheduler.py +698 -0
  624. tools/compliance/cjis_assessor.py +76 -0
  625. tools/compliance/classification_manager.py +1340 -0
  626. tools/compliance/cmmc_assessor.py +1478 -0
  627. tools/compliance/cmmc_report_generator.py +1087 -0
  628. tools/compliance/compliance_detector.py +452 -0
  629. tools/compliance/compliance_exporter.py +418 -0
  630. tools/compliance/compliance_status.py +810 -0
  631. tools/compliance/control_mapper.py +488 -0
  632. tools/compliance/crosswalk_engine.py +1208 -0
  633. tools/compliance/cssp_assessor.py +1032 -0
  634. tools/compliance/cssp_evidence_collector.py +716 -0
  635. tools/compliance/cssp_report_generator.py +1103 -0
  636. tools/compliance/cui_marker.py +387 -0
  637. tools/compliance/diagram_validator.py +599 -0
  638. tools/compliance/emass/__init__.py +2 -0
  639. tools/compliance/emass/emass_client.py +822 -0
  640. tools/compliance/emass/emass_export.py +758 -0
  641. tools/compliance/emass/emass_sync.py +807 -0
  642. tools/compliance/eu_ai_act_classifier.py +193 -0
  643. tools/compliance/evidence_collector.py +459 -0
  644. tools/compliance/fairness_assessor.py +310 -0
  645. tools/compliance/fedramp_20x_ksi_emitter.py +692 -0
  646. tools/compliance/fedramp_assessor.py +1795 -0
  647. tools/compliance/fedramp_authorization_packager.py +137 -0
  648. tools/compliance/fedramp_ksi_generator.py +349 -0
  649. tools/compliance/fedramp_report_generator.py +1115 -0
  650. tools/compliance/fips199_categorizer.py +869 -0
  651. tools/compliance/fips200_validator.py +304 -0
  652. tools/compliance/firmware_sbom.py +646 -0
  653. tools/compliance/gao_ai_assessor.py +228 -0
  654. tools/compliance/gao_evidence_builder.py +302 -0
  655. tools/compliance/hipaa_assessor.py +78 -0
  656. tools/compliance/hitrust_assessor.py +49 -0
  657. tools/compliance/incident_response_plan.py +705 -0
  658. tools/compliance/inheritance_engine.py +693 -0
  659. tools/compliance/iso27001_assessor.py +92 -0
  660. tools/compliance/iso42001_assessor.py +114 -0
  661. tools/compliance/ivv_assessor.py +2314 -0
  662. tools/compliance/ivv_report_generator.py +1649 -0
  663. tools/compliance/model_card_generator.py +291 -0
  664. tools/compliance/mosa_assessor.py +117 -0
  665. tools/compliance/multi_regime_assessor.py +441 -0
  666. tools/compliance/narrative_generator.py +1012 -0
  667. tools/compliance/narrative_quality_gate.py +701 -0
  668. tools/compliance/narrative_workflow.py +814 -0
  669. tools/compliance/nist_800_207_assessor.py +191 -0
  670. tools/compliance/nist_ai_600_1_assessor.py +185 -0
  671. tools/compliance/nist_ai_rmf_assessor.py +110 -0
  672. tools/compliance/nist_lookup.py +244 -0
  673. tools/compliance/omb_m25_21_assessor.py +225 -0
  674. tools/compliance/omb_m26_04_assessor.py +185 -0
  675. tools/compliance/oscal_catalog_adapter.py +395 -0
  676. tools/compliance/oscal_generator.py +2157 -0
  677. tools/compliance/oscal_tools.py +1182 -0
  678. tools/compliance/oscal_validator.py +692 -0
  679. tools/compliance/owasp_agentic_assessor.py +227 -0
  680. tools/compliance/owasp_asi_assessor.py +197 -0
  681. tools/compliance/owasp_llm_assessor.py +245 -0
  682. tools/compliance/pci_dss_assessor.py +80 -0
  683. tools/compliance/pi_compliance_tracker.py +1447 -0
  684. tools/compliance/poam_generator.py +388 -0
  685. tools/compliance/resolve_marking.py +272 -0
  686. tools/compliance/sbd_assessor.py +2070 -0
  687. tools/compliance/sbd_report_generator.py +1223 -0
  688. tools/compliance/sbom_generator.py +993 -0
  689. tools/compliance/siem_config_generator.py +661 -0
  690. tools/compliance/slsa_attestation_generator.py +479 -0
  691. tools/compliance/soc2_assessor.py +77 -0
  692. tools/compliance/ssp_generator.py +556 -0
  693. tools/compliance/stig_checker.py +712 -0
  694. tools/compliance/swft_evidence_bundler.py +326 -0
  695. tools/compliance/system_card_generator.py +303 -0
  696. tools/compliance/template_exchange.py +513 -0
  697. tools/compliance/traceability_matrix.py +1268 -0
  698. tools/compliance/universal_classification_manager.py +1159 -0
  699. tools/compliance/xacta/__init__.py +2 -0
  700. tools/compliance/xacta/xacta_client.py +438 -0
  701. tools/compliance/xacta/xacta_export.py +546 -0
  702. tools/compliance/xacta/xacta_sync.py +322 -0
  703. tools/compliance/xai_assessor.py +231 -0
  704. tools/core/__init__.py +2 -0
  705. tools/core/circuit_breaker.py +353 -0
  706. tools/core/compliance_sidecar.py +344 -0
  707. tools/core/container.py +110 -0
  708. tools/core/errors.py +256 -0
  709. tools/core/feature_flags.py +311 -0
  710. tools/core/task_dlq.py +350 -0
  711. tools/dashboard/__init__.py +2 -0
  712. tools/dashboard/app.py +6288 -0
  713. tools/dashboard/templates/agent_evolution.html +287 -0
  714. tools/dashboard/templates/agents/list.html +71 -0
  715. tools/dashboard/templates/agents.html +132 -0
  716. tools/dashboard/templates/architecture.html +289 -0
  717. tools/dashboard/templates/ato_simulator.html +170 -0
  718. tools/dashboard/templates/audit_engine.html +844 -0
  719. tools/dashboard/templates/base.html +236 -0
  720. tools/dashboard/templates/cato_live.html +116 -0
  721. tools/dashboard/templates/cloudforge.html +195 -0
  722. tools/dashboard/templates/cloudforge_finops.html +111 -0
  723. tools/dashboard/templates/cloudforge_hybrid.html +122 -0
  724. tools/dashboard/templates/cloudforge_metastore.html +234 -0
  725. tools/dashboard/templates/cloudforge_migration.html +87 -0
  726. tools/dashboard/templates/cloudforge_runbooks.html +201 -0
  727. tools/dashboard/templates/cloudforge_siem.html +94 -0
  728. tools/dashboard/templates/compliance_accel.html +292 -0
  729. tools/dashboard/templates/crashes.html +122 -0
  730. tools/dashboard/templates/databridge.html +305 -0
  731. tools/dashboard/templates/databridge_analytics.html +195 -0
  732. tools/dashboard/templates/databridge_mapping.html +345 -0
  733. tools/dashboard/templates/databridge_messaging.html +321 -0
  734. tools/dashboard/templates/decisions.html +258 -0
  735. tools/dashboard/templates/devices.html +151 -0
  736. tools/dashboard/templates/devsecops_maturity.html +278 -0
  737. tools/dashboard/templates/edge_ai.html +128 -0
  738. tools/dashboard/templates/firmware.html +120 -0
  739. tools/dashboard/templates/firmware_sbom.html +193 -0
  740. tools/dashboard/templates/forge_hub.html +196 -0
  741. tools/dashboard/templates/forge_studio.html +379 -0
  742. tools/dashboard/templates/forge_studio_analytics.html +360 -0
  743. tools/dashboard/templates/forge_studio_builder.html +1637 -0
  744. tools/dashboard/templates/forge_studio_compliance.html +310 -0
  745. tools/dashboard/templates/forge_studio_deploy.html +573 -0
  746. tools/dashboard/templates/forge_studio_enterprise.html +888 -0
  747. tools/dashboard/templates/forge_studio_marketplace.html +502 -0
  748. tools/dashboard/templates/forge_studio_workflow.html +696 -0
  749. tools/dashboard/templates/golden_path.html +175 -0
  750. tools/dashboard/templates/govcon.html +280 -0
  751. tools/dashboard/templates/harness.html +148 -0
  752. tools/dashboard/templates/index.html +207 -0
  753. tools/dashboard/templates/intelligence.html +336 -0
  754. tools/dashboard/templates/knowledge/index.html +190 -0
  755. tools/dashboard/templates/knowledge_graph.html +739 -0
  756. tools/dashboard/templates/login.html +51 -0
  757. tools/dashboard/templates/marketplace.html +336 -0
  758. tools/dashboard/templates/marketplace_admin.html +247 -0
  759. tools/dashboard/templates/missions.html +403 -0
  760. tools/dashboard/templates/narratives.html +154 -0
  761. tools/dashboard/templates/pr_intelligence.html +151 -0
  762. tools/dashboard/templates/proposals/detail.html +300 -0
  763. tools/dashboard/templates/proposals/list.html +52 -0
  764. tools/dashboard/templates/proposals/sam_detail.html +132 -0
  765. tools/dashboard/templates/proposals/section_detail.html +375 -0
  766. tools/dashboard/templates/research.html +222 -0
  767. tools/dashboard/templates/resilience.html +300 -0
  768. tools/dashboard/templates/scorecard.html +162 -0
  769. tools/dashboard/templates/simulator.html +131 -0
  770. tools/dashboard/templates/template_exchange.html +147 -0
  771. tools/dashboard/templates/thread_heatmap.html +151 -0
  772. tools/dashboard/templates/threat_model.html +195 -0
  773. tools/dashboard/templates/vsm.html +141 -0
  774. tools/dashboard/templates/writeguard.html +277 -0
  775. tools/databridge/__init__.py +5 -0
  776. tools/databridge/agent/__init__.py +2 -0
  777. tools/databridge/agent/daemon.py +227 -0
  778. tools/databridge/agent/tunnel.py +101 -0
  779. tools/databridge/agent/ws_relay.py +91 -0
  780. tools/databridge/analytics.py +167 -0
  781. tools/databridge/arrow_pipeline.py +327 -0
  782. tools/databridge/connection_manager.py +424 -0
  783. tools/databridge/connector.py +331 -0
  784. tools/databridge/connectors/__init__.py +2 -0
  785. tools/databridge/connectors/argocd_connector.py +160 -0
  786. tools/databridge/connectors/avro_connector.py +203 -0
  787. tools/databridge/connectors/azure_blob.py +63 -0
  788. tools/databridge/connectors/cdc_connector.py +205 -0
  789. tools/databridge/connectors/csv_connector.py +172 -0
  790. tools/databridge/connectors/datadog_connector.py +153 -0
  791. tools/databridge/connectors/discord_messaging.py +215 -0
  792. tools/databridge/connectors/dynamics365.py +151 -0
  793. tools/databridge/connectors/elasticsearch_connector.py +145 -0
  794. tools/databridge/connectors/email_base.py +114 -0
  795. tools/databridge/connectors/excel_connector.py +175 -0
  796. tools/databridge/connectors/fsspec_base.py +300 -0
  797. tools/databridge/connectors/gcs.py +53 -0
  798. tools/databridge/connectors/github_connector.py +138 -0
  799. tools/databridge/connectors/gitlab_connector.py +132 -0
  800. tools/databridge/connectors/gmail_connector.py +182 -0
  801. tools/databridge/connectors/hdfs.py +57 -0
  802. tools/databridge/connectors/health_base.py +401 -0
  803. tools/databridge/connectors/hubspot.py +124 -0
  804. tools/databridge/connectors/imap_connector.py +171 -0
  805. tools/databridge/connectors/jenkins_connector.py +138 -0
  806. tools/databridge/connectors/jira_connector.py +86 -0
  807. tools/databridge/connectors/json_connector.py +184 -0
  808. tools/databridge/connectors/kafka_connector.py +246 -0
  809. tools/databridge/connectors/kinesis_connector.py +238 -0
  810. tools/databridge/connectors/local_fs.py +30 -0
  811. tools/databridge/connectors/matrix.py +197 -0
  812. tools/databridge/connectors/mattermost_messaging.py +184 -0
  813. tools/databridge/connectors/messaging_base.py +172 -0
  814. tools/databridge/connectors/mssql.py +63 -0
  815. tools/databridge/connectors/mysql.py +57 -0
  816. tools/databridge/connectors/netsuite.py +170 -0
  817. tools/databridge/connectors/o365_mail.py +196 -0
  818. tools/databridge/connectors/oracle.py +65 -0
  819. tools/databridge/connectors/pagerduty_connector.py +162 -0
  820. tools/databridge/connectors/parquet_connector.py +131 -0
  821. tools/databridge/connectors/postgresql.py +58 -0
  822. tools/databridge/connectors/s3.py +65 -0
  823. tools/databridge/connectors/saas_base.py +198 -0
  824. tools/databridge/connectors/salesforce.py +126 -0
  825. tools/databridge/connectors/sap.py +89 -0
  826. tools/databridge/connectors/servicenow.py +60 -0
  827. tools/databridge/connectors/signal_messaging.py +150 -0
  828. tools/databridge/connectors/slack_messaging.py +203 -0
  829. tools/databridge/connectors/smtp_connector.py +126 -0
  830. tools/databridge/connectors/soap_base.py +258 -0
  831. tools/databridge/connectors/splunk_connector.py +171 -0
  832. tools/databridge/connectors/sql_base.py +310 -0
  833. tools/databridge/connectors/sqlite_connector.py +76 -0
  834. tools/databridge/connectors/teams.py +148 -0
  835. tools/databridge/connectors/telegram.py +192 -0
  836. tools/databridge/connectors/whatsapp.py +137 -0
  837. tools/databridge/data_profiler.py +99 -0
  838. tools/databridge/forge/__init__.py +6 -0
  839. tools/databridge/forge/base_selector.py +150 -0
  840. tools/databridge/forge/code_generator.py +206 -0
  841. tools/databridge/forge/community_hub.py +539 -0
  842. tools/databridge/forge/forge_agent.py +306 -0
  843. tools/databridge/forge/import_handler.py +133 -0
  844. tools/databridge/forge/integration_tester.py +127 -0
  845. tools/databridge/forge/marketplace_publisher.py +164 -0
  846. tools/databridge/forge/promoter.py +159 -0
  847. tools/databridge/forge/sandbox_manager.py +257 -0
  848. tools/databridge/forge/spec_parser.py +358 -0
  849. tools/databridge/forge/static_validator.py +363 -0
  850. tools/databridge/forge/templates/__init__.py +591 -0
  851. tools/databridge/format_converter.py +188 -0
  852. tools/databridge/mapping_engine.py +348 -0
  853. tools/databridge/messaging/__init__.py +5 -0
  854. tools/databridge/messaging/agent_bridge.py +254 -0
  855. tools/databridge/messaging/message_envelope.py +111 -0
  856. tools/databridge/messaging/message_logger.py +204 -0
  857. tools/databridge/messaging/messaging_daemon.py +326 -0
  858. tools/databridge/messaging/oauth2_manager.py +411 -0
  859. tools/databridge/pii_detector.py +221 -0
  860. tools/databridge/registry.py +352 -0
  861. tools/databridge/relay_server.py +105 -0
  862. tools/databridge/scale/__init__.py +16 -0
  863. tools/databridge/scale/backpressure.py +134 -0
  864. tools/databridge/scale/chunked_pipeline.py +169 -0
  865. tools/databridge/scale/connection_pool.py +293 -0
  866. tools/databridge/scale/engine.py +492 -0
  867. tools/databridge/scale/worker_pool.py +140 -0
  868. tools/databridge/scale/write_batcher.py +250 -0
  869. tools/databridge/schema_engine.py +324 -0
  870. tools/databridge/stream_manager.py +225 -0
  871. tools/databridge/sync_engine.py +411 -0
  872. tools/databridge/transforms.py +302 -0
  873. tools/db/__init__.py +1 -0
  874. tools/db/backup.py +312 -0
  875. tools/db/backup_manager.py +832 -0
  876. tools/db/init_icdev_db.py +7753 -0
  877. tools/db/init_sparkpilot_db.py +431 -0
  878. tools/db/migrate.py +177 -0
  879. tools/db/migrate_innovation_audit.py +165 -0
  880. tools/db/migration_runner.py +548 -0
  881. tools/db/migrations/001_baseline/meta.json +9 -0
  882. tools/db/migrations/001_baseline/up.py +67 -0
  883. tools/db/migrations/002_memory_enhancements/down.sql +8 -0
  884. tools/db/migrations/002_memory_enhancements/meta.json +9 -0
  885. tools/db/migrations/002_memory_enhancements/up.py +119 -0
  886. tools/db/migrations/003_dev_profiles/meta.json +8 -0
  887. tools/db/migrations/003_dev_profiles/up.py +93 -0
  888. tools/db/migrations/004_innovation_engine/down.py +19 -0
  889. tools/db/migrations/004_innovation_engine/up.py +227 -0
  890. tools/db/migrations/005_phase_37_ai_security/down.py +19 -0
  891. tools/db/migrations/005_phase_37_ai_security/up.py +257 -0
  892. tools/db/migrations/006_phase_36_evolution/down.py +21 -0
  893. tools/db/migrations/006_phase_36_evolution/up.py +323 -0
  894. tools/db/migrations/007_phase_38_cloud/down.py +14 -0
  895. tools/db/migrations/007_phase_38_cloud/up.py +110 -0
  896. tools/db/migrations/008_phase36_37_integration/up.py +55 -0
  897. tools/db/migrations/__init__.py +2 -0
  898. tools/db/pg_migrate.py +642 -0
  899. tools/db/storage.py +1080 -0
  900. tools/decisions/__init__.py +2 -0
  901. tools/decisions/dmn_engine.py +695 -0
  902. tools/devsecops/__init__.py +2 -0
  903. tools/devsecops/attestation_manager.py +449 -0
  904. tools/devsecops/network_segmentation_generator.py +604 -0
  905. tools/devsecops/pdp_config_generator.py +1246 -0
  906. tools/devsecops/pipeline_security_generator.py +475 -0
  907. tools/devsecops/policy_generator.py +644 -0
  908. tools/devsecops/profile_manager.py +374 -0
  909. tools/devsecops/service_mesh_generator.py +1063 -0
  910. tools/devsecops/zta_maturity_scorer.py +355 -0
  911. tools/devsecops/zta_terraform_generator.py +1301 -0
  912. tools/edge_ai/__init__.py +2 -0
  913. tools/edge_ai/model_manager.py +200 -0
  914. tools/embedded/__init__.py +2 -0
  915. tools/embedded/cmake_generator.py +318 -0
  916. tools/embedded/crash_analyzer.py +191 -0
  917. tools/embedded/nl_to_firmware.py +277 -0
  918. tools/events/__init__.py +1 -0
  919. tools/events/event_bus.py +199 -0
  920. tools/finetune/pair_generator.py +832 -0
  921. tools/fleet/__init__.py +2 -0
  922. tools/fleet/device_registry.py +148 -0
  923. tools/fleet/ota_manager.py +153 -0
  924. tools/forge_studio/__init__.py +13 -0
  925. tools/forge_studio/analytics/__init__.py +0 -0
  926. tools/forge_studio/analytics/process_miner.py +383 -0
  927. tools/forge_studio/audit.py +183 -0
  928. tools/forge_studio/blueprint/__init__.py +2 -0
  929. tools/forge_studio/blueprint/build_tracker.py +317 -0
  930. tools/forge_studio/blueprint/export_engine.py +441 -0
  931. tools/forge_studio/blueprint/parent_client.py +335 -0
  932. tools/forge_studio/catalog/__init__.py +2 -0
  933. tools/forge_studio/catalog/component_registry.py +176 -0
  934. tools/forge_studio/catalog/schema_validator.py +193 -0
  935. tools/forge_studio/compliance/__init__.py +1 -0
  936. tools/forge_studio/compliance/compliance_wiring.py +554 -0
  937. tools/forge_studio/deploy/__init__.py +1 -0
  938. tools/forge_studio/deploy/airgap_packager.py +466 -0
  939. tools/forge_studio/deploy/deploy_engine.py +1792 -0
  940. tools/forge_studio/deploy/env_manager.py +431 -0
  941. tools/forge_studio/eject/__init__.py +2 -0
  942. tools/forge_studio/eject/docker_compose_generator.py +237 -0
  943. tools/forge_studio/eject/eject_engine.py +230 -0
  944. tools/forge_studio/eject/expo_scaffolder.py +303 -0
  945. tools/forge_studio/eject/nextjs_scaffolder.py +338 -0
  946. tools/forge_studio/enterprise/__init__.py +0 -0
  947. tools/forge_studio/enterprise/custom_frameworks.py +826 -0
  948. tools/forge_studio/enterprise/hardening_engine.py +1530 -0
  949. tools/forge_studio/enterprise/sso_manager.py +718 -0
  950. tools/forge_studio/enterprise/whitelabel_engine.py +887 -0
  951. tools/forge_studio/formula/__init__.py +0 -0
  952. tools/forge_studio/formula/expression_engine.py +562 -0
  953. tools/forge_studio/formula/formula_registry.py +265 -0
  954. tools/forge_studio/generator/__init__.py +2 -0
  955. tools/forge_studio/generator/app_generator.py +584 -0
  956. tools/forge_studio/generator/complexity_detector.py +368 -0
  957. tools/forge_studio/generator/prompt_templates.py +104 -0
  958. tools/forge_studio/generator/spec_builder.py +192 -0
  959. tools/forge_studio/intake_bridge.py +898 -0
  960. tools/forge_studio/marketplace/__init__.py +0 -0
  961. tools/forge_studio/marketplace/component_hub.py +428 -0
  962. tools/forge_studio/models.py +369 -0
  963. tools/forge_studio/renderer/__init__.py +2 -0
  964. tools/forge_studio/renderer/json_render_engine.py +623 -0
  965. tools/forge_studio/renderer/layout_engine.py +214 -0
  966. tools/forge_studio/renderer/rn_component_map.py +182 -0
  967. tools/forge_studio/supabase/__init__.py +2 -0
  968. tools/forge_studio/supabase/auth_generator.py +283 -0
  969. tools/forge_studio/supabase/migration_generator.py +93 -0
  970. tools/forge_studio/supabase/schema_generator.py +281 -0
  971. tools/forge_studio/tenant_manager.py +387 -0
  972. tools/forge_studio/workflow/__init__.py +2 -0
  973. tools/forge_studio/workflow/bpmn_adapter.py +489 -0
  974. tools/govcon/draft_orchestrator.py +1151 -0
  975. tools/govcon/engine_enrichment.py +373 -0
  976. tools/govcon/knowledge_base.py +487 -0
  977. tools/govcon/knowledge_ingestion.py +510 -0
  978. tools/govcon/sam_scanner.py +754 -0
  979. tools/harness/__init__.py +6 -0
  980. tools/harness/exit_criteria_evaluator.py +231 -0
  981. tools/harness/maturity_assessor.py +347 -0
  982. tools/harness/scaffold_harness.py +416 -0
  983. tools/harness/trace_analyzer.py +281 -0
  984. tools/infra/__init__.py +1 -0
  985. tools/infra/ansible_generator.py +867 -0
  986. tools/infra/dockerfile_generator.py +359 -0
  987. tools/infra/infra_status.py +384 -0
  988. tools/infra/ironbank_metadata_generator.py +403 -0
  989. tools/infra/k8s_generator.py +1000 -0
  990. tools/infra/pipeline_generator.py +830 -0
  991. tools/infra/rollback.py +389 -0
  992. tools/infra/terraform_generator.py +1140 -0
  993. tools/infra/terraform_generator_azure.py +1252 -0
  994. tools/infra/terraform_generator_gcp.py +951 -0
  995. tools/infra/terraform_generator_ibm.py +359 -0
  996. tools/infra/terraform_generator_oci.py +918 -0
  997. tools/infra/terraform_generator_onprem.py +318 -0
  998. tools/knowledge/__init__.py +1 -0
  999. tools/knowledge/knowledge_ingest.py +281 -0
  1000. tools/knowledge/pattern_detector.py +681 -0
  1001. tools/knowledge/recommendation_engine.py +449 -0
  1002. tools/knowledge/self_heal_analyzer.py +492 -0
  1003. tools/knowledge_graph/__init__.py +2 -0
  1004. tools/knowledge_graph/graph_rag.py +498 -0
  1005. tools/knowledge_graph/ingester.py +406 -0
  1006. tools/knowledge_graph/insight_generator.py +369 -0
  1007. tools/knowledge_graph/text_network.py +832 -0
  1008. tools/llm/__init__.py +72 -0
  1009. tools/llm/anthropic_provider.py +170 -0
  1010. tools/llm/azure_openai_provider.py +338 -0
  1011. tools/llm/bedrock_provider.py +315 -0
  1012. tools/llm/embedding_provider.py +438 -0
  1013. tools/llm/gemini_provider.py +381 -0
  1014. tools/llm/ibm_watsonx_provider.py +231 -0
  1015. tools/llm/oci_genai_provider.py +462 -0
  1016. tools/llm/ollama_provider.py +350 -0
  1017. tools/llm/openai_provider.py +225 -0
  1018. tools/llm/prompt_registry.py +447 -0
  1019. tools/llm/provider.py +355 -0
  1020. tools/llm/provider_sdk.py +175 -0
  1021. tools/llm/router.py +1124 -0
  1022. tools/llm/semantic_cache.py +394 -0
  1023. tools/llm/vertex_ai_provider.py +374 -0
  1024. tools/maintenance/__init__.py +2 -0
  1025. tools/maintenance/dependency_scanner.py +1016 -0
  1026. tools/maintenance/maintenance_auditor.py +804 -0
  1027. tools/maintenance/remediation_engine.py +957 -0
  1028. tools/maintenance/vulnerability_checker.py +978 -0
  1029. tools/manifest.md +1066 -0
  1030. tools/marketplace/asset_installer.py +639 -0
  1031. tools/marketplace/feedback_validator.py +359 -0
  1032. tools/marketplace/license_client.py +458 -0
  1033. tools/marketplace/module_crypto.py +544 -0
  1034. tools/marketplace/module_runtime.py +236 -0
  1035. tools/marketplace/token_store.py +264 -0
  1036. tools/mbse/__init__.py +3 -0
  1037. tools/mbse/des_assessor.py +1173 -0
  1038. tools/mbse/des_report_generator.py +787 -0
  1039. tools/mbse/diagram_extractor.py +792 -0
  1040. tools/mbse/digital_thread.py +1650 -0
  1041. tools/mbse/model_code_generator.py +1115 -0
  1042. tools/mbse/model_control_mapper.py +410 -0
  1043. tools/mbse/pi_model_tracker.py +1079 -0
  1044. tools/mbse/reqif_parser.py +1468 -0
  1045. tools/mbse/sync_engine.py +1789 -0
  1046. tools/mbse/thread_heatmap.py +445 -0
  1047. tools/mbse/xmi_parser.py +1558 -0
  1048. tools/mcp/builder_server.py +64 -0
  1049. tools/mcp/compliance_server.py +64 -0
  1050. tools/mcp/connector_forge_server.py +155 -0
  1051. tools/mcp/core_server.py +64 -0
  1052. tools/mcp/devsecops_server.py +11 -0
  1053. tools/mcp/devsecops_zta_server.py +64 -0
  1054. tools/mcp/knowledge_server.py +64 -0
  1055. tools/mcp/monitor_server.py +64 -0
  1056. tools/mcp/ops_server.py +300 -0
  1057. tools/mcp/requirements_analyst_server.py +64 -0
  1058. tools/mcp/requirements_server.py +11 -0
  1059. tools/mcp/security_server.py +64 -0
  1060. tools/mcp/simulation_server.py +64 -0
  1061. tools/mcp/supply_chain_server.py +64 -0
  1062. tools/mcp/tool_registry.py +299 -0
  1063. tools/memory/__init__.py +2 -0
  1064. tools/memory/auto_capture.py +346 -0
  1065. tools/memory/embed_memory.py +157 -0
  1066. tools/memory/history_compressor.py +334 -0
  1067. tools/memory/hybrid_search.py +235 -0
  1068. tools/memory/maintenance_cron.py +288 -0
  1069. tools/memory/memory_consolidation.py +439 -0
  1070. tools/memory/memory_db.py +132 -0
  1071. tools/memory/memory_read.py +101 -0
  1072. tools/memory/memory_write.py +221 -0
  1073. tools/memory/semantic_search.py +138 -0
  1074. tools/memory/time_decay.py +434 -0
  1075. tools/missions/__init__.py +2 -0
  1076. tools/missions/mission_engine.py +459 -0
  1077. tools/monitor/__init__.py +1 -0
  1078. tools/monitor/alert_correlator.py +486 -0
  1079. tools/monitor/auto_resolver.py +603 -0
  1080. tools/monitor/health_checker.py +507 -0
  1081. tools/monitor/heartbeat_daemon.py +779 -0
  1082. tools/monitor/log_analyzer.py +507 -0
  1083. tools/monitor/metric_collector.py +484 -0
  1084. tools/mosa/__init__.py +10 -0
  1085. tools/mosa/icd_generator.py +358 -0
  1086. tools/mosa/modular_design_analyzer.py +682 -0
  1087. tools/mosa/mosa_code_enforcer.py +348 -0
  1088. tools/mosa/tsp_generator.py +265 -0
  1089. tools/observability/__init__.py +100 -0
  1090. tools/observability/genai_attributes.py +88 -0
  1091. tools/observability/instrumentation.py +140 -0
  1092. tools/observability/mlflow_exporter.py +193 -0
  1093. tools/observability/otel_tracer.py +168 -0
  1094. tools/observability/provenance/__init__.py +3 -0
  1095. tools/observability/provenance/prov_recorder.py +322 -0
  1096. tools/observability/shap/__init__.py +3 -0
  1097. tools/observability/shap/agent_shap.py +274 -0
  1098. tools/observability/sqlite_tracer.py +360 -0
  1099. tools/observability/trace_context.py +205 -0
  1100. tools/observability/tracer.py +230 -0
  1101. tools/orchestration/__init__.py +1 -0
  1102. tools/orchestration/peer_channels.py +254 -0
  1103. tools/orchestration/saga_coordinator.py +390 -0
  1104. tools/project/__init__.py +1 -0
  1105. tools/project/manifest_loader.py +418 -0
  1106. tools/project/project_create.py +350 -0
  1107. tools/project/project_list.py +171 -0
  1108. tools/project/project_scaffold.py +1715 -0
  1109. tools/project/project_status.py +478 -0
  1110. tools/project/session_context_builder.py +752 -0
  1111. tools/project/validate_manifest.py +54 -0
  1112. tools/rag/corrective_rag.py +582 -0
  1113. tools/rag/source_registry.py +482 -0
  1114. tools/requirements/__init__.py +1 -0
  1115. tools/requirements/ai_governance_scorer.py +207 -0
  1116. tools/requirements/boundary_analyzer.py +1281 -0
  1117. tools/requirements/clarification_engine.py +605 -0
  1118. tools/requirements/complexity_scorer.py +369 -0
  1119. tools/requirements/consistency_analyzer.py +789 -0
  1120. tools/requirements/constitution_manager.py +592 -0
  1121. tools/requirements/decomposition_engine.py +764 -0
  1122. tools/requirements/document_extractor.py +1002 -0
  1123. tools/requirements/elicitation_techniques.py +508 -0
  1124. tools/requirements/gap_detector.py +260 -0
  1125. tools/requirements/intake_engine.py +2175 -0
  1126. tools/requirements/prd_generator.py +839 -0
  1127. tools/requirements/prd_validator.py +584 -0
  1128. tools/requirements/readiness_scorer.py +302 -0
  1129. tools/requirements/spec_organizer.py +1015 -0
  1130. tools/requirements/spec_quality_checker.py +1083 -0
  1131. tools/requirements/traceability_builder.py +566 -0
  1132. tools/research/__init__.py +3 -0
  1133. tools/research/academic_scanner.py +130 -0
  1134. tools/research/build_buy_analyzer.py +229 -0
  1135. tools/research/challenge_scorer.py +280 -0
  1136. tools/research/community_scanner.py +174 -0
  1137. tools/research/cross_engine_bridge.py +124 -0
  1138. tools/research/dossier_generator.py +305 -0
  1139. tools/research/landscape_scanner.py +315 -0
  1140. tools/research/regulatory_scanner.py +248 -0
  1141. tools/research/research_manager.py +469 -0
  1142. tools/research/source_scanner.py +150 -0
  1143. tools/research/vertical_loader.py +118 -0
  1144. tools/saas/__init__.py +0 -0
  1145. tools/saas/licensing/__init__.py +0 -0
  1146. tools/saas/licensing/license_validator.py +345 -0
  1147. tools/scaffold/__init__.py +2 -0
  1148. tools/scaffold/golden_path.py +504 -0
  1149. tools/security/__init__.py +1 -0
  1150. tools/security/agent_output_validator.py +330 -0
  1151. tools/security/agent_trust_scorer.py +652 -0
  1152. tools/security/ai_bom_generator.py +718 -0
  1153. tools/security/ai_telemetry_logger.py +469 -0
  1154. tools/security/atlas_red_team.py +541 -0
  1155. tools/security/code_pattern_scanner.py +382 -0
  1156. tools/security/confabulation_detector.py +265 -0
  1157. tools/security/container_scanner.py +489 -0
  1158. tools/security/dependency_auditor.py +942 -0
  1159. tools/security/endpoint_security_scanner.py +626 -0
  1160. tools/security/mcp_tool_authorizer.py +242 -0
  1161. tools/security/output_verifier.py +427 -0
  1162. tools/security/prompt_injection_detector.py +737 -0
  1163. tools/security/sast_runner.py +946 -0
  1164. tools/security/secret_detector.py +376 -0
  1165. tools/security/threat_modeler.py +678 -0
  1166. tools/security/tool_chain_validator.py +357 -0
  1167. tools/security/vuln_scanner.py +536 -0
  1168. tools/simulation/__init__.py +2 -0
  1169. tools/simulation/ato_simulator.py +517 -0
  1170. tools/simulation/coa_generator.py +1539 -0
  1171. tools/simulation/monte_carlo.py +745 -0
  1172. tools/simulation/scenario_manager.py +1060 -0
  1173. tools/simulation/simulation_engine.py +1091 -0
  1174. tools/simulator/__init__.py +2 -0
  1175. tools/simulator/sim_runner.py +272 -0
  1176. tools/supply_chain/__init__.py +2 -0
  1177. tools/supply_chain/cve_triager.py +690 -0
  1178. tools/supply_chain/dependency_graph.py +630 -0
  1179. tools/supply_chain/isa_manager.py +526 -0
  1180. tools/supply_chain/scrm_assessor.py +531 -0
  1181. tools/supply_chain/slsa_verifier.py +473 -0
  1182. tools/testing/__init__.py +2 -0
  1183. tools/testing/acceptance_validator.py +411 -0
  1184. tools/testing/api_surface_extractor.py +749 -0
  1185. tools/testing/claude_dir_validator.py +831 -0
  1186. tools/testing/data_types.py +199 -0
  1187. tools/testing/e2e_runner.py +715 -0
  1188. tools/testing/fuzz_cli.py +306 -0
  1189. tools/testing/health_check.py +483 -0
  1190. tools/testing/platform_check.py +143 -0
  1191. tools/testing/production_audit.py +1836 -0
  1192. tools/testing/production_remediate.py +803 -0
  1193. tools/testing/screenshot_validator.py +538 -0
  1194. tools/testing/smoke_test.py +283 -0
  1195. tools/testing/test_agent_models.py +117 -0
  1196. tools/testing/test_orchestrator.py +957 -0
  1197. tools/testing/utils.py +229 -0
  1198. tools/writeguard/__init__.py +1 -0
  1199. tools/writeguard/main.py +1 -0
  1200. tools/writing/__init__.py +7 -0
  1201. tools/writing/ai_content_detector.py +316 -0
  1202. tools/writing/analysis_engine.py +454 -0
  1203. tools/writing/batch_analyzer.py +276 -0
  1204. tools/writing/coherence_analyzer.py +221 -0
  1205. tools/writing/govcon_bridge.py +509 -0
  1206. tools/writing/grammar_checker.py +270 -0
  1207. tools/writing/plagiarism_detector.py +106 -0
  1208. tools/writing/readability_scorer.py +201 -0
  1209. tools/writing/rewriter.py +96 -0
  1210. tools/writing/signal_registrar.py +167 -0
  1211. tools/writing/snippet_manager.py +276 -0
  1212. tools/writing/style_enforcer.py +220 -0
  1213. tools/writing/style_guide_manager.py +438 -0
  1214. tools/writing/tone_profiler.py +168 -0
@@ -0,0 +1,1223 @@
1
+ #!/usr/bin/env python3
2
+ # CUI // SP-CTI
3
+ """Secure by Design (SbD) report generator.
4
+
5
+ Loads sbd_report_template.md, queries sbd_assessments table, builds domain scores
6
+ and CISA commitment status, generates a comprehensive SbD assessment report with
7
+ CUI markings."""
8
+
9
+ import argparse
10
+ import json
11
+ import re
12
+ import sys
13
+ from datetime import datetime, timedelta, timezone
14
+ from pathlib import Path
15
+ from tools.db.storage import get_connection
16
+ DB_PATH = None # Storage layer handles path resolution (D-DB-20)
17
+
18
+ BASE_DIR = Path(__file__).resolve().parent.parent.parent
19
+ SBD_TEMPLATE_PATH = BASE_DIR / "context" / "compliance" / "sbd_report_template.md"
20
+ SBD_REQUIREMENTS_PATH = BASE_DIR / "context" / "compliance" / "cisa_sbd_requirements.json"
21
+
22
+ # SbD domains as defined in the CISA requirements catalog
23
+ SBD_DOMAINS = [
24
+ "Authentication",
25
+ "Memory Safety",
26
+ "Vulnerability Management",
27
+ "Intrusion Evidence",
28
+ "Cryptography",
29
+ "Access Control",
30
+ "Input Handling",
31
+ "Error Handling",
32
+ "Supply Chain",
33
+ "Threat Modeling",
34
+ "Defense in Depth",
35
+ "Secure Defaults",
36
+ "CUI Compliance",
37
+ "DoD Software Assurance",
38
+ ]
39
+
40
+ # CISA Secure by Design commitments (7 pledges)
41
+ CISA_COMMITMENTS = {
42
+ 1: "Multi-Factor Authentication",
43
+ 2: "Default Password Elimination",
44
+ 3: "Vulnerability Class Reduction",
45
+ 4: "Security Patch Deployment",
46
+ 5: "Vulnerability Disclosure Policy",
47
+ 6: "CVE Transparency",
48
+ 7: "Intrusion Evidence Collection",
49
+ }
50
+
51
+ # Priority ordering for remediation
52
+ PRIORITY_ORDER = ["critical", "high", "medium", "low"]
53
+
54
+
55
+ # ---------------------------------------------------------------------------
56
+ # Helper functions
57
+ # ---------------------------------------------------------------------------
58
+
59
+
60
+ def _load_template(template_path=None):
61
+ """Load the SbD report template markdown.
62
+
63
+ If the template file does not exist a minimal built-in template is
64
+ returned so the generator can still produce a useful report.
65
+ """
66
+ path = template_path or SBD_TEMPLATE_PATH
67
+ if path.exists():
68
+ with open(path, "r", encoding="utf-8") as f:
69
+ return f.read()
70
+
71
+ # Fallback minimal template when file is missing
72
+ return _builtin_template()
73
+
74
+
75
+ def _builtin_template():
76
+ """Return a minimal built-in SbD report template."""
77
+ return (
78
+ "{{cui_banner_top}}\n\n"
79
+ "# Secure by Design Assessment Report\n\n"
80
+ "**Project:** {{project_name}}\n"
81
+ "**Project ID:** {{project_id}}\n"
82
+ "**Classification:** {{classification}}\n"
83
+ "**Assessment Date:** {{assessment_date}}\n"
84
+ "**Report Version:** {{version}}\n"
85
+ "**Assessor:** {{assessor}}\n"
86
+ "**Framework:** CISA Secure by Design + DoDI 5000.87 + NIST SP 800-218 SSDF\n\n"
87
+ "---\n\n"
88
+ "## 1. Executive Summary\n\n"
89
+ "**Overall SbD Score:** {{overall_score}}%\n"
90
+ "**Gate Result:** {{gate_result}}\n"
91
+ "**Domains Assessed:** {{domains_assessed}} / 14\n"
92
+ "**Critical Requirements Not Satisfied:** {{critical_not_satisfied}}\n\n"
93
+ "{{executive_summary}}\n\n"
94
+ "## 2. CISA Secure by Design Commitment Status\n\n"
95
+ "The following table shows compliance with the 7 CISA Secure by Design commitments:\n\n"
96
+ "{{cisa_commitment_table}}\n\n"
97
+ "## 3. Domain Assessment Summary\n\n"
98
+ "{{domain_scores_table}}\n\n"
99
+ "## 4. Detailed Domain Assessments\n\n"
100
+ "{{domain_details}}\n\n"
101
+ "## 5. Auto-Check Results\n\n"
102
+ "{{auto_check_results}}\n\n"
103
+ "## 6. Manual Review Items\n\n"
104
+ "The following requirements require manual verification:\n\n"
105
+ "{{manual_review_items}}\n\n"
106
+ "## 7. Findings and Remediation\n\n"
107
+ "### Critical Findings\n"
108
+ "{{critical_findings}}\n\n"
109
+ "### Remediation Recommendations\n"
110
+ "{{remediation_table}}\n\n"
111
+ "## 8. Evidence Artifacts\n\n"
112
+ "{{evidence_summary}}\n\n"
113
+ "## 9. NIST 800-53 Control Mapping\n\n"
114
+ "{{nist_control_mapping}}\n\n"
115
+ "## 10. Assessment Methodology\n\n"
116
+ "This assessment was conducted using the ICDEV SbD Assessor tool against the "
117
+ "CISA Secure by Design requirements catalog (35 requirements across 14 domains). "
118
+ "Automated checks were performed where possible; requirements marked as \"semi\" "
119
+ "or \"manual\" are flagged for human review.\n\n"
120
+ "**Scoring Formula:** Score = 100 x (satisfied + partially_satisfied x 0.5 + "
121
+ "risk_accepted x 0.75) / assessable_count\n\n"
122
+ "**Gate Logic:** PASS if 0 critical-priority requirements have status "
123
+ "\"not_satisfied\"\n\n"
124
+ "---\n\n"
125
+ "**Prepared by:** {{assessor}}\n"
126
+ "**Date:** {{assessment_date}}\n\n"
127
+ "{{cui_banner_bottom}}\n"
128
+ )
129
+
130
+
131
+ def _get_project_data(conn, project_id):
132
+ """Load project record from database."""
133
+ row = conn.execute(
134
+ "SELECT * FROM projects WHERE id = ?", (project_id,)
135
+ ).fetchone()
136
+ if not row:
137
+ raise ValueError(f"Project '{project_id}' not found in database.")
138
+ return dict(row)
139
+
140
+
141
+ def _load_cui_config():
142
+ """Load CUI marking configuration.
143
+
144
+ Attempts to import load_cui_config from the cui_marker module;
145
+ falls back to sensible defaults if unavailable.
146
+ """
147
+ try:
148
+ from tools.compliance.cui_marker import load_cui_config as _load
149
+ return _load()
150
+ except Exception:
151
+ pass
152
+
153
+ # Try relative import
154
+ try:
155
+ cui_marker_path = Path(__file__).resolve().parent / "cui_marker.py"
156
+ if cui_marker_path.exists():
157
+ import importlib.util
158
+ spec = importlib.util.spec_from_file_location("cui_marker", cui_marker_path)
159
+ mod = importlib.util.module_from_spec(spec)
160
+ spec.loader.exec_module(mod)
161
+ return mod.load_cui_config()
162
+ except Exception:
163
+ pass
164
+
165
+ return {
166
+ "banner_top": "CUI // SP-CTI",
167
+ "banner_bottom": "CUI // SP-CTI",
168
+ "document_header": (
169
+ "////////////////////////////////////////////////////////////////////\n"
170
+ "CONTROLLED UNCLASSIFIED INFORMATION (CUI) // SP-CTI\n"
171
+ "Distribution: Distribution D -- Authorized DoD Personnel Only\n"
172
+ "////////////////////////////////////////////////////////////////////"
173
+ ),
174
+ "document_footer": (
175
+ "////////////////////////////////////////////////////////////////////\n"
176
+ "CUI // SP-CTI | Department of Defense\n"
177
+ "////////////////////////////////////////////////////////////////////"
178
+ ),
179
+ }
180
+
181
+
182
+ def _load_sbd_requirements():
183
+ """Load the CISA SbD requirements catalog for reference data.
184
+
185
+ Returns a dict keyed by requirement ID with full requirement metadata
186
+ including domain, cisa_commitment, priority, nist_controls, etc.
187
+ Falls back to an empty dict if the file is unavailable.
188
+ """
189
+ path = SBD_REQUIREMENTS_PATH
190
+ if not path.exists():
191
+ return {}
192
+
193
+ try:
194
+ with open(path, "r", encoding="utf-8") as f:
195
+ data = json.load(f)
196
+ requirements = {}
197
+ for req in data.get("requirements", []):
198
+ requirements[req["id"]] = req
199
+ return requirements
200
+ except (json.JSONDecodeError, KeyError, TypeError) as e:
201
+ print(f"Warning: Could not load SbD requirements catalog: {e}", file=sys.stderr)
202
+ return {}
203
+
204
+
205
+ # ---------------------------------------------------------------------------
206
+ # Data retrieval
207
+ # ---------------------------------------------------------------------------
208
+
209
+ def _get_sbd_assessments(conn, project_id):
210
+ """Retrieve all SbD assessment results for a project."""
211
+ rows = conn.execute(
212
+ """SELECT * FROM sbd_assessments
213
+ WHERE project_id = ?
214
+ ORDER BY domain, requirement_id""",
215
+ (project_id,),
216
+ ).fetchall()
217
+ return [dict(r) for r in rows]
218
+
219
+
220
+ def _get_stig_findings(conn, project_id):
221
+ """Retrieve STIG finding counts grouped by severity and status for cross-reference."""
222
+ rows = conn.execute(
223
+ """SELECT severity, status, COUNT(*) as cnt
224
+ FROM stig_findings WHERE project_id = ?
225
+ GROUP BY severity, status""",
226
+ (project_id,),
227
+ ).fetchall()
228
+ return [dict(r) for r in rows]
229
+
230
+
231
+ def _get_sbom_records(conn, project_id):
232
+ """Retrieve SBOM records for supply chain status cross-reference."""
233
+ rows = conn.execute(
234
+ """SELECT * FROM sbom_records
235
+ WHERE project_id = ?
236
+ ORDER BY generated_at DESC""",
237
+ (project_id,),
238
+ ).fetchall()
239
+ return [dict(r) for r in rows]
240
+
241
+
242
+ # ---------------------------------------------------------------------------
243
+ # Score calculation
244
+ # ---------------------------------------------------------------------------
245
+
246
+ def _calculate_domain_scores(assessments):
247
+ """Calculate a compliance score for each SbD domain.
248
+
249
+ Score formula:
250
+ score = 100 * (satisfied + partially_satisfied*0.5 + risk_accepted*0.75)
251
+ / total (excluding not_applicable)
252
+
253
+ Returns:
254
+ dict mapping domain name to a dict with score, total, and
255
+ per-status counts.
256
+ """
257
+ area_data = {domain: [] for domain in SBD_DOMAINS}
258
+ for a in assessments:
259
+ dom = a.get("domain")
260
+ if dom in area_data:
261
+ area_data[dom].append(a)
262
+
263
+ results = {}
264
+ for domain in SBD_DOMAINS:
265
+ items = area_data[domain]
266
+ total = len(items)
267
+ if total == 0:
268
+ results[domain] = {
269
+ "score": 0.0,
270
+ "total": 0,
271
+ "satisfied": 0,
272
+ "partially_satisfied": 0,
273
+ "not_satisfied": 0,
274
+ "not_applicable": 0,
275
+ "not_assessed": 0,
276
+ "risk_accepted": 0,
277
+ }
278
+ continue
279
+
280
+ satisfied = sum(1 for i in items if i["status"] == "satisfied")
281
+ partially = sum(1 for i in items if i["status"] == "partially_satisfied")
282
+ not_satisfied = sum(1 for i in items if i["status"] == "not_satisfied")
283
+ not_applicable = sum(1 for i in items if i["status"] == "not_applicable")
284
+ not_assessed = sum(1 for i in items if i["status"] == "not_assessed")
285
+ risk_accepted = sum(1 for i in items if i["status"] == "risk_accepted")
286
+
287
+ # Denominator excludes not_applicable
288
+ scoreable = total - not_applicable
289
+ if scoreable > 0:
290
+ score = 100.0 * (
291
+ satisfied + partially * 0.5 + risk_accepted * 0.75
292
+ ) / scoreable
293
+ else:
294
+ score = 100.0 # All N/A means fully compliant for this domain
295
+
296
+ results[domain] = {
297
+ "score": round(score, 1),
298
+ "total": total,
299
+ "satisfied": satisfied,
300
+ "partially_satisfied": partially,
301
+ "not_satisfied": not_satisfied,
302
+ "not_applicable": not_applicable,
303
+ "not_assessed": not_assessed,
304
+ "risk_accepted": risk_accepted,
305
+ }
306
+
307
+ return results
308
+
309
+
310
+ def _calculate_cisa_commitment_status(assessments, requirements):
311
+ """Map each of 7 CISA commitments to a compliance status.
312
+
313
+ Uses the requirements catalog to determine which requirements map to
314
+ each CISA commitment number. For each commitment, gathers assessments
315
+ for the matching requirements and determines overall status.
316
+
317
+ Status logic:
318
+ - All satisfied -> "Compliant"
319
+ - Any partially_satisfied (none not_satisfied) -> "Partially Compliant"
320
+ - Any not_satisfied -> "Non-Compliant"
321
+ - No assessments -> "Not Assessed"
322
+
323
+ Returns:
324
+ list of dicts with commitment_num, title, status, count,
325
+ satisfied_count.
326
+ """
327
+ # Build mapping: commitment_num -> list of requirement IDs
328
+ commitment_reqs = {num: [] for num in range(1, 8)}
329
+ for req_id, req_data in requirements.items():
330
+ cisa_num = req_data.get("cisa_commitment")
331
+ if cisa_num and cisa_num in commitment_reqs:
332
+ commitment_reqs[cisa_num].append(req_id)
333
+
334
+ # Build mapping: requirement_id -> assessment
335
+ assessment_map = {}
336
+ for a in assessments:
337
+ assessment_map[a.get("requirement_id")] = a
338
+
339
+ results = []
340
+ for num in range(1, 8):
341
+ title = CISA_COMMITMENTS.get(num, f"Commitment {num}")
342
+ req_ids = commitment_reqs[num]
343
+ count = len(req_ids)
344
+
345
+ if count == 0:
346
+ results.append({
347
+ "commitment_num": num,
348
+ "title": title,
349
+ "status": "Not Assessed",
350
+ "count": 0,
351
+ "satisfied_count": 0,
352
+ })
353
+ continue
354
+
355
+ # Gather statuses for this commitment's requirements
356
+ statuses = []
357
+ satisfied_count = 0
358
+ for req_id in req_ids:
359
+ a = assessment_map.get(req_id)
360
+ if a:
361
+ st = a.get("status", "not_assessed")
362
+ statuses.append(st)
363
+ if st == "satisfied":
364
+ satisfied_count += 1
365
+ else:
366
+ statuses.append("not_assessed")
367
+
368
+ # Determine commitment status
369
+ if all(s == "satisfied" for s in statuses):
370
+ status = "Compliant"
371
+ elif all(s in ("satisfied", "risk_accepted") for s in statuses):
372
+ status = "Compliant"
373
+ elif any(s == "not_satisfied" for s in statuses):
374
+ status = "Non-Compliant"
375
+ elif any(s == "partially_satisfied" for s in statuses):
376
+ status = "Partially Compliant"
377
+ elif any(s == "not_assessed" for s in statuses):
378
+ status = "Not Assessed"
379
+ else:
380
+ status = "Partially Compliant"
381
+
382
+ results.append({
383
+ "commitment_num": num,
384
+ "title": title,
385
+ "status": status,
386
+ "count": count,
387
+ "satisfied_count": satisfied_count,
388
+ })
389
+
390
+ return results
391
+
392
+
393
+ def _calculate_overall_status(domain_scores):
394
+ """Determine overall status from domain scores.
395
+
396
+ Returns:
397
+ tuple of (overall_score, overall_status_label)
398
+ """
399
+ scoreable_domains = [v for v in domain_scores.values() if v["total"] > 0]
400
+ if not scoreable_domains:
401
+ return 0.0, "Non-Compliant"
402
+
403
+ overall = sum(d["score"] for d in scoreable_domains) / len(scoreable_domains)
404
+ overall = round(overall, 1)
405
+
406
+ if overall >= 80:
407
+ status = "Compliant"
408
+ elif overall >= 50:
409
+ status = "Partially Compliant"
410
+ else:
411
+ status = "Non-Compliant"
412
+
413
+ return overall, status
414
+
415
+
416
+ # ---------------------------------------------------------------------------
417
+ # Section builder functions
418
+ # ---------------------------------------------------------------------------
419
+
420
+ def _build_domain_scores_table(domain_scores):
421
+ """Build a markdown table summarising per-domain scores."""
422
+ lines = [
423
+ "| Domain | Score | Satisfied | Partial | Not Satisfied | Not Assessed | N/A | Risk Accepted |",
424
+ "|--------|------:|----------:|--------:|--------------:|-------------:|----:|--------------:|",
425
+ ]
426
+ for domain in SBD_DOMAINS:
427
+ s = domain_scores.get(domain, {})
428
+ if s.get("total", 0) == 0:
429
+ continue
430
+ lines.append(
431
+ f"| {domain} | {s.get('score', 0.0):.1f}% "
432
+ f"| {s.get('satisfied', 0)} "
433
+ f"| {s.get('partially_satisfied', 0)} "
434
+ f"| {s.get('not_satisfied', 0)} "
435
+ f"| {s.get('not_assessed', 0)} "
436
+ f"| {s.get('not_applicable', 0)} "
437
+ f"| {s.get('risk_accepted', 0)} |"
438
+ )
439
+
440
+ return "\n".join(lines)
441
+
442
+
443
+ def _build_cisa_commitment_table(cisa_status):
444
+ """Build a markdown table of CISA commitment statuses."""
445
+ lines = [
446
+ "| # | Commitment | Status | Requirements | Satisfied |",
447
+ "|---|-----------|--------|-------------:|----------:|",
448
+ ]
449
+ for c in cisa_status:
450
+ num = c["commitment_num"]
451
+ title = c["title"]
452
+ status = c["status"]
453
+ count = c["count"]
454
+ satisfied = c["satisfied_count"]
455
+ lines.append(
456
+ f"| {num} | {title} | {status} | {count} | {satisfied} |"
457
+ )
458
+
459
+ return "\n".join(lines)
460
+
461
+
462
+ def _build_domain_details(assessments, domain_scores):
463
+ """Build markdown detail sections for each assessed domain.
464
+
465
+ Each domain gets a sub-heading and a table listing every requirement
466
+ with its status, evidence description, and notes.
467
+ """
468
+ domain_data = {domain: [] for domain in SBD_DOMAINS}
469
+ for a in assessments:
470
+ dom = a.get("domain")
471
+ if dom in domain_data:
472
+ domain_data[dom].append(a)
473
+
474
+ sections = []
475
+ for domain in SBD_DOMAINS:
476
+ items = domain_data[domain]
477
+ s = domain_scores.get(domain, {})
478
+ score = s.get("score", 0.0)
479
+
480
+ # Skip domains with no assessments
481
+ if not items and s.get("total", 0) == 0:
482
+ continue
483
+
484
+ sections.append(f"### {domain} ({score:.1f}%)")
485
+ sections.append("")
486
+
487
+ if not items:
488
+ sections.append("*No assessments recorded for this domain.*")
489
+ sections.append("")
490
+ continue
491
+
492
+ sections.append(
493
+ "| Requirement ID | Status | Automation | Evidence | Notes |"
494
+ )
495
+ sections.append(
496
+ "|----------------|--------|------------|----------|-------|"
497
+ )
498
+ for item in sorted(items, key=lambda x: x.get("requirement_id", "")):
499
+ req_id = item.get("requirement_id", "N/A")
500
+ status = item.get("status", "not_assessed")
501
+ automation = item.get("automation_result", "N/A") or "N/A"
502
+ evidence = (item.get("evidence_description") or "").replace("\n", " ").strip()
503
+ notes = (item.get("notes") or "").replace("\n", " ").strip()
504
+ # Truncate long fields for table readability
505
+ if len(evidence) > 80:
506
+ evidence = evidence[:77] + "..."
507
+ if len(notes) > 80:
508
+ notes = notes[:77] + "..."
509
+ if len(automation) > 30:
510
+ automation = automation[:27] + "..."
511
+ sections.append(
512
+ f"| {req_id} | {status} | {automation} | {evidence} | {notes} |"
513
+ )
514
+ sections.append("")
515
+
516
+ return "\n".join(sections)
517
+
518
+
519
+ def _build_findings_table(assessments):
520
+ """Build a table of not_satisfied requirements grouped by domain.
521
+
522
+ Lists all findings that are not satisfied, ordered by domain then
523
+ requirement ID.
524
+ """
525
+ findings = [
526
+ a for a in assessments if a.get("status") == "not_satisfied"
527
+ ]
528
+ if not findings:
529
+ return "*No findings requiring remediation.*"
530
+
531
+ lines = [
532
+ "| Domain | Requirement ID | Evidence | Notes |",
533
+ "|--------|----------------|----------|-------|",
534
+ ]
535
+ for domain in SBD_DOMAINS:
536
+ domain_findings = [f for f in findings if f.get("domain") == domain]
537
+ for f in sorted(domain_findings, key=lambda x: x.get("requirement_id", "")):
538
+ evidence = (f.get("evidence_description") or "").replace("\n", " ").strip()
539
+ notes = (f.get("notes") or "").replace("\n", " ").strip()
540
+ if len(evidence) > 60:
541
+ evidence = evidence[:57] + "..."
542
+ if len(notes) > 60:
543
+ notes = notes[:57] + "..."
544
+ lines.append(
545
+ f"| {domain} | {f.get('requirement_id', 'N/A')} "
546
+ f"| {evidence} | {notes} |"
547
+ )
548
+
549
+ return "\n".join(lines)
550
+
551
+
552
+ def _build_remediation_table(assessments):
553
+ """Build table of findings needing remediation with priority.
554
+
555
+ Priority is derived from the requirement priority in the catalog.
556
+ Default remediation windows: critical=14 days, high=30 days,
557
+ medium=60 days, low=90 days.
558
+ """
559
+ DEFAULT_WINDOWS = {
560
+ "critical": 14,
561
+ "high": 30,
562
+ "medium": 60,
563
+ "low": 90,
564
+ }
565
+
566
+ # Load requirements for priority data
567
+ requirements = _load_sbd_requirements()
568
+
569
+ needing_remediation = [
570
+ a for a in assessments
571
+ if a.get("status") in ("not_satisfied", "partially_satisfied")
572
+ ]
573
+ if not needing_remediation:
574
+ return "*No items require remediation at this time.*"
575
+
576
+ now = datetime.now(timezone.utc)
577
+ lines = [
578
+ "| Requirement ID | Domain | Current Status | Priority | Target Date | Remediation |",
579
+ "|----------------|--------|----------------|----------|-------------|-------------|",
580
+ ]
581
+
582
+ for item in sorted(needing_remediation,
583
+ key=lambda x: (
584
+ PRIORITY_ORDER.index(
585
+ requirements.get(x.get("requirement_id", ""), {}).get("priority", "low")
586
+ ) if requirements.get(x.get("requirement_id", ""), {}).get("priority", "low") in PRIORITY_ORDER else 99,
587
+ x.get("domain", ""),
588
+ x.get("requirement_id", ""),
589
+ )):
590
+ req_id = item.get("requirement_id", "N/A")
591
+ domain = item.get("domain", "N/A")
592
+ status = item.get("status", "N/A")
593
+
594
+ # Get priority from requirements catalog
595
+ req_data = requirements.get(req_id, {})
596
+ priority = req_data.get("priority", "medium")
597
+ title = req_data.get("title", "")
598
+
599
+ # Determine target date based on priority
600
+ window_days = DEFAULT_WINDOWS.get(priority, 60)
601
+ target = (now + timedelta(days=window_days)).strftime("%Y-%m-%d")
602
+
603
+ # Remediation suggestion
604
+ if status == "not_satisfied":
605
+ remediation = f"Implement {title}" if title else "Full implementation required"
606
+ else:
607
+ remediation = f"Complete {title}" if title else "Complete partial implementation"
608
+
609
+ if len(remediation) > 50:
610
+ remediation = remediation[:47] + "..."
611
+
612
+ lines.append(
613
+ f"| {req_id} | {domain} | {status} | {priority} | {target} | {remediation} |"
614
+ )
615
+
616
+ return "\n".join(lines)
617
+
618
+
619
+ def _build_evidence_summary(assessments):
620
+ """Count evidence artifacts by domain."""
621
+ domain_counts = {domain: {"with_evidence": 0, "without_evidence": 0, "total": 0}
622
+ for domain in SBD_DOMAINS}
623
+
624
+ for a in assessments:
625
+ dom = a.get("domain")
626
+ if dom not in domain_counts:
627
+ continue
628
+ domain_counts[dom]["total"] += 1
629
+ if a.get("evidence_path") or a.get("evidence_description"):
630
+ domain_counts[dom]["with_evidence"] += 1
631
+ else:
632
+ domain_counts[dom]["without_evidence"] += 1
633
+
634
+ lines = [
635
+ "| Domain | Total Requirements | With Evidence | Without Evidence | Coverage |",
636
+ "|--------|-------------------:|--------------:|-----------------:|---------:|",
637
+ ]
638
+ for domain in SBD_DOMAINS:
639
+ c = domain_counts[domain]
640
+ if c["total"] == 0:
641
+ continue
642
+ coverage = (
643
+ f"{100.0 * c['with_evidence'] / c['total']:.0f}%"
644
+ if c["total"] > 0 else "N/A"
645
+ )
646
+ lines.append(
647
+ f"| {domain} | {c['total']} | {c['with_evidence']} "
648
+ f"| {c['without_evidence']} | {coverage} |"
649
+ )
650
+
651
+ total_all = sum(c["total"] for c in domain_counts.values())
652
+ total_with = sum(c["with_evidence"] for c in domain_counts.values())
653
+ total_without = sum(c["without_evidence"] for c in domain_counts.values())
654
+ total_cov = f"{100.0 * total_with / total_all:.0f}%" if total_all > 0 else "N/A"
655
+ lines.append(
656
+ f"| **Total** | **{total_all}** | **{total_with}** "
657
+ f"| **{total_without}** | **{total_cov}** |"
658
+ )
659
+
660
+ return "\n".join(lines)
661
+
662
+
663
+ def _build_nist_mapping(assessments, requirements):
664
+ """Build NIST 800-53 control mapping table.
665
+
666
+ Maps each assessed requirement to its corresponding NIST controls
667
+ from the requirements catalog.
668
+ """
669
+ if not requirements:
670
+ return "*NIST control mapping unavailable (requirements catalog not loaded).*"
671
+
672
+ # Collect unique requirement IDs from assessments
673
+ assessed_reqs = set()
674
+ assessment_map = {}
675
+ for a in assessments:
676
+ req_id = a.get("requirement_id")
677
+ if req_id:
678
+ assessed_reqs.add(req_id)
679
+ assessment_map[req_id] = a
680
+
681
+ if not assessed_reqs:
682
+ return "*No assessed requirements to map.*"
683
+
684
+ lines = [
685
+ "| Requirement ID | Domain | NIST Controls | Status |",
686
+ "|----------------|--------|---------------|--------|",
687
+ ]
688
+
689
+ for req_id in sorted(assessed_reqs):
690
+ req_data = requirements.get(req_id, {})
691
+ domain = req_data.get("domain", "N/A")
692
+ nist_controls = req_data.get("nist_controls", [])
693
+ nist_str = ", ".join(nist_controls) if nist_controls else "N/A"
694
+ status = assessment_map.get(req_id, {}).get("status", "not_assessed")
695
+ lines.append(
696
+ f"| {req_id} | {domain} | {nist_str} | {status} |"
697
+ )
698
+
699
+ return "\n".join(lines)
700
+
701
+
702
+ def _build_auto_check_results(assessments, requirements):
703
+ """Build table of automated check results.
704
+
705
+ Filters for requirements with automation_level 'auto' and shows
706
+ their automation_result field from the assessment.
707
+ """
708
+ # Identify which requirements are auto-checkable
709
+ auto_req_ids = set()
710
+ for req_id, req_data in requirements.items():
711
+ if req_data.get("automation_level") == "auto":
712
+ auto_req_ids.add(req_id)
713
+
714
+ auto_assessments = [
715
+ a for a in assessments
716
+ if a.get("requirement_id") in auto_req_ids
717
+ ]
718
+
719
+ if not auto_assessments:
720
+ return "*No automated check results available.*"
721
+
722
+ lines = [
723
+ "| Requirement ID | Domain | Status | Automation Result |",
724
+ "|----------------|--------|--------|-------------------|",
725
+ ]
726
+ for a in sorted(auto_assessments, key=lambda x: x.get("requirement_id", "")):
727
+ req_id = a.get("requirement_id", "N/A")
728
+ domain = a.get("domain", "N/A")
729
+ status = a.get("status", "not_assessed")
730
+ result = (a.get("automation_result") or "N/A").replace("\n", " ").strip()
731
+ if len(result) > 60:
732
+ result = result[:57] + "..."
733
+ lines.append(
734
+ f"| {req_id} | {domain} | {status} | {result} |"
735
+ )
736
+
737
+ return "\n".join(lines)
738
+
739
+
740
+ def _build_manual_review_items(assessments, requirements):
741
+ """Build table of requirements needing manual review.
742
+
743
+ Filters for requirements with automation_level 'semi' or 'manual'.
744
+ """
745
+ # Identify which requirements need manual/semi review
746
+ manual_req_ids = set()
747
+ for req_id, req_data in requirements.items():
748
+ if req_data.get("automation_level") in ("semi", "manual"):
749
+ manual_req_ids.add(req_id)
750
+
751
+ manual_assessments = [
752
+ a for a in assessments
753
+ if a.get("requirement_id") in manual_req_ids
754
+ ]
755
+
756
+ if not manual_assessments:
757
+ return "*No manual review items.*"
758
+
759
+ lines = [
760
+ "| Requirement ID | Domain | Automation Level | Status | Notes |",
761
+ "|----------------|--------|------------------|--------|-------|",
762
+ ]
763
+ for a in sorted(manual_assessments, key=lambda x: x.get("requirement_id", "")):
764
+ req_id = a.get("requirement_id", "N/A")
765
+ domain = a.get("domain", "N/A")
766
+ status = a.get("status", "not_assessed")
767
+ req_data = requirements.get(req_id, {})
768
+ auto_level = req_data.get("automation_level", "manual")
769
+ notes = (a.get("notes") or "").replace("\n", " ").strip()
770
+ if len(notes) > 60:
771
+ notes = notes[:57] + "..."
772
+ lines.append(
773
+ f"| {req_id} | {domain} | {auto_level} | {status} | {notes} |"
774
+ )
775
+
776
+ return "\n".join(lines)
777
+
778
+
779
+ def _build_executive_summary(overall_score, overall_status, gate_result,
780
+ domain_scores, cisa_status, assessments,
781
+ requirements):
782
+ """Build the executive summary paragraph.
783
+
784
+ Provides a high-level overview of the assessment results including
785
+ key metrics, gate status, and notable findings.
786
+ """
787
+ total_assessed = len(assessments)
788
+ total_satisfied = sum(1 for a in assessments if a.get("status") == "satisfied")
789
+ total_not_satisfied = sum(1 for a in assessments if a.get("status") == "not_satisfied")
790
+ total_partial = sum(1 for a in assessments if a.get("status") == "partially_satisfied")
791
+ total_na = sum(1 for a in assessments if a.get("status") == "not_applicable")
792
+ total_not_assessed = sum(1 for a in assessments if a.get("status") == "not_assessed")
793
+
794
+ # Count domains with assessments
795
+ domains_with_data = sum(
796
+ 1 for d in domain_scores.values() if d.get("total", 0) > 0
797
+ )
798
+
799
+ # Count critical not_satisfied
800
+ critical_not_satisfied = 0
801
+ for a in assessments:
802
+ if a.get("status") == "not_satisfied":
803
+ req_data = requirements.get(a.get("requirement_id", ""), {})
804
+ if req_data.get("priority") == "critical":
805
+ critical_not_satisfied += 1
806
+
807
+ # Count CISA commitments by status
808
+ cisa_compliant = sum(1 for c in cisa_status if c["status"] == "Compliant")
809
+ cisa_total = len(cisa_status)
810
+
811
+ # Identify weakest domain
812
+ scored_domains = {
813
+ d: s for d, s in domain_scores.items()
814
+ if s.get("total", 0) > 0 and s.get("total", 0) != s.get("not_applicable", 0)
815
+ }
816
+ weakest_domain = ""
817
+ weakest_score = 100.0
818
+ for d, s in scored_domains.items():
819
+ if s["score"] < weakest_score:
820
+ weakest_score = s["score"]
821
+ weakest_domain = d
822
+
823
+ lines = []
824
+ lines.append(
825
+ f"This Secure by Design assessment evaluated {total_assessed} requirements "
826
+ f"across {domains_with_data} domains. The overall score is **{overall_score:.1f}%** "
827
+ f"with a gate result of **{gate_result}**."
828
+ )
829
+ lines.append("")
830
+ lines.append(
831
+ f"- **{total_satisfied}** requirements satisfied, "
832
+ f"**{total_partial}** partially satisfied, "
833
+ f"**{total_not_satisfied}** not satisfied, "
834
+ f"**{total_not_assessed}** not assessed, "
835
+ f"**{total_na}** not applicable."
836
+ )
837
+ lines.append(
838
+ f"- **{cisa_compliant}/{cisa_total}** CISA Secure by Design commitments are compliant."
839
+ )
840
+ if critical_not_satisfied > 0:
841
+ lines.append(
842
+ f"- **{critical_not_satisfied} critical-priority requirement(s) not satisfied** "
843
+ f"-- immediate remediation required."
844
+ )
845
+ if weakest_domain:
846
+ lines.append(
847
+ f"- Weakest domain: **{weakest_domain}** ({weakest_score:.1f}%)."
848
+ )
849
+
850
+ return "\n".join(lines), critical_not_satisfied
851
+
852
+
853
+ # ---------------------------------------------------------------------------
854
+ # Variable substitution & CUI markings
855
+ # ---------------------------------------------------------------------------
856
+
857
+ def _apply_cui_markings(content, cui_config):
858
+ """Apply CUI header and footer banners to the report content."""
859
+ header = cui_config.get("document_header", "").strip()
860
+ footer = cui_config.get("document_footer", "").strip()
861
+ banner_top = cui_config.get("banner_top", "CUI // SP-CTI")
862
+
863
+ # If the content already contains the banner, skip
864
+ if banner_top in content:
865
+ return content
866
+
867
+ return f"{header}\n\n{content.strip()}\n\n{footer}\n"
868
+
869
+
870
+ def _substitute_variables(template, variables):
871
+ """Replace {{variable_name}} placeholders in the template."""
872
+ def replacer(match):
873
+ key = match.group(1).strip()
874
+ return str(variables.get(key, match.group(0)))
875
+ return re.sub(r"\{\{(\w+)\}\}", replacer, template)
876
+
877
+
878
+ # ---------------------------------------------------------------------------
879
+ # Audit logging
880
+ # ---------------------------------------------------------------------------
881
+
882
+ def _log_audit_event(conn, project_id, action, details, file_path):
883
+ """Log an audit trail event for SbD report generation."""
884
+ try:
885
+ conn.execute(
886
+ """INSERT INTO audit_trail
887
+ (project_id, event_type, actor, action, details,
888
+ affected_files, classification)
889
+ VALUES (?, ?, ?, ?, ?, ?, ?)""",
890
+ (
891
+ project_id,
892
+ "sbd_report_generated",
893
+ "icdev-compliance-engine",
894
+ action,
895
+ json.dumps(details),
896
+ json.dumps([str(file_path)]),
897
+ "CUI",
898
+ ),
899
+ )
900
+ conn.commit()
901
+ except Exception as e:
902
+ print(f"Warning: Could not log audit event: {e}", file=sys.stderr)
903
+
904
+
905
+ # ---------------------------------------------------------------------------
906
+ # Main generator
907
+ # ---------------------------------------------------------------------------
908
+
909
+ def generate_sbd_report(project_id, output_path=None, db_path=None):
910
+ """Generate a Secure by Design assessment report for a project.
911
+
912
+ Args:
913
+ project_id: The project identifier.
914
+ output_path: Override output directory or file path.
915
+ db_path: Override database path.
916
+
917
+ Returns:
918
+ dict with ``output_file`` path and metadata about the generated report.
919
+ """
920
+ conn = get_connection(db_path=db_path)
921
+ try:
922
+ # 1. Load project data
923
+ project = _get_project_data(conn, project_id)
924
+ project_name = project.get("name", project_id)
925
+
926
+ # 2. Load template (with fallback)
927
+ template = _load_template()
928
+
929
+ # 3. Query sbd_assessments
930
+ assessments = _get_sbd_assessments(conn, project_id)
931
+
932
+ # Cross-reference data for enrichment
933
+ stig_findings = _get_stig_findings(conn, project_id)
934
+ sbom_records = _get_sbom_records(conn, project_id)
935
+
936
+ # 4. Load requirements catalog for CISA commitment mapping
937
+ requirements = _load_sbd_requirements()
938
+
939
+ # 5. Calculate domain scores, CISA status, overall status
940
+ domain_scores = _calculate_domain_scores(assessments)
941
+ overall_score, overall_status = _calculate_overall_status(domain_scores)
942
+ cisa_status = _calculate_cisa_commitment_status(assessments, requirements)
943
+
944
+ # Determine gate result: PASS if 0 critical-priority reqs are not_satisfied
945
+ critical_not_sat = 0
946
+ for a in assessments:
947
+ if a.get("status") == "not_satisfied":
948
+ req_data = requirements.get(a.get("requirement_id", ""), {})
949
+ if req_data.get("priority") == "critical":
950
+ critical_not_sat += 1
951
+ gate_result = "PASS" if critical_not_sat == 0 else "FAIL"
952
+
953
+ # 6. Build all section content
954
+ domain_scores_table = _build_domain_scores_table(domain_scores)
955
+ cisa_commitment_table = _build_cisa_commitment_table(cisa_status)
956
+ domain_details = _build_domain_details(assessments, domain_scores)
957
+ findings_table = _build_findings_table(assessments)
958
+ remediation_table = _build_remediation_table(assessments)
959
+ evidence_summary = _build_evidence_summary(assessments)
960
+ nist_mapping = _build_nist_mapping(assessments, requirements)
961
+ auto_check_results = _build_auto_check_results(assessments, requirements)
962
+ manual_review_items = _build_manual_review_items(assessments, requirements)
963
+ executive_summary, critical_not_satisfied = _build_executive_summary(
964
+ overall_score, overall_status, gate_result,
965
+ domain_scores, cisa_status, assessments, requirements,
966
+ )
967
+
968
+ # Count domains with data
969
+ domains_assessed = sum(
970
+ 1 for d in domain_scores.values() if d.get("total", 0) > 0
971
+ )
972
+
973
+ # Load CUI config for banner variables
974
+ cui_config = _load_cui_config()
975
+
976
+ # Determine version number by counting existing SbD audit events
977
+ report_count_row = conn.execute(
978
+ """SELECT COUNT(*) as cnt FROM audit_trail
979
+ WHERE project_id = ? AND event_type = 'sbd_report_generated'""",
980
+ (project_id,),
981
+ ).fetchone()
982
+ report_count = report_count_row["cnt"] if report_count_row else 0
983
+ new_version = f"{report_count + 1}.0"
984
+
985
+ now = datetime.now(timezone.utc)
986
+
987
+ # Determine assessor from most recent assessment
988
+ assessor = "icdev-compliance-engine"
989
+ if assessments:
990
+ assessor = assessments[0].get("assessor", assessor)
991
+
992
+ # 7. Create substitution dict with all {{variables}}
993
+ variables = {
994
+ # Project info
995
+ "project_name": project_name,
996
+ "project_id": project_id,
997
+ "classification": project.get("classification", "CUI"),
998
+
999
+ # Report metadata
1000
+ "version": new_version,
1001
+ "report_version": new_version,
1002
+ "assessment_date": now.strftime("%Y-%m-%d"),
1003
+ "date_prepared": now.strftime("%Y-%m-%d"),
1004
+ "assessor": assessor,
1005
+ "generation_timestamp": now.strftime("%Y-%m-%d %H:%M UTC"),
1006
+ "icdev_version": "1.0",
1007
+
1008
+ # Overall scores
1009
+ "overall_score": f"{overall_score:.1f}",
1010
+ "overall_status": overall_status,
1011
+ "gate_result": gate_result,
1012
+ "domains_assessed": str(domains_assessed),
1013
+ "critical_not_satisfied": str(critical_not_satisfied),
1014
+
1015
+ # Executive summary
1016
+ "executive_summary": executive_summary,
1017
+
1018
+ # CISA commitments
1019
+ "cisa_commitment_table": cisa_commitment_table,
1020
+
1021
+ # Domain scores
1022
+ "domain_scores_table": domain_scores_table,
1023
+
1024
+ # Domain details
1025
+ "domain_details": domain_details,
1026
+
1027
+ # Auto-check and manual review
1028
+ "auto_check_results": auto_check_results,
1029
+ "manual_review_items": manual_review_items,
1030
+
1031
+ # Findings and remediation
1032
+ "critical_findings": findings_table,
1033
+ "findings_table": findings_table,
1034
+ "remediation_table": remediation_table,
1035
+
1036
+ # Evidence
1037
+ "evidence_summary": evidence_summary,
1038
+
1039
+ # NIST mapping
1040
+ "nist_control_mapping": nist_mapping,
1041
+
1042
+ # Assessment counts
1043
+ "total_assessments": str(len(assessments)),
1044
+ "assessments_satisfied": str(sum(
1045
+ 1 for a in assessments if a.get("status") == "satisfied"
1046
+ )),
1047
+ "assessments_not_satisfied": str(sum(
1048
+ 1 for a in assessments if a.get("status") == "not_satisfied"
1049
+ )),
1050
+ "assessments_partial": str(sum(
1051
+ 1 for a in assessments if a.get("status") == "partially_satisfied"
1052
+ )),
1053
+ "assessments_na": str(sum(
1054
+ 1 for a in assessments if a.get("status") == "not_applicable"
1055
+ )),
1056
+ "assessments_not_assessed": str(sum(
1057
+ 1 for a in assessments if a.get("status") == "not_assessed"
1058
+ )),
1059
+ "assessments_risk_accepted": str(sum(
1060
+ 1 for a in assessments if a.get("status") == "risk_accepted"
1061
+ )),
1062
+
1063
+ # Cross-reference data
1064
+ "stig_findings_count": str(sum(r.get("cnt", 0) for r in stig_findings)),
1065
+ "sbom_records_count": str(len(sbom_records)),
1066
+ "sbom_latest_date": (
1067
+ sbom_records[0].get("generated_at", "N/A") if sbom_records else "N/A"
1068
+ ),
1069
+
1070
+ # CUI banners
1071
+ "cui_banner_top": cui_config.get(
1072
+ "document_header", cui_config.get("banner_top", "CUI // SP-CTI")
1073
+ ),
1074
+ "cui_banner_bottom": cui_config.get(
1075
+ "document_footer", cui_config.get("banner_bottom", "CUI // SP-CTI")
1076
+ ),
1077
+ }
1078
+
1079
+ # Per-domain score variables (e.g., authentication_score, etc.)
1080
+ for domain in SBD_DOMAINS:
1081
+ key_prefix = domain.lower().replace(" ", "_")
1082
+ s = domain_scores.get(domain, {})
1083
+ variables[f"{key_prefix}_score"] = f"{s.get('score', 0.0):.1f}"
1084
+ variables[f"{key_prefix}_total"] = str(s.get("total", 0))
1085
+ variables[f"{key_prefix}_satisfied"] = str(s.get("satisfied", 0))
1086
+ variables[f"{key_prefix}_not_satisfied"] = str(s.get("not_satisfied", 0))
1087
+ variables[f"{key_prefix}_partial"] = str(s.get("partially_satisfied", 0))
1088
+ variables[f"{key_prefix}_na"] = str(s.get("not_applicable", 0))
1089
+
1090
+ # Per-CISA commitment variables
1091
+ for c in cisa_status:
1092
+ num = c["commitment_num"]
1093
+ variables[f"cisa_{num}_status"] = c["status"]
1094
+ variables[f"cisa_{num}_title"] = c["title"]
1095
+ variables[f"cisa_{num}_count"] = str(c["count"])
1096
+ variables[f"cisa_{num}_satisfied"] = str(c["satisfied_count"])
1097
+
1098
+ # 8. Apply regex substitution
1099
+ report_content = _substitute_variables(template, variables)
1100
+
1101
+ # 9. Apply CUI markings (header/footer banners)
1102
+ report_content = _apply_cui_markings(report_content, cui_config)
1103
+
1104
+ # 10. Determine output path
1105
+ if output_path:
1106
+ out_path = Path(output_path)
1107
+ if out_path.is_dir() or str(output_path).endswith("/") or str(output_path).endswith("\\"):
1108
+ out_dir = out_path
1109
+ out_file = out_dir / f"sbd-report-v{new_version}.md"
1110
+ else:
1111
+ out_file = out_path
1112
+ else:
1113
+ dir_path = project.get("directory_path", "")
1114
+ if dir_path:
1115
+ out_dir = Path(dir_path) / "compliance"
1116
+ else:
1117
+ out_dir = BASE_DIR / "projects" / project_name / "compliance"
1118
+ out_file = out_dir / f"sbd-report-v{new_version}.md"
1119
+
1120
+ out_file.parent.mkdir(parents=True, exist_ok=True)
1121
+
1122
+ # 11. Write file
1123
+ with open(out_file, "w", encoding="utf-8") as f:
1124
+ f.write(report_content)
1125
+
1126
+ # 12. Log audit event
1127
+ audit_details = {
1128
+ "version": new_version,
1129
+ "overall_score": overall_score,
1130
+ "overall_status": overall_status,
1131
+ "gate_result": gate_result,
1132
+ "domains_assessed": domains_assessed,
1133
+ "total_assessments": len(assessments),
1134
+ "critical_not_satisfied": critical_not_satisfied,
1135
+ "cisa_commitments_compliant": sum(
1136
+ 1 for c in cisa_status if c["status"] == "Compliant"
1137
+ ),
1138
+ "stig_findings": sum(r.get("cnt", 0) for r in stig_findings),
1139
+ "sbom_records": len(sbom_records),
1140
+ "output_file": str(out_file),
1141
+ }
1142
+ _log_audit_event(
1143
+ conn, project_id,
1144
+ f"SbD report v{new_version} generated",
1145
+ audit_details,
1146
+ out_file,
1147
+ )
1148
+
1149
+ # Print summary
1150
+ print("SbD assessment report generated successfully:")
1151
+ print(f" File: {out_file}")
1152
+ print(f" Version: {new_version}")
1153
+ print(f" Project: {project_name}")
1154
+ print(f" Overall Score: {overall_score:.1f}%")
1155
+ print(f" Overall Status: {overall_status}")
1156
+ print(f" Gate Result: {gate_result}")
1157
+ print(f" Domains Assessed: {domains_assessed} / {len(SBD_DOMAINS)}")
1158
+ print(f" Total Assessments: {len(assessments)}")
1159
+ print(f" Critical Not Satisfied:{critical_not_satisfied}")
1160
+ print(f" CISA Commitments: {sum(1 for c in cisa_status if c['status'] == 'Compliant')}/7 Compliant")
1161
+
1162
+ # 13. Return output metadata
1163
+ return {
1164
+ "output_file": str(out_file),
1165
+ "version": new_version,
1166
+ "project_id": project_id,
1167
+ "project_name": project_name,
1168
+ "overall_score": overall_score,
1169
+ "overall_status": overall_status,
1170
+ "gate_result": gate_result,
1171
+ "domain_scores": {
1172
+ domain: domain_scores[domain]["score"] for domain in SBD_DOMAINS
1173
+ if domain_scores[domain]["total"] > 0
1174
+ },
1175
+ "cisa_status": [
1176
+ {
1177
+ "commitment": c["commitment_num"],
1178
+ "title": c["title"],
1179
+ "status": c["status"],
1180
+ }
1181
+ for c in cisa_status
1182
+ ],
1183
+ "domains_assessed": domains_assessed,
1184
+ "total_assessments": len(assessments),
1185
+ "critical_not_satisfied": critical_not_satisfied,
1186
+ "generated_at": now.isoformat(),
1187
+ }
1188
+
1189
+ finally:
1190
+ conn.close()
1191
+
1192
+
1193
+ # ---------------------------------------------------------------------------
1194
+ # CLI entry point
1195
+ # ---------------------------------------------------------------------------
1196
+
1197
+ if __name__ == "__main__":
1198
+ parser = argparse.ArgumentParser(
1199
+ description="Generate SbD assessment report"
1200
+ )
1201
+ parser.add_argument("--project-id", required=True, help="Project ID")
1202
+ parser.add_argument("--output-dir", help="Output directory")
1203
+ parser.add_argument(
1204
+ "--db-path", type=Path, default=DB_PATH, help="Database path"
1205
+ )
1206
+ parser.add_argument(
1207
+ "--format", choices=["text", "json"], default="text",
1208
+ help="Output format: text (default) or json"
1209
+ )
1210
+ parser.add_argument("--json", action="store_true", dest="json_output", help="JSON output")
1211
+ args = parser.parse_args()
1212
+
1213
+ try:
1214
+ result = generate_sbd_report(
1215
+ args.project_id, args.output_dir, args.db_path
1216
+ )
1217
+ if args.format == "json":
1218
+ print(json.dumps(result, indent=2))
1219
+ else:
1220
+ print(f"\nSbD report generated: {result['output_file']}")
1221
+ except (FileNotFoundError, ValueError) as e:
1222
+ print(f"ERROR: {e}", file=sys.stderr)
1223
+ sys.exit(1)