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,2157 @@
1
+ #!/usr/bin/env python3
2
+ # CUI // SP-CTI
3
+ ####################################################################
4
+ # CONTROLLED UNCLASSIFIED INFORMATION (CUI) // SP-CTI
5
+ # Distribution: Distribution D -- Authorized DoD Personnel Only
6
+ ####################################################################
7
+ """NIST OSCAL 1.1.2 artifact generator for ICDEV.
8
+
9
+ Generates four OSCAL JSON artifact types from the ICDEV database:
10
+ - System Security Plan (SSP)
11
+ - Plan of Action & Milestones (POA&M)
12
+ - Assessment Results
13
+ - Component Definition
14
+
15
+ Each artifact conforms to the OSCAL 1.1.2 specification with proper UUIDs,
16
+ ISO 8601 timestamps, and lowercase hyphenated control IDs.
17
+
18
+ Usage:
19
+ python tools/compliance/oscal_generator.py --project-id "proj-123" --artifact all
20
+ python tools/compliance/oscal_generator.py --project-id "proj-123" --artifact ssp
21
+ python tools/compliance/oscal_generator.py --validate "/path/to/ssp.oscal.json"
22
+ """
23
+
24
+ import argparse
25
+ import hashlib
26
+ import json
27
+ import re
28
+ import sqlite3
29
+ import sys
30
+ import uuid
31
+ from datetime import datetime, timezone
32
+ from pathlib import Path
33
+ from tools.db.storage import get_connection
34
+
35
+ # ---------------------------------------------------------------------------
36
+ # Constants
37
+ # ---------------------------------------------------------------------------
38
+
39
+ BASE_DIR = Path(__file__).resolve().parent.parent.parent
40
+ OSCAL_VERSION = "1.1.2"
41
+ OSCAL_NS = "http://csrc.nist.gov/ns/oscal/1.0"
42
+
43
+ # FedRAMP profile URIs by baseline
44
+ FEDRAMP_PROFILE_URIS = {
45
+ "low": "https://raw.githubusercontent.com/GSA/fedramp-automation/master/dist/content/rev5/baselines/json/FedRAMP_rev5_LOW-baseline-resolved-profile_catalog.json",
46
+ "moderate": "https://raw.githubusercontent.com/GSA/fedramp-automation/master/dist/content/rev5/baselines/json/FedRAMP_rev5_MODERATE-baseline-resolved-profile_catalog.json",
47
+ "high": "https://raw.githubusercontent.com/GSA/fedramp-automation/master/dist/content/rev5/baselines/json/FedRAMP_rev5_HIGH-baseline-resolved-profile_catalog.json",
48
+ }
49
+
50
+ # Impact level to FedRAMP baseline mapping
51
+ IL_TO_BASELINE = {
52
+ "IL4": "moderate",
53
+ "IL4": "moderate",
54
+ "IL4": "high",
55
+ "IL4": "high",
56
+ }
57
+
58
+ # NIST 800-53 control family names
59
+ CONTROL_FAMILIES = {
60
+ "ac": "Access Control",
61
+ "at": "Awareness and Training",
62
+ "au": "Audit and Accountability",
63
+ "ca": "Assessment, Authorization, and Monitoring",
64
+ "cm": "Configuration Management",
65
+ "cp": "Contingency Planning",
66
+ "ia": "Identification and Authentication",
67
+ "ir": "Incident Response",
68
+ "ma": "Maintenance",
69
+ "mp": "Media Protection",
70
+ "pe": "Physical and Environmental Protection",
71
+ "pl": "Planning",
72
+ "pm": "Program Management",
73
+ "ps": "Personnel Security",
74
+ "pt": "PII Processing and Transparency",
75
+ "ra": "Risk Assessment",
76
+ "sa": "System and Services Acquisition",
77
+ "sc": "System and Communications Protection",
78
+ "si": "System and Information Integrity",
79
+ "sr": "Supply Chain Risk Management",
80
+ }
81
+
82
+ # UUID pattern for validation
83
+ UUID_PATTERN = re.compile(
84
+ r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"
85
+ )
86
+
87
+ # ISO 8601 timestamp pattern for validation
88
+ ISO_TIMESTAMP_PATTERN = re.compile(
89
+ r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z$"
90
+ )
91
+
92
+ # OSCAL control-id pattern (lowercase, hyphenated)
93
+ CONTROL_ID_PATTERN = re.compile(r"^[a-z]{2}-\d+(\.\d+)?$")
94
+
95
+
96
+ # ---------------------------------------------------------------------------
97
+ # Helper functions
98
+ # ---------------------------------------------------------------------------
99
+
100
+ def _generate_uuid():
101
+ """Generate a UUID4 string for OSCAL identifiers."""
102
+ return str(uuid.uuid4())
103
+
104
+
105
+ def _oscal_timestamp():
106
+ """Generate an ISO 8601 timestamp with Z timezone for OSCAL metadata."""
107
+ return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z"
108
+
109
+
110
+ def _control_id_to_oscal(control_id):
111
+ """Convert a control ID to OSCAL format (lowercase with hyphens).
112
+
113
+ Examples:
114
+ "AC-2" -> "ac-2"
115
+ "AC-2(1)" -> "ac-2.1"
116
+ "ac-2" -> "ac-2"
117
+ "SI-4(4)" -> "si-4.4"
118
+ """
119
+ if not control_id:
120
+ return ""
121
+ cid = control_id.strip().lower()
122
+ # Convert enhancement notation: ac-2(1) -> ac-2.1
123
+ cid = re.sub(r"\((\d+)\)", r".\1", cid)
124
+ return cid
125
+
126
+
127
+ def _compute_file_hash(file_path):
128
+ """Compute SHA-256 hash of a file for integrity verification."""
129
+ sha256 = hashlib.sha256()
130
+ path = Path(file_path)
131
+ if not path.exists():
132
+ return ""
133
+ with open(path, "rb") as f:
134
+ for chunk in iter(lambda: f.read(8192), b""):
135
+ sha256.update(chunk)
136
+ return sha256.hexdigest()
137
+
138
+
139
+ # ---------------------------------------------------------------------------
140
+ # Database helpers
141
+ # ---------------------------------------------------------------------------
142
+
143
+
144
+ def _get_project(conn, project_id):
145
+ """Load project record from the projects table."""
146
+ row = conn.execute(
147
+ "SELECT * FROM projects WHERE id = ?", (project_id,)
148
+ ).fetchone()
149
+ if not row:
150
+ raise ValueError(f"Project '{project_id}' not found in database.")
151
+ return dict(row)
152
+
153
+
154
+ def _get_controls(conn, project_id):
155
+ """Load control implementations for a project.
156
+
157
+ Joins project_controls with compliance_controls for full metadata.
158
+ Returns list of dicts with control_id, implementation_status,
159
+ implementation_description, responsible_role, evidence_path, family, title.
160
+ """
161
+ rows = conn.execute(
162
+ """SELECT pc.control_id, pc.implementation_status,
163
+ pc.implementation_description, pc.responsible_role,
164
+ pc.evidence_path, pc.last_assessed,
165
+ cc.family, cc.title AS control_title,
166
+ cc.description AS control_description
167
+ FROM project_controls pc
168
+ LEFT JOIN compliance_controls cc ON pc.control_id = cc.id
169
+ WHERE pc.project_id = ?
170
+ ORDER BY pc.control_id""",
171
+ (project_id,),
172
+ ).fetchall()
173
+ return [dict(r) for r in rows]
174
+
175
+
176
+ def _get_poam_items(conn, project_id):
177
+ """Load POA&M items for a project, ordered by severity."""
178
+ rows = conn.execute(
179
+ """SELECT * FROM poam_items
180
+ WHERE project_id = ?
181
+ ORDER BY
182
+ CASE severity
183
+ WHEN 'critical' THEN 1
184
+ WHEN 'high' THEN 2
185
+ WHEN 'moderate' THEN 3
186
+ WHEN 'low' THEN 4
187
+ END,
188
+ id""",
189
+ (project_id,),
190
+ ).fetchall()
191
+ return [dict(r) for r in rows]
192
+
193
+
194
+ def _get_findings(conn, project_id):
195
+ """Load assessment findings across all compliance frameworks.
196
+
197
+ Pulls from fedramp_assessments, cmmc_assessments, stig_findings,
198
+ cssp_assessments, and sbd_assessments tables.
199
+
200
+ Returns a dict keyed by source framework with lists of finding dicts.
201
+ """
202
+ findings = {}
203
+
204
+ # FedRAMP assessments
205
+ rows = conn.execute(
206
+ """SELECT control_id, baseline, status, implementation_status,
207
+ evidence_description, evidence_path, notes,
208
+ assessment_date, assessor
209
+ FROM fedramp_assessments
210
+ WHERE project_id = ?
211
+ ORDER BY control_id""",
212
+ (project_id,),
213
+ ).fetchall()
214
+ findings["fedramp"] = [dict(r) for r in rows]
215
+
216
+ # CMMC assessments
217
+ rows = conn.execute(
218
+ """SELECT practice_id, domain, level, status,
219
+ evidence_description, evidence_path, notes,
220
+ nist_171_id, assessment_date, assessor
221
+ FROM cmmc_assessments
222
+ WHERE project_id = ?
223
+ ORDER BY practice_id""",
224
+ (project_id,),
225
+ ).fetchall()
226
+ findings["cmmc"] = [dict(r) for r in rows]
227
+
228
+ # STIG findings
229
+ rows = conn.execute(
230
+ """SELECT stig_id, finding_id, rule_id, severity, title,
231
+ description, check_content, fix_text, status,
232
+ comments, target_type, assessed_by, assessed_at
233
+ FROM stig_findings
234
+ WHERE project_id = ?
235
+ ORDER BY severity, finding_id""",
236
+ (project_id,),
237
+ ).fetchall()
238
+ findings["stig"] = [dict(r) for r in rows]
239
+
240
+ # CSSP assessments
241
+ try:
242
+ rows = conn.execute(
243
+ """SELECT functional_area, requirement_id, status,
244
+ evidence_description, evidence_path, notes,
245
+ assessment_date, assessor
246
+ FROM cssp_assessments
247
+ WHERE project_id = ?
248
+ ORDER BY requirement_id""",
249
+ (project_id,),
250
+ ).fetchall()
251
+ findings["cssp"] = [dict(r) for r in rows]
252
+ except sqlite3.OperationalError:
253
+ findings["cssp"] = []
254
+
255
+ # SbD assessments
256
+ try:
257
+ rows = conn.execute(
258
+ """SELECT domain, requirement_id, status,
259
+ evidence_description, evidence_path, notes,
260
+ assessment_date, assessor
261
+ FROM sbd_assessments
262
+ WHERE project_id = ?
263
+ ORDER BY requirement_id""",
264
+ (project_id,),
265
+ ).fetchall()
266
+ findings["sbd"] = [dict(r) for r in rows]
267
+ except sqlite3.OperationalError:
268
+ findings["sbd"] = []
269
+
270
+ return findings
271
+
272
+
273
+ def _get_sbom_records(conn, project_id):
274
+ """Load SBOM records for a project."""
275
+ rows = conn.execute(
276
+ """SELECT * FROM sbom_records
277
+ WHERE project_id = ?
278
+ ORDER BY generated_at DESC""",
279
+ (project_id,),
280
+ ).fetchall()
281
+ return [dict(r) for r in rows]
282
+
283
+
284
+ def _store_oscal_artifact(conn, project_id, artifact_type, file_path,
285
+ file_hash, schema_valid, validation_errors=None):
286
+ """Insert or update an OSCAL artifact record in the oscal_artifacts table.
287
+
288
+ Uses INSERT OR REPLACE on UNIQUE(project_id, artifact_type, format).
289
+ """
290
+ errors_json = json.dumps(validation_errors) if validation_errors else None
291
+ try:
292
+ conn.execute(
293
+ """INSERT OR REPLACE INTO oscal_artifacts
294
+ (project_id, artifact_type, oscal_version, format,
295
+ file_path, file_hash, schema_valid, validation_errors,
296
+ generated_at, classification)
297
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
298
+ (
299
+ project_id,
300
+ artifact_type,
301
+ OSCAL_VERSION,
302
+ "json",
303
+ str(file_path),
304
+ file_hash,
305
+ 1 if schema_valid else 0,
306
+ errors_json,
307
+ _oscal_timestamp(),
308
+ "CUI",
309
+ ),
310
+ )
311
+ conn.commit()
312
+ except Exception as e:
313
+ print(f"Warning: Could not store OSCAL artifact record: {e}",
314
+ file=sys.stderr)
315
+
316
+
317
+ def _log_audit(conn, project_id, action, details):
318
+ """Log an audit trail event for OSCAL generation (append-only, NIST AU)."""
319
+ try:
320
+ conn.execute(
321
+ """INSERT INTO audit_trail
322
+ (project_id, event_type, actor, action, details,
323
+ affected_files, classification)
324
+ VALUES (?, ?, ?, ?, ?, ?, ?)""",
325
+ (
326
+ project_id,
327
+ "oscal_generated",
328
+ "icdev-compliance-engine",
329
+ action,
330
+ json.dumps(details),
331
+ json.dumps(details.get("affected_files", [])),
332
+ "CUI",
333
+ ),
334
+ )
335
+ conn.commit()
336
+ except Exception as e:
337
+ print(f"Warning: Could not log audit event: {e}", file=sys.stderr)
338
+
339
+
340
+ def _resolve_output_dir(project, project_id, output_dir=None):
341
+ """Resolve the output directory for OSCAL artifacts.
342
+
343
+ Priority:
344
+ 1. Explicit output_dir argument
345
+ 2. Project directory_path / compliance / oscal
346
+ 3. BASE_DIR / .tmp / compliance / project_id / oscal
347
+ """
348
+ if output_dir:
349
+ out = Path(output_dir)
350
+ else:
351
+ dir_path = project.get("directory_path", "")
352
+ if dir_path:
353
+ out = Path(dir_path) / "compliance" / "oscal"
354
+ else:
355
+ out = BASE_DIR / ".tmp" / "compliance" / project_id / "oscal"
356
+ out.mkdir(parents=True, exist_ok=True)
357
+ return out
358
+
359
+
360
+ def _determine_baseline(project):
361
+ """Determine FedRAMP baseline from project impact level."""
362
+ il = project.get("impact_level", "IL4")
363
+ return IL_TO_BASELINE.get(il, "moderate")
364
+
365
+
366
+ def _build_metadata(project, title_prefix, extra_roles=None):
367
+ """Build the OSCAL metadata block common to all artifact types."""
368
+ now = _oscal_timestamp()
369
+ roles = [
370
+ {
371
+ "id": "system-owner",
372
+ "title": "System Owner",
373
+ },
374
+ {
375
+ "id": "authorizing-official",
376
+ "title": "Authorizing Official",
377
+ },
378
+ {
379
+ "id": "system-admin",
380
+ "title": "System Administrator",
381
+ },
382
+ {
383
+ "id": "isso",
384
+ "title": "Information System Security Officer",
385
+ },
386
+ {
387
+ "id": "issm",
388
+ "title": "Information System Security Manager",
389
+ },
390
+ ]
391
+ if extra_roles:
392
+ roles.extend(extra_roles)
393
+
394
+ parties = [
395
+ {
396
+ "uuid": _generate_uuid(),
397
+ "type": "organization",
398
+ "name": project.get("created_by", "Organization"),
399
+ "remarks": "System owning organization",
400
+ },
401
+ ]
402
+
403
+ return {
404
+ "title": f"{title_prefix} -- {project.get('name', 'UNNAMED')}",
405
+ "last-modified": now,
406
+ "version": "1.0",
407
+ "oscal-version": OSCAL_VERSION,
408
+ "roles": roles,
409
+ "parties": parties,
410
+ "remarks": (
411
+ f"Generated by ICDEV Compliance Engine. "
412
+ f"Classification: CUI // SP-CTI. "
413
+ f"Impact Level: {project.get('impact_level', 'IL4')}."
414
+ ),
415
+ }
416
+
417
+
418
+ def _build_system_characteristics(project):
419
+ """Build the system-characteristics block for SSP."""
420
+ baseline = _determine_baseline(project)
421
+ sensitivity = "high" if baseline == "high" else "moderate"
422
+
423
+ # Determine security objective levels from impact level
424
+ il = project.get("impact_level", "IL4")
425
+ if il in ("IL4", "IL4"):
426
+ conf = "high"
427
+ integ = "high"
428
+ avail = "moderate"
429
+ else:
430
+ conf = "moderate"
431
+ integ = "moderate"
432
+ avail = "low"
433
+
434
+ return {
435
+ "system-ids": [
436
+ {
437
+ "identifier-type": "https://ietf.org/rfc/rfc4122",
438
+ "id": project.get("id", _generate_uuid()),
439
+ }
440
+ ],
441
+ "system-name": project.get("name", "UNNAMED SYSTEM"),
442
+ "description": project.get("description", "System description pending."),
443
+ "security-sensitivity-level": sensitivity,
444
+ "system-information": {
445
+ "information-types": [
446
+ {
447
+ "uuid": _generate_uuid(),
448
+ "title": "Controlled Technical Information",
449
+ "description": (
450
+ "Technical information with military or space "
451
+ "application that is subject to controls on the access, "
452
+ "use, reproduction, modification, performance, display, "
453
+ "release, disclosure, or dissemination."
454
+ ),
455
+ "categorizations": [
456
+ {
457
+ "system": "https://doi.org/10.6028/NIST.SP.800-60v2r1",
458
+ "information-type-ids": ["C.3.5.8"],
459
+ }
460
+ ],
461
+ "confidentiality-impact": {
462
+ "base": conf,
463
+ },
464
+ "integrity-impact": {
465
+ "base": integ,
466
+ },
467
+ "availability-impact": {
468
+ "base": avail,
469
+ },
470
+ }
471
+ ],
472
+ },
473
+ "security-impact-level": {
474
+ "security-objective-confidentiality": conf,
475
+ "security-objective-integrity": integ,
476
+ "security-objective-availability": avail,
477
+ },
478
+ "status": {
479
+ "state": project.get("status", "under-development"),
480
+ "remarks": (
481
+ f"ATO Status: {project.get('ato_status', 'none')}. "
482
+ f"Classification: {project.get('classification', 'CUI')}."
483
+ ),
484
+ },
485
+ "authorization-boundary": {
486
+ "description": (
487
+ f"The authorization boundary encompasses the "
488
+ f"{project.get('name', 'system')} application, its "
489
+ f"supporting infrastructure within "
490
+ f"{project.get('cloud_environment', 'AWS GovCloud')}, "
491
+ f"and all data flows between components."
492
+ ),
493
+ },
494
+ "network-architecture": {
495
+ "description": (
496
+ f"The system operates within "
497
+ f"{project.get('cloud_environment', 'AWS GovCloud')} "
498
+ f"using a {project.get('type', 'webapp')} architecture. "
499
+ f"All network traffic is encrypted using TLS 1.2+ "
500
+ f"with FIPS 140-2 validated cryptographic modules."
501
+ ),
502
+ },
503
+ "data-flow": {
504
+ "description": (
505
+ "Data flows are restricted to encrypted channels. "
506
+ "All CUI data at rest is encrypted with AES-256. "
507
+ "Data in transit uses TLS 1.2+ with mutual TLS "
508
+ "for inter-service communication."
509
+ ),
510
+ },
511
+ }
512
+
513
+
514
+ def _build_system_implementation(project, controls):
515
+ """Build the system-implementation block for SSP."""
516
+ users = [
517
+ {
518
+ "uuid": _generate_uuid(),
519
+ "role-ids": ["system-owner"],
520
+ "title": "System Owner",
521
+ "description": "Responsible for overall system operation.",
522
+ },
523
+ {
524
+ "uuid": _generate_uuid(),
525
+ "role-ids": ["system-admin"],
526
+ "title": "System Administrator",
527
+ "description": "Manages system configuration and maintenance.",
528
+ },
529
+ {
530
+ "uuid": _generate_uuid(),
531
+ "role-ids": ["isso"],
532
+ "title": "ISSO",
533
+ "description": (
534
+ "Ensures system security controls are implemented "
535
+ "and operating effectively."
536
+ ),
537
+ },
538
+ ]
539
+
540
+ components = [
541
+ {
542
+ "uuid": _generate_uuid(),
543
+ "type": "this-system",
544
+ "title": project.get("name", "Application"),
545
+ "description": project.get("description", "Primary application component."),
546
+ "status": {
547
+ "state": "operational",
548
+ },
549
+ "props": [],
550
+ },
551
+ ]
552
+
553
+ # Add tech stack components if available
554
+ backend = project.get("tech_stack_backend")
555
+ if backend:
556
+ components.append({
557
+ "uuid": _generate_uuid(),
558
+ "type": "software",
559
+ "title": f"Backend: {backend}",
560
+ "description": f"Backend technology stack: {backend}",
561
+ "status": {"state": "operational"},
562
+ })
563
+
564
+ frontend = project.get("tech_stack_frontend")
565
+ if frontend:
566
+ components.append({
567
+ "uuid": _generate_uuid(),
568
+ "type": "software",
569
+ "title": f"Frontend: {frontend}",
570
+ "description": f"Frontend technology stack: {frontend}",
571
+ "status": {"state": "operational"},
572
+ })
573
+
574
+ database = project.get("tech_stack_database")
575
+ if database:
576
+ components.append({
577
+ "uuid": _generate_uuid(),
578
+ "type": "software",
579
+ "title": f"Database: {database}",
580
+ "description": f"Database technology: {database}",
581
+ "status": {"state": "operational"},
582
+ })
583
+
584
+ # Cloud infrastructure component
585
+ cloud_env = project.get("cloud_environment", "aws-govcloud")
586
+ components.append({
587
+ "uuid": _generate_uuid(),
588
+ "type": "leveraged-system",
589
+ "title": f"Cloud Infrastructure: {cloud_env}",
590
+ "description": (
591
+ f"Cloud infrastructure provided by {cloud_env}. "
592
+ f"FedRAMP authorized cloud service provider."
593
+ ),
594
+ "status": {"state": "operational"},
595
+ })
596
+
597
+ return {
598
+ "users": users,
599
+ "components": components,
600
+ }
601
+
602
+
603
+ def _build_control_implementation(controls, system_component_uuid=None):
604
+ """Build the control-implementation block for SSP.
605
+
606
+ Converts each project control into an OSCAL implemented-requirement.
607
+ """
608
+ implemented_requirements = []
609
+
610
+ for ctrl in controls:
611
+ oscal_cid = _control_id_to_oscal(ctrl["control_id"])
612
+ if not oscal_cid:
613
+ continue
614
+
615
+ # Build statement description from implementation details
616
+ description = ctrl.get("implementation_description") or (
617
+ f"Control {oscal_cid} implementation is "
618
+ f"{ctrl.get('implementation_status', 'planned')}."
619
+ )
620
+
621
+ req = {
622
+ "uuid": _generate_uuid(),
623
+ "control-id": oscal_cid,
624
+ "statements": [
625
+ {
626
+ "statement-id": f"{oscal_cid}_smt",
627
+ "uuid": _generate_uuid(),
628
+ "description": description,
629
+ }
630
+ ],
631
+ }
632
+
633
+ # Add props for status and responsible role
634
+ props = [
635
+ {
636
+ "name": "implementation-status",
637
+ "ns": OSCAL_NS,
638
+ "value": ctrl.get("implementation_status", "planned"),
639
+ },
640
+ ]
641
+ if ctrl.get("responsible_role"):
642
+ props.append({
643
+ "name": "responsible-role",
644
+ "ns": OSCAL_NS,
645
+ "value": ctrl["responsible_role"],
646
+ })
647
+ req["props"] = props
648
+
649
+ # Add responsible-roles if available
650
+ if ctrl.get("responsible_role"):
651
+ req["responsible-roles"] = [
652
+ {
653
+ "role-id": ctrl["responsible_role"]
654
+ .lower()
655
+ .replace(" ", "-")
656
+ .replace("_", "-"),
657
+ }
658
+ ]
659
+
660
+ implemented_requirements.append(req)
661
+
662
+ return {
663
+ "description": (
664
+ "This section describes the implementation of each "
665
+ "security control for the system. Controls are mapped to "
666
+ "NIST 800-53 Rev 5 per the applicable FedRAMP baseline."
667
+ ),
668
+ "implemented-requirements": implemented_requirements,
669
+ }
670
+
671
+
672
+ # ---------------------------------------------------------------------------
673
+ # Core generation functions
674
+ # ---------------------------------------------------------------------------
675
+
676
+ def generate_oscal_ssp(project_id, output_dir=None, db_path=None):
677
+ """Generate an OSCAL SSP JSON artifact.
678
+
679
+ Loads project data and control implementations from the database,
680
+ builds a full OSCAL 1.1.2 SSP structure, writes to disk, records
681
+ in oscal_artifacts, and logs an audit event.
682
+
683
+ Args:
684
+ project_id: The project identifier.
685
+ output_dir: Override output directory (default: project compliance/oscal/).
686
+ db_path: Override database path.
687
+
688
+ Returns:
689
+ Dict with file_path, uuid, controls_count, and validation result.
690
+ """
691
+ conn = get_connection(db_path=db_path)
692
+ try:
693
+ project = _get_project(conn, project_id)
694
+ controls = _get_controls(conn, project_id)
695
+ baseline = _determine_baseline(project)
696
+ profile_href = FEDRAMP_PROFILE_URIS.get(baseline, FEDRAMP_PROFILE_URIS["moderate"])
697
+
698
+ ssp_uuid = _generate_uuid()
699
+
700
+ # Build system-implementation first to get component UUIDs
701
+ sys_impl = _build_system_implementation(project, controls)
702
+ primary_component_uuid = (
703
+ sys_impl["components"][0]["uuid"]
704
+ if sys_impl["components"]
705
+ else None
706
+ )
707
+
708
+ ssp = {
709
+ "system-security-plan": {
710
+ "uuid": ssp_uuid,
711
+ "metadata": _build_metadata(project, "System Security Plan"),
712
+ "import-profile": {
713
+ "href": profile_href,
714
+ },
715
+ "system-characteristics": _build_system_characteristics(project),
716
+ "system-implementation": sys_impl,
717
+ "control-implementation": _build_control_implementation(
718
+ controls, primary_component_uuid
719
+ ),
720
+ "back-matter": {
721
+ "resources": [
722
+ {
723
+ "uuid": _generate_uuid(),
724
+ "title": "FedRAMP Profile",
725
+ "description": (
726
+ f"FedRAMP {baseline.capitalize()} baseline profile."
727
+ ),
728
+ "rlinks": [
729
+ {"href": profile_href},
730
+ ],
731
+ },
732
+ {
733
+ "uuid": _generate_uuid(),
734
+ "title": "NIST SP 800-53 Rev 5",
735
+ "description": (
736
+ "Security and Privacy Controls for Information "
737
+ "Systems and Organizations."
738
+ ),
739
+ "rlinks": [
740
+ {
741
+ "href": "https://doi.org/10.6028/NIST.SP.800-53r5",
742
+ },
743
+ ],
744
+ },
745
+ ],
746
+ },
747
+ },
748
+ }
749
+
750
+ # Write to file
751
+ out_dir = _resolve_output_dir(project, project_id, output_dir)
752
+ out_file = out_dir / "ssp.oscal.json"
753
+
754
+ with open(out_file, "w", encoding="utf-8") as f:
755
+ json.dump(ssp, f, indent=2, ensure_ascii=False)
756
+
757
+ file_hash = _compute_file_hash(out_file)
758
+
759
+ # Validate
760
+ validation = validate_oscal(str(out_file), "ssp")
761
+ schema_valid = validation["valid"]
762
+
763
+ # Store artifact record
764
+ _store_oscal_artifact(
765
+ conn, project_id, "ssp", str(out_file),
766
+ file_hash, schema_valid, validation.get("errors")
767
+ )
768
+
769
+ # Audit
770
+ _log_audit(conn, project_id, "OSCAL SSP generated", {
771
+ "artifact_type": "ssp",
772
+ "oscal_version": OSCAL_VERSION,
773
+ "uuid": ssp_uuid,
774
+ "controls_count": len(controls),
775
+ "baseline": baseline,
776
+ "file_hash": file_hash,
777
+ "schema_valid": schema_valid,
778
+ "affected_files": [str(out_file)],
779
+ })
780
+
781
+ print("OSCAL SSP generated:")
782
+ print(f" File: {out_file}")
783
+ print(f" UUID: {ssp_uuid}")
784
+ print(f" Controls: {len(controls)}")
785
+ print(f" Baseline: {baseline}")
786
+ print(f" Valid: {schema_valid}")
787
+
788
+ return {
789
+ "file_path": str(out_file),
790
+ "uuid": ssp_uuid,
791
+ "controls_count": len(controls),
792
+ "baseline": baseline,
793
+ "file_hash": file_hash,
794
+ "validation": validation,
795
+ }
796
+
797
+ finally:
798
+ conn.close()
799
+
800
+
801
+ def generate_oscal_poam(project_id, output_dir=None, db_path=None):
802
+ """Generate an OSCAL POA&M JSON artifact.
803
+
804
+ Pulls items from the poam_items table and builds a full OSCAL 1.1.2
805
+ POA&M structure with poam-items, findings, observations, and risks.
806
+
807
+ Args:
808
+ project_id: The project identifier.
809
+ output_dir: Override output directory.
810
+ db_path: Override database path.
811
+
812
+ Returns:
813
+ Dict with file_path, uuid, items_count, and validation result.
814
+ """
815
+ conn = get_connection(db_path=db_path)
816
+ try:
817
+ project = _get_project(conn, project_id)
818
+ poam_items = _get_poam_items(conn, project_id)
819
+
820
+ poam_uuid = _generate_uuid()
821
+ now = _oscal_timestamp()
822
+
823
+ # Build OSCAL poam-items
824
+ oscal_poam_items = []
825
+ observations = []
826
+ risks = []
827
+
828
+ for item in poam_items:
829
+ item_uuid = _generate_uuid()
830
+ obs_uuid = _generate_uuid()
831
+ risk_uuid = _generate_uuid()
832
+
833
+ # Map severity to risk level
834
+ severity = item.get("severity", "moderate")
835
+ risk_level = {
836
+ "critical": "very-high",
837
+ "high": "high",
838
+ "moderate": "moderate",
839
+ "low": "low",
840
+ }.get(severity, "moderate")
841
+
842
+ # Build observation
843
+ observation = {
844
+ "uuid": obs_uuid,
845
+ "title": f"Observation: {item.get('weakness_id', 'Unknown')}",
846
+ "description": item.get("weakness_description", "No description."),
847
+ "methods": ["EXAMINE", "TEST"],
848
+ "collected": item.get("created_at", now),
849
+ }
850
+ if item.get("source"):
851
+ observation["origins"] = [
852
+ {
853
+ "actors": [
854
+ {
855
+ "type": "tool",
856
+ "actor-uuid": _generate_uuid(),
857
+ }
858
+ ],
859
+ }
860
+ ]
861
+ observations.append(observation)
862
+
863
+ # Build risk
864
+ risk = {
865
+ "uuid": risk_uuid,
866
+ "title": f"Risk: {item.get('weakness_id', 'Unknown')}",
867
+ "description": item.get("weakness_description", "No description."),
868
+ "statement": (
869
+ f"Identified weakness {item.get('weakness_id', '')} "
870
+ f"with severity {severity}. "
871
+ f"Source: {item.get('source', 'Assessment')}."
872
+ ),
873
+ "status": _poam_status_to_oscal(item.get("status", "open")),
874
+ "characterizations": [
875
+ {
876
+ "origin": {
877
+ "actors": [
878
+ {
879
+ "type": "tool",
880
+ "actor-uuid": _generate_uuid(),
881
+ }
882
+ ],
883
+ },
884
+ "facets": [
885
+ {
886
+ "name": "risk-level",
887
+ "system": OSCAL_NS,
888
+ "value": risk_level,
889
+ },
890
+ ],
891
+ }
892
+ ],
893
+ }
894
+ if item.get("corrective_action"):
895
+ risk["mitigating-factors"] = [
896
+ {
897
+ "uuid": _generate_uuid(),
898
+ "description": item["corrective_action"],
899
+ }
900
+ ]
901
+ if item.get("milestone_date"):
902
+ risk["remediations"] = [
903
+ {
904
+ "uuid": _generate_uuid(),
905
+ "lifecycle": "planned",
906
+ "title": f"Remediation for {item.get('weakness_id', '')}",
907
+ "description": item.get("corrective_action", "Pending remediation."),
908
+ }
909
+ ]
910
+ risks.append(risk)
911
+
912
+ # Build POA&M item
913
+ poam_entry = {
914
+ "uuid": item_uuid,
915
+ "title": f"POA&M: {item.get('weakness_id', 'Unknown')}",
916
+ "description": item.get("weakness_description", "No description."),
917
+ "related-observations": [
918
+ {"observation-uuid": obs_uuid},
919
+ ],
920
+ "related-risks": [
921
+ {"risk-uuid": risk_uuid},
922
+ ],
923
+ }
924
+
925
+ # Add props
926
+ props = [
927
+ {
928
+ "name": "severity",
929
+ "ns": OSCAL_NS,
930
+ "value": severity,
931
+ },
932
+ ]
933
+ if item.get("status"):
934
+ props.append({
935
+ "name": "status",
936
+ "ns": OSCAL_NS,
937
+ "value": item["status"],
938
+ })
939
+ if item.get("milestone_date"):
940
+ props.append({
941
+ "name": "milestone-date",
942
+ "ns": OSCAL_NS,
943
+ "value": item["milestone_date"],
944
+ })
945
+ if item.get("responsible_party"):
946
+ props.append({
947
+ "name": "responsible-party",
948
+ "ns": OSCAL_NS,
949
+ "value": item["responsible_party"],
950
+ })
951
+ if item.get("control_id"):
952
+ oscal_cid = _control_id_to_oscal(item["control_id"])
953
+ if oscal_cid:
954
+ props.append({
955
+ "name": "related-control",
956
+ "ns": OSCAL_NS,
957
+ "value": oscal_cid,
958
+ })
959
+ poam_entry["props"] = props
960
+
961
+ oscal_poam_items.append(poam_entry)
962
+
963
+ # Assemble full POA&M document
964
+ poam_doc = {
965
+ "plan-of-action-and-milestones": {
966
+ "uuid": poam_uuid,
967
+ "metadata": _build_metadata(
968
+ project, "Plan of Action and Milestones"
969
+ ),
970
+ "import-ssp": {
971
+ "href": "./ssp.oscal.json",
972
+ },
973
+ "observations": observations,
974
+ "risks": risks,
975
+ "poam-items": oscal_poam_items,
976
+ "back-matter": {
977
+ "resources": [],
978
+ },
979
+ },
980
+ }
981
+
982
+ # Write
983
+ out_dir = _resolve_output_dir(project, project_id, output_dir)
984
+ out_file = out_dir / "poam.oscal.json"
985
+
986
+ with open(out_file, "w", encoding="utf-8") as f:
987
+ json.dump(poam_doc, f, indent=2, ensure_ascii=False)
988
+
989
+ file_hash = _compute_file_hash(out_file)
990
+
991
+ # Validate
992
+ validation = validate_oscal(str(out_file), "poam")
993
+ schema_valid = validation["valid"]
994
+
995
+ # Store record
996
+ _store_oscal_artifact(
997
+ conn, project_id, "poam", str(out_file),
998
+ file_hash, schema_valid, validation.get("errors")
999
+ )
1000
+
1001
+ # Audit
1002
+ _log_audit(conn, project_id, "OSCAL POA&M generated", {
1003
+ "artifact_type": "poam",
1004
+ "oscal_version": OSCAL_VERSION,
1005
+ "uuid": poam_uuid,
1006
+ "items_count": len(poam_items),
1007
+ "file_hash": file_hash,
1008
+ "schema_valid": schema_valid,
1009
+ "affected_files": [str(out_file)],
1010
+ })
1011
+
1012
+ print("OSCAL POA&M generated:")
1013
+ print(f" File: {out_file}")
1014
+ print(f" UUID: {poam_uuid}")
1015
+ print(f" Items: {len(poam_items)}")
1016
+ print(f" Valid: {schema_valid}")
1017
+
1018
+ return {
1019
+ "file_path": str(out_file),
1020
+ "uuid": poam_uuid,
1021
+ "items_count": len(poam_items),
1022
+ "file_hash": file_hash,
1023
+ "validation": validation,
1024
+ }
1025
+
1026
+ finally:
1027
+ conn.close()
1028
+
1029
+
1030
+ def _poam_status_to_oscal(status):
1031
+ """Map POAM item status to OSCAL risk status."""
1032
+ mapping = {
1033
+ "open": "open",
1034
+ "in_progress": "investigating",
1035
+ "completed": "closed",
1036
+ "accepted_risk": "deviation-approved",
1037
+ }
1038
+ return mapping.get(status, "open")
1039
+
1040
+
1041
+ def generate_oscal_assessment_results(project_id, output_dir=None, db_path=None):
1042
+ """Generate an OSCAL Assessment Results JSON artifact.
1043
+
1044
+ Pulls findings from fedramp_assessments, cmmc_assessments,
1045
+ stig_findings, cssp_assessments, and sbd_assessments tables.
1046
+ Builds assessment-results with findings, observations, and risks
1047
+ organized per control.
1048
+
1049
+ Args:
1050
+ project_id: The project identifier.
1051
+ output_dir: Override output directory.
1052
+ db_path: Override database path.
1053
+
1054
+ Returns:
1055
+ Dict with file_path, uuid, findings_count, and validation result.
1056
+ """
1057
+ conn = get_connection(db_path=db_path)
1058
+ try:
1059
+ project = _get_project(conn, project_id)
1060
+ all_findings = _get_findings(conn, project_id)
1061
+
1062
+ ar_uuid = _generate_uuid()
1063
+ result_uuid = _generate_uuid()
1064
+ now = _oscal_timestamp()
1065
+
1066
+ observations = []
1067
+ findings = []
1068
+ total_finding_count = 0
1069
+
1070
+ # Process FedRAMP assessments
1071
+ for item in all_findings.get("fedramp", []):
1072
+ obs_uuid = _generate_uuid()
1073
+ finding_uuid = _generate_uuid()
1074
+ total_finding_count += 1
1075
+
1076
+ oscal_cid = _control_id_to_oscal(item.get("control_id", ""))
1077
+ status = _assessment_status_to_oscal(item.get("status", "not_assessed"))
1078
+
1079
+ observations.append({
1080
+ "uuid": obs_uuid,
1081
+ "title": f"FedRAMP: {item.get('control_id', 'Unknown')}",
1082
+ "description": item.get("evidence_description", "No evidence description."),
1083
+ "methods": ["EXAMINE", "INTERVIEW", "TEST"],
1084
+ "collected": item.get("assessment_date", now),
1085
+ "props": [
1086
+ {
1087
+ "name": "framework",
1088
+ "ns": OSCAL_NS,
1089
+ "value": "FedRAMP",
1090
+ },
1091
+ {
1092
+ "name": "baseline",
1093
+ "ns": OSCAL_NS,
1094
+ "value": item.get("baseline", "moderate"),
1095
+ },
1096
+ ],
1097
+ })
1098
+
1099
+ finding_entry = {
1100
+ "uuid": finding_uuid,
1101
+ "title": f"FedRAMP Finding: {item.get('control_id', '')}",
1102
+ "description": (
1103
+ f"FedRAMP {item.get('baseline', 'moderate')} assessment "
1104
+ f"for control {item.get('control_id', '')}."
1105
+ ),
1106
+ "target": {
1107
+ "type": "objective-id",
1108
+ "target-id": oscal_cid or "unknown",
1109
+ "status": {
1110
+ "state": status,
1111
+ },
1112
+ },
1113
+ "related-observations": [
1114
+ {"observation-uuid": obs_uuid},
1115
+ ],
1116
+ }
1117
+ if item.get("notes"):
1118
+ finding_entry["remarks"] = item["notes"]
1119
+ findings.append(finding_entry)
1120
+
1121
+ # Process CMMC assessments
1122
+ for item in all_findings.get("cmmc", []):
1123
+ obs_uuid = _generate_uuid()
1124
+ finding_uuid = _generate_uuid()
1125
+ total_finding_count += 1
1126
+
1127
+ status = _cmmc_status_to_oscal(item.get("status", "not_assessed"))
1128
+
1129
+ observations.append({
1130
+ "uuid": obs_uuid,
1131
+ "title": f"CMMC: {item.get('practice_id', 'Unknown')}",
1132
+ "description": item.get("evidence_description", "No evidence description."),
1133
+ "methods": ["EXAMINE", "TEST"],
1134
+ "collected": item.get("assessment_date", now),
1135
+ "props": [
1136
+ {
1137
+ "name": "framework",
1138
+ "ns": OSCAL_NS,
1139
+ "value": "CMMC",
1140
+ },
1141
+ {
1142
+ "name": "level",
1143
+ "ns": OSCAL_NS,
1144
+ "value": str(item.get("level", 2)),
1145
+ },
1146
+ {
1147
+ "name": "domain",
1148
+ "ns": OSCAL_NS,
1149
+ "value": item.get("domain", ""),
1150
+ },
1151
+ ],
1152
+ })
1153
+
1154
+ findings.append({
1155
+ "uuid": finding_uuid,
1156
+ "title": f"CMMC Finding: {item.get('practice_id', '')}",
1157
+ "description": (
1158
+ f"CMMC Level {item.get('level', 2)} assessment for "
1159
+ f"practice {item.get('practice_id', '')} "
1160
+ f"(domain: {item.get('domain', '')})."
1161
+ ),
1162
+ "target": {
1163
+ "type": "objective-id",
1164
+ "target-id": item.get("practice_id", "unknown").lower(),
1165
+ "status": {
1166
+ "state": status,
1167
+ },
1168
+ },
1169
+ "related-observations": [
1170
+ {"observation-uuid": obs_uuid},
1171
+ ],
1172
+ })
1173
+
1174
+ # Process STIG findings
1175
+ for item in all_findings.get("stig", []):
1176
+ obs_uuid = _generate_uuid()
1177
+ finding_uuid = _generate_uuid()
1178
+ total_finding_count += 1
1179
+
1180
+ status = _stig_status_to_oscal(item.get("status", "Open"))
1181
+
1182
+ observations.append({
1183
+ "uuid": obs_uuid,
1184
+ "title": f"STIG: {item.get('stig_id', '')} - {item.get('finding_id', '')}",
1185
+ "description": item.get("description", item.get("title", "No description.")),
1186
+ "methods": ["TEST"],
1187
+ "collected": item.get("assessed_at", now),
1188
+ "props": [
1189
+ {
1190
+ "name": "framework",
1191
+ "ns": OSCAL_NS,
1192
+ "value": "DISA-STIG",
1193
+ },
1194
+ {
1195
+ "name": "severity",
1196
+ "ns": OSCAL_NS,
1197
+ "value": item.get("severity", "CAT2"),
1198
+ },
1199
+ {
1200
+ "name": "rule-id",
1201
+ "ns": OSCAL_NS,
1202
+ "value": item.get("rule_id", ""),
1203
+ },
1204
+ ],
1205
+ })
1206
+
1207
+ finding_entry = {
1208
+ "uuid": finding_uuid,
1209
+ "title": f"STIG Finding: {item.get('title', '')}",
1210
+ "description": item.get("description", "No description."),
1211
+ "target": {
1212
+ "type": "objective-id",
1213
+ "target-id": item.get("rule_id", "unknown"),
1214
+ "status": {
1215
+ "state": status,
1216
+ },
1217
+ },
1218
+ "related-observations": [
1219
+ {"observation-uuid": obs_uuid},
1220
+ ],
1221
+ }
1222
+ if item.get("comments"):
1223
+ finding_entry["remarks"] = item["comments"]
1224
+ findings.append(finding_entry)
1225
+
1226
+ # Process CSSP assessments
1227
+ for item in all_findings.get("cssp", []):
1228
+ obs_uuid = _generate_uuid()
1229
+ finding_uuid = _generate_uuid()
1230
+ total_finding_count += 1
1231
+
1232
+ status = _assessment_status_to_oscal(item.get("status", "not_assessed"))
1233
+
1234
+ observations.append({
1235
+ "uuid": obs_uuid,
1236
+ "title": f"CSSP: {item.get('requirement_id', 'Unknown')}",
1237
+ "description": item.get("evidence_description", "No evidence description."),
1238
+ "methods": ["EXAMINE"],
1239
+ "collected": item.get("assessment_date", now),
1240
+ "props": [
1241
+ {
1242
+ "name": "framework",
1243
+ "ns": OSCAL_NS,
1244
+ "value": "DoDI-8530.01-CSSP",
1245
+ },
1246
+ {
1247
+ "name": "functional-area",
1248
+ "ns": OSCAL_NS,
1249
+ "value": item.get("functional_area", ""),
1250
+ },
1251
+ ],
1252
+ })
1253
+
1254
+ findings.append({
1255
+ "uuid": finding_uuid,
1256
+ "title": f"CSSP Finding: {item.get('requirement_id', '')}",
1257
+ "description": (
1258
+ f"CSSP assessment for requirement "
1259
+ f"{item.get('requirement_id', '')} "
1260
+ f"(area: {item.get('functional_area', '')})."
1261
+ ),
1262
+ "target": {
1263
+ "type": "objective-id",
1264
+ "target-id": item.get("requirement_id", "unknown").lower(),
1265
+ "status": {
1266
+ "state": status,
1267
+ },
1268
+ },
1269
+ "related-observations": [
1270
+ {"observation-uuid": obs_uuid},
1271
+ ],
1272
+ })
1273
+
1274
+ # Process SbD assessments
1275
+ for item in all_findings.get("sbd", []):
1276
+ obs_uuid = _generate_uuid()
1277
+ finding_uuid = _generate_uuid()
1278
+ total_finding_count += 1
1279
+
1280
+ status = _assessment_status_to_oscal(item.get("status", "not_assessed"))
1281
+
1282
+ observations.append({
1283
+ "uuid": obs_uuid,
1284
+ "title": f"SbD: {item.get('requirement_id', 'Unknown')}",
1285
+ "description": item.get("evidence_description", "No evidence description."),
1286
+ "methods": ["EXAMINE", "TEST"],
1287
+ "collected": item.get("assessment_date", now),
1288
+ "props": [
1289
+ {
1290
+ "name": "framework",
1291
+ "ns": OSCAL_NS,
1292
+ "value": "CISA-SbD",
1293
+ },
1294
+ {
1295
+ "name": "domain",
1296
+ "ns": OSCAL_NS,
1297
+ "value": item.get("domain", ""),
1298
+ },
1299
+ ],
1300
+ })
1301
+
1302
+ findings.append({
1303
+ "uuid": finding_uuid,
1304
+ "title": f"SbD Finding: {item.get('requirement_id', '')}",
1305
+ "description": (
1306
+ f"CISA Secure by Design assessment for requirement "
1307
+ f"{item.get('requirement_id', '')} "
1308
+ f"(domain: {item.get('domain', '')})."
1309
+ ),
1310
+ "target": {
1311
+ "type": "objective-id",
1312
+ "target-id": item.get("requirement_id", "unknown").lower(),
1313
+ "status": {
1314
+ "state": status,
1315
+ },
1316
+ },
1317
+ "related-observations": [
1318
+ {"observation-uuid": obs_uuid},
1319
+ ],
1320
+ })
1321
+
1322
+ # Assemble assessment results document
1323
+ ar_doc = {
1324
+ "assessment-results": {
1325
+ "uuid": ar_uuid,
1326
+ "metadata": _build_metadata(
1327
+ project,
1328
+ "Assessment Results",
1329
+ extra_roles=[
1330
+ {
1331
+ "id": "assessor",
1332
+ "title": "Security Assessor",
1333
+ },
1334
+ ],
1335
+ ),
1336
+ "import-ap": {
1337
+ "href": "#assessment-plan-placeholder",
1338
+ "remarks": (
1339
+ "Assessment plan reference. Replace with actual "
1340
+ "assessment plan OSCAL artifact URI."
1341
+ ),
1342
+ },
1343
+ "results": [
1344
+ {
1345
+ "uuid": result_uuid,
1346
+ "title": f"Assessment Results -- {project.get('name', '')}",
1347
+ "description": (
1348
+ f"Consolidated assessment results across "
1349
+ f"FedRAMP, CMMC, DISA STIG, CSSP, and SbD "
1350
+ f"frameworks for project {project_id}."
1351
+ ),
1352
+ "start": now,
1353
+ "observations": observations,
1354
+ "findings": findings,
1355
+ "props": [
1356
+ {
1357
+ "name": "total-findings",
1358
+ "ns": OSCAL_NS,
1359
+ "value": str(total_finding_count),
1360
+ },
1361
+ {
1362
+ "name": "fedramp-findings",
1363
+ "ns": OSCAL_NS,
1364
+ "value": str(len(all_findings.get("fedramp", []))),
1365
+ },
1366
+ {
1367
+ "name": "cmmc-findings",
1368
+ "ns": OSCAL_NS,
1369
+ "value": str(len(all_findings.get("cmmc", []))),
1370
+ },
1371
+ {
1372
+ "name": "stig-findings",
1373
+ "ns": OSCAL_NS,
1374
+ "value": str(len(all_findings.get("stig", []))),
1375
+ },
1376
+ {
1377
+ "name": "cssp-findings",
1378
+ "ns": OSCAL_NS,
1379
+ "value": str(len(all_findings.get("cssp", []))),
1380
+ },
1381
+ {
1382
+ "name": "sbd-findings",
1383
+ "ns": OSCAL_NS,
1384
+ "value": str(len(all_findings.get("sbd", []))),
1385
+ },
1386
+ ],
1387
+ },
1388
+ ],
1389
+ "back-matter": {
1390
+ "resources": [],
1391
+ },
1392
+ },
1393
+ }
1394
+
1395
+ # Write
1396
+ out_dir = _resolve_output_dir(project, project_id, output_dir)
1397
+ out_file = out_dir / "assessment-results.oscal.json"
1398
+
1399
+ with open(out_file, "w", encoding="utf-8") as f:
1400
+ json.dump(ar_doc, f, indent=2, ensure_ascii=False)
1401
+
1402
+ file_hash = _compute_file_hash(out_file)
1403
+
1404
+ # Validate
1405
+ validation = validate_oscal(str(out_file), "assessment_results")
1406
+ schema_valid = validation["valid"]
1407
+
1408
+ # Store record
1409
+ _store_oscal_artifact(
1410
+ conn, project_id, "assessment_results", str(out_file),
1411
+ file_hash, schema_valid, validation.get("errors")
1412
+ )
1413
+
1414
+ # Audit
1415
+ _log_audit(conn, project_id, "OSCAL Assessment Results generated", {
1416
+ "artifact_type": "assessment_results",
1417
+ "oscal_version": OSCAL_VERSION,
1418
+ "uuid": ar_uuid,
1419
+ "total_findings": total_finding_count,
1420
+ "frameworks": {
1421
+ k: len(v) for k, v in all_findings.items()
1422
+ },
1423
+ "file_hash": file_hash,
1424
+ "schema_valid": schema_valid,
1425
+ "affected_files": [str(out_file)],
1426
+ })
1427
+
1428
+ print("OSCAL Assessment Results generated:")
1429
+ print(f" File: {out_file}")
1430
+ print(f" UUID: {ar_uuid}")
1431
+ print(f" Total findings: {total_finding_count}")
1432
+ for fw, items in all_findings.items():
1433
+ if items:
1434
+ print(f" {fw}: {len(items)}")
1435
+ print(f" Valid: {schema_valid}")
1436
+
1437
+ return {
1438
+ "file_path": str(out_file),
1439
+ "uuid": ar_uuid,
1440
+ "total_findings": total_finding_count,
1441
+ "frameworks": {k: len(v) for k, v in all_findings.items()},
1442
+ "file_hash": file_hash,
1443
+ "validation": validation,
1444
+ }
1445
+
1446
+ finally:
1447
+ conn.close()
1448
+
1449
+
1450
+ def _assessment_status_to_oscal(status):
1451
+ """Map assessment status to OSCAL finding status state."""
1452
+ mapping = {
1453
+ "satisfied": "satisfied",
1454
+ "not_satisfied": "not-satisfied",
1455
+ "other_than_satisfied": "not-satisfied",
1456
+ "partially_satisfied": "not-satisfied",
1457
+ "not_assessed": "not-satisfied",
1458
+ "not_applicable": "satisfied",
1459
+ "risk_accepted": "satisfied",
1460
+ }
1461
+ return mapping.get(status, "not-satisfied")
1462
+
1463
+
1464
+ def _cmmc_status_to_oscal(status):
1465
+ """Map CMMC assessment status to OSCAL finding status state."""
1466
+ mapping = {
1467
+ "met": "satisfied",
1468
+ "not_met": "not-satisfied",
1469
+ "partially_met": "not-satisfied",
1470
+ "not_assessed": "not-satisfied",
1471
+ "not_applicable": "satisfied",
1472
+ }
1473
+ return mapping.get(status, "not-satisfied")
1474
+
1475
+
1476
+ def _stig_status_to_oscal(status):
1477
+ """Map STIG finding status to OSCAL finding status state."""
1478
+ mapping = {
1479
+ "Open": "not-satisfied",
1480
+ "NotAFinding": "satisfied",
1481
+ "Not_Applicable": "satisfied",
1482
+ "Not_Reviewed": "not-satisfied",
1483
+ }
1484
+ return mapping.get(status, "not-satisfied")
1485
+
1486
+
1487
+ def generate_oscal_component_definition(project_id, output_dir=None, db_path=None):
1488
+ """Generate an OSCAL Component Definition JSON artifact.
1489
+
1490
+ Creates a reusable component definition with control-implementations
1491
+ pulled from project_controls and SBOM data.
1492
+
1493
+ Args:
1494
+ project_id: The project identifier.
1495
+ output_dir: Override output directory.
1496
+ db_path: Override database path.
1497
+
1498
+ Returns:
1499
+ Dict with file_path, uuid, components_count, and validation result.
1500
+ """
1501
+ conn = get_connection(db_path=db_path)
1502
+ try:
1503
+ project = _get_project(conn, project_id)
1504
+ controls = _get_controls(conn, project_id)
1505
+ sbom_records = _get_sbom_records(conn, project_id)
1506
+ baseline = _determine_baseline(project)
1507
+
1508
+ cd_uuid = _generate_uuid()
1509
+
1510
+ # Build components list
1511
+ components = []
1512
+
1513
+ # Primary application component
1514
+ app_component_uuid = _generate_uuid()
1515
+ app_component = {
1516
+ "uuid": app_component_uuid,
1517
+ "type": "software",
1518
+ "title": project.get("name", "Application"),
1519
+ "description": project.get("description", "Primary application component."),
1520
+ "props": [
1521
+ {
1522
+ "name": "type",
1523
+ "ns": OSCAL_NS,
1524
+ "value": project.get("type", "webapp"),
1525
+ },
1526
+ {
1527
+ "name": "classification",
1528
+ "ns": OSCAL_NS,
1529
+ "value": project.get("classification", "CUI"),
1530
+ },
1531
+ {
1532
+ "name": "impact-level",
1533
+ "ns": OSCAL_NS,
1534
+ "value": project.get("impact_level", "IL4"),
1535
+ },
1536
+ ],
1537
+ "control-implementations": [],
1538
+ }
1539
+
1540
+ # Build control implementation for this component
1541
+ if controls:
1542
+ profile_href = FEDRAMP_PROFILE_URIS.get(
1543
+ baseline, FEDRAMP_PROFILE_URIS["moderate"]
1544
+ )
1545
+ impl_reqs = []
1546
+ for ctrl in controls:
1547
+ oscal_cid = _control_id_to_oscal(ctrl["control_id"])
1548
+ if not oscal_cid:
1549
+ continue
1550
+
1551
+ description = ctrl.get("implementation_description") or (
1552
+ f"Control {oscal_cid} implementation: "
1553
+ f"{ctrl.get('implementation_status', 'planned')}."
1554
+ )
1555
+
1556
+ impl_reqs.append({
1557
+ "uuid": _generate_uuid(),
1558
+ "control-id": oscal_cid,
1559
+ "description": description,
1560
+ "props": [
1561
+ {
1562
+ "name": "implementation-status",
1563
+ "ns": OSCAL_NS,
1564
+ "value": ctrl.get("implementation_status", "planned"),
1565
+ },
1566
+ ],
1567
+ })
1568
+
1569
+ app_component["control-implementations"].append({
1570
+ "uuid": _generate_uuid(),
1571
+ "source": profile_href,
1572
+ "description": (
1573
+ f"Control implementations for "
1574
+ f"{project.get('name', 'application')} aligned to "
1575
+ f"FedRAMP {baseline.capitalize()} baseline."
1576
+ ),
1577
+ "implemented-requirements": impl_reqs,
1578
+ })
1579
+
1580
+ components.append(app_component)
1581
+
1582
+ # Add tech stack components
1583
+ for stack_key, stack_type in [
1584
+ ("tech_stack_backend", "Backend Framework"),
1585
+ ("tech_stack_frontend", "Frontend Framework"),
1586
+ ("tech_stack_database", "Database"),
1587
+ ]:
1588
+ value = project.get(stack_key)
1589
+ if value:
1590
+ components.append({
1591
+ "uuid": _generate_uuid(),
1592
+ "type": "software",
1593
+ "title": f"{stack_type}: {value}",
1594
+ "description": f"{stack_type} component: {value}",
1595
+ "props": [
1596
+ {
1597
+ "name": "stack-layer",
1598
+ "ns": OSCAL_NS,
1599
+ "value": stack_key.replace("tech_stack_", ""),
1600
+ },
1601
+ ],
1602
+ })
1603
+
1604
+ # Add SBOM-derived components
1605
+ for sbom in sbom_records:
1606
+ components.append({
1607
+ "uuid": _generate_uuid(),
1608
+ "type": "software",
1609
+ "title": f"SBOM: {sbom.get('format', 'cyclonedx')} v{sbom.get('version', '1.0')}",
1610
+ "description": (
1611
+ f"Software Bill of Materials ({sbom.get('format', 'CycloneDX')}) "
1612
+ f"with {sbom.get('component_count', 0)} components, "
1613
+ f"{sbom.get('vulnerability_count', 0)} known vulnerabilities."
1614
+ ),
1615
+ "props": [
1616
+ {
1617
+ "name": "sbom-format",
1618
+ "ns": OSCAL_NS,
1619
+ "value": sbom.get("format", "cyclonedx"),
1620
+ },
1621
+ {
1622
+ "name": "component-count",
1623
+ "ns": OSCAL_NS,
1624
+ "value": str(sbom.get("component_count", 0)),
1625
+ },
1626
+ {
1627
+ "name": "vulnerability-count",
1628
+ "ns": OSCAL_NS,
1629
+ "value": str(sbom.get("vulnerability_count", 0)),
1630
+ },
1631
+ ],
1632
+ })
1633
+
1634
+ # Assemble component definition document
1635
+ cd_doc = {
1636
+ "component-definition": {
1637
+ "uuid": cd_uuid,
1638
+ "metadata": _build_metadata(
1639
+ project, "Component Definition"
1640
+ ),
1641
+ "components": components,
1642
+ "back-matter": {
1643
+ "resources": [],
1644
+ },
1645
+ },
1646
+ }
1647
+
1648
+ # Write
1649
+ out_dir = _resolve_output_dir(project, project_id, output_dir)
1650
+ out_file = out_dir / "component-definition.oscal.json"
1651
+
1652
+ with open(out_file, "w", encoding="utf-8") as f:
1653
+ json.dump(cd_doc, f, indent=2, ensure_ascii=False)
1654
+
1655
+ file_hash = _compute_file_hash(out_file)
1656
+
1657
+ # Validate
1658
+ validation = validate_oscal(str(out_file), "component_definition")
1659
+ schema_valid = validation["valid"]
1660
+
1661
+ # Store record
1662
+ _store_oscal_artifact(
1663
+ conn, project_id, "component_definition", str(out_file),
1664
+ file_hash, schema_valid, validation.get("errors")
1665
+ )
1666
+
1667
+ # Audit
1668
+ _log_audit(conn, project_id, "OSCAL Component Definition generated", {
1669
+ "artifact_type": "component_definition",
1670
+ "oscal_version": OSCAL_VERSION,
1671
+ "uuid": cd_uuid,
1672
+ "components_count": len(components),
1673
+ "controls_count": len(controls),
1674
+ "sbom_records": len(sbom_records),
1675
+ "file_hash": file_hash,
1676
+ "schema_valid": schema_valid,
1677
+ "affected_files": [str(out_file)],
1678
+ })
1679
+
1680
+ print("OSCAL Component Definition generated:")
1681
+ print(f" File: {out_file}")
1682
+ print(f" UUID: {cd_uuid}")
1683
+ print(f" Components: {len(components)}")
1684
+ print(f" Controls: {len(controls)}")
1685
+ print(f" Valid: {schema_valid}")
1686
+
1687
+ return {
1688
+ "file_path": str(out_file),
1689
+ "uuid": cd_uuid,
1690
+ "components_count": len(components),
1691
+ "controls_count": len(controls),
1692
+ "file_hash": file_hash,
1693
+ "validation": validation,
1694
+ }
1695
+
1696
+ finally:
1697
+ conn.close()
1698
+
1699
+
1700
+ # ---------------------------------------------------------------------------
1701
+ # Validation
1702
+ # ---------------------------------------------------------------------------
1703
+
1704
+ def validate_oscal(file_path, artifact_type=None):
1705
+ """Validate an OSCAL JSON file for structural correctness.
1706
+
1707
+ Checks:
1708
+ - Valid JSON
1709
+ - Required top-level keys per artifact type
1710
+ - UUID format (RFC 4122 lowercase)
1711
+ - ISO 8601 timestamp format
1712
+ - Control ID format (lowercase with hyphens)
1713
+
1714
+ Args:
1715
+ file_path: Path to the OSCAL JSON file.
1716
+ artifact_type: One of ssp, poam, assessment_results,
1717
+ component_definition. If None, auto-detects.
1718
+
1719
+ Returns:
1720
+ Dict with valid (bool) and errors (list of strings).
1721
+ """
1722
+ errors = []
1723
+ path = Path(file_path)
1724
+
1725
+ # Check file exists
1726
+ if not path.exists():
1727
+ return {"valid": False, "errors": [f"File not found: {file_path}"]}
1728
+
1729
+ # Parse JSON
1730
+ try:
1731
+ with open(path, "r", encoding="utf-8") as f:
1732
+ data = json.load(f)
1733
+ except json.JSONDecodeError as e:
1734
+ return {"valid": False, "errors": [f"Invalid JSON: {e}"]}
1735
+
1736
+ if not isinstance(data, dict):
1737
+ return {"valid": False, "errors": ["Root must be a JSON object."]}
1738
+
1739
+ # Determine artifact type from top-level key
1740
+ top_level_keys = {
1741
+ "ssp": "system-security-plan",
1742
+ "poam": "plan-of-action-and-milestones",
1743
+ "assessment_results": "assessment-results",
1744
+ "component_definition": "component-definition",
1745
+ }
1746
+
1747
+ if artifact_type is None:
1748
+ # Auto-detect
1749
+ for at, key in top_level_keys.items():
1750
+ if key in data:
1751
+ artifact_type = at
1752
+ break
1753
+ if artifact_type is None:
1754
+ return {
1755
+ "valid": False,
1756
+ "errors": [
1757
+ f"No recognized OSCAL top-level key found. "
1758
+ f"Expected one of: {list(top_level_keys.values())}"
1759
+ ],
1760
+ }
1761
+
1762
+ expected_key = top_level_keys.get(artifact_type)
1763
+ if expected_key and expected_key not in data:
1764
+ errors.append(
1765
+ f"Missing required top-level key: '{expected_key}'"
1766
+ )
1767
+
1768
+ if expected_key and expected_key in data:
1769
+ doc = data[expected_key]
1770
+
1771
+ # Check UUID at document level
1772
+ if "uuid" in doc:
1773
+ if not UUID_PATTERN.match(str(doc["uuid"])):
1774
+ errors.append(
1775
+ f"Document UUID format invalid: '{doc['uuid']}'. "
1776
+ f"Expected RFC 4122 lowercase UUID."
1777
+ )
1778
+
1779
+ # Check metadata
1780
+ metadata = doc.get("metadata", {})
1781
+ if not metadata:
1782
+ errors.append("Missing 'metadata' block.")
1783
+ else:
1784
+ # Check last-modified timestamp
1785
+ last_mod = metadata.get("last-modified", "")
1786
+ if last_mod and not ISO_TIMESTAMP_PATTERN.match(last_mod):
1787
+ errors.append(
1788
+ f"Metadata 'last-modified' timestamp format invalid: "
1789
+ f"'{last_mod}'. Expected ISO 8601 with Z suffix."
1790
+ )
1791
+
1792
+ # Check oscal-version
1793
+ oscal_ver = metadata.get("oscal-version", "")
1794
+ if oscal_ver and oscal_ver != OSCAL_VERSION:
1795
+ errors.append(
1796
+ f"OSCAL version mismatch: '{oscal_ver}' "
1797
+ f"(expected '{OSCAL_VERSION}')."
1798
+ )
1799
+
1800
+ # Check required metadata fields
1801
+ for field in ["title", "last-modified", "version", "oscal-version"]:
1802
+ if field not in metadata:
1803
+ errors.append(f"Missing metadata field: '{field}'.")
1804
+
1805
+ # Artifact-specific validation
1806
+ if artifact_type == "ssp":
1807
+ _validate_ssp(doc, errors)
1808
+ elif artifact_type == "poam":
1809
+ _validate_poam(doc, errors)
1810
+ elif artifact_type == "assessment_results":
1811
+ _validate_assessment_results(doc, errors)
1812
+ elif artifact_type == "component_definition":
1813
+ _validate_component_definition(doc, errors)
1814
+
1815
+ # Walk entire document for UUID and control-id validation
1816
+ _validate_uuids_recursive(data, errors, max_errors=20)
1817
+ _validate_control_ids_recursive(data, errors, max_errors=20)
1818
+
1819
+ return {
1820
+ "valid": len(errors) == 0,
1821
+ "errors": errors,
1822
+ }
1823
+
1824
+
1825
+ def _validate_ssp(doc, errors):
1826
+ """Validate SSP-specific structure."""
1827
+ if "import-profile" not in doc:
1828
+ errors.append("SSP missing 'import-profile' block.")
1829
+ elif "href" not in doc.get("import-profile", {}):
1830
+ errors.append("SSP 'import-profile' missing 'href'.")
1831
+
1832
+ if "system-characteristics" not in doc:
1833
+ errors.append("SSP missing 'system-characteristics' block.")
1834
+ else:
1835
+ sc = doc["system-characteristics"]
1836
+ for field in [
1837
+ "system-name", "description", "security-sensitivity-level",
1838
+ "security-impact-level", "status", "authorization-boundary",
1839
+ ]:
1840
+ if field not in sc:
1841
+ errors.append(
1842
+ f"SSP 'system-characteristics' missing '{field}'."
1843
+ )
1844
+
1845
+ if "system-implementation" not in doc:
1846
+ errors.append("SSP missing 'system-implementation' block.")
1847
+
1848
+ if "control-implementation" not in doc:
1849
+ errors.append("SSP missing 'control-implementation' block.")
1850
+ else:
1851
+ ci = doc["control-implementation"]
1852
+ if "implemented-requirements" not in ci:
1853
+ errors.append(
1854
+ "SSP 'control-implementation' missing "
1855
+ "'implemented-requirements'."
1856
+ )
1857
+
1858
+
1859
+ def _validate_poam(doc, errors):
1860
+ """Validate POA&M-specific structure."""
1861
+ if "poam-items" not in doc:
1862
+ errors.append("POA&M missing 'poam-items' array.")
1863
+ elif not isinstance(doc["poam-items"], list):
1864
+ errors.append("POA&M 'poam-items' must be an array.")
1865
+
1866
+
1867
+ def _validate_assessment_results(doc, errors):
1868
+ """Validate Assessment Results-specific structure."""
1869
+ if "results" not in doc:
1870
+ errors.append("Assessment Results missing 'results' array.")
1871
+ elif not isinstance(doc["results"], list):
1872
+ errors.append("Assessment Results 'results' must be an array.")
1873
+ elif len(doc["results"]) == 0:
1874
+ errors.append("Assessment Results 'results' array is empty.")
1875
+
1876
+
1877
+ def _validate_component_definition(doc, errors):
1878
+ """Validate Component Definition-specific structure."""
1879
+ if "components" not in doc:
1880
+ errors.append("Component Definition missing 'components' array.")
1881
+ elif not isinstance(doc["components"], list):
1882
+ errors.append("Component Definition 'components' must be an array.")
1883
+ elif len(doc["components"]) == 0:
1884
+ errors.append("Component Definition 'components' array is empty.")
1885
+
1886
+
1887
+ def _validate_uuids_recursive(obj, errors, path="", max_errors=20):
1888
+ """Recursively validate UUID fields in the document."""
1889
+ if len(errors) >= max_errors:
1890
+ return
1891
+
1892
+ if isinstance(obj, dict):
1893
+ for key, value in obj.items():
1894
+ current_path = f"{path}.{key}" if path else key
1895
+ if key == "uuid" and isinstance(value, str):
1896
+ if not UUID_PATTERN.match(value):
1897
+ errors.append(
1898
+ f"Invalid UUID at '{current_path}': '{value}'."
1899
+ )
1900
+ if len(errors) >= max_errors:
1901
+ return
1902
+ elif key.endswith("-uuid") and isinstance(value, str):
1903
+ if not UUID_PATTERN.match(value):
1904
+ errors.append(
1905
+ f"Invalid UUID reference at '{current_path}': "
1906
+ f"'{value}'."
1907
+ )
1908
+ if len(errors) >= max_errors:
1909
+ return
1910
+ else:
1911
+ _validate_uuids_recursive(
1912
+ value, errors, current_path, max_errors
1913
+ )
1914
+ elif isinstance(obj, list):
1915
+ for i, item in enumerate(obj):
1916
+ _validate_uuids_recursive(
1917
+ item, errors, f"{path}[{i}]", max_errors
1918
+ )
1919
+
1920
+
1921
+ def _validate_control_ids_recursive(obj, errors, path="", max_errors=20):
1922
+ """Recursively validate control-id fields use OSCAL lowercase format."""
1923
+ if len(errors) >= max_errors:
1924
+ return
1925
+
1926
+ if isinstance(obj, dict):
1927
+ for key, value in obj.items():
1928
+ current_path = f"{path}.{key}" if path else key
1929
+ if key == "control-id" and isinstance(value, str):
1930
+ if value != value.lower():
1931
+ errors.append(
1932
+ f"Control ID not lowercase at '{current_path}': "
1933
+ f"'{value}'. OSCAL requires lowercase."
1934
+ )
1935
+ if len(errors) >= max_errors:
1936
+ return
1937
+ else:
1938
+ _validate_control_ids_recursive(
1939
+ value, errors, current_path, max_errors
1940
+ )
1941
+ elif isinstance(obj, list):
1942
+ for i, item in enumerate(obj):
1943
+ _validate_control_ids_recursive(
1944
+ item, errors, f"{path}[{i}]", max_errors
1945
+ )
1946
+
1947
+
1948
+ # ---------------------------------------------------------------------------
1949
+ # Aggregate generation
1950
+ # ---------------------------------------------------------------------------
1951
+
1952
+ def generate_all_oscal(project_id, output_dir=None, db_path=None):
1953
+ """Generate all four OSCAL artifact types for a project.
1954
+
1955
+ Generates SSP, POA&M, Assessment Results, and Component Definition
1956
+ in sequence. Returns a summary dict.
1957
+
1958
+ Args:
1959
+ project_id: The project identifier.
1960
+ output_dir: Override output directory.
1961
+ db_path: Override database path.
1962
+
1963
+ Returns:
1964
+ Dict with results for each artifact type and overall summary.
1965
+ """
1966
+ results = {}
1967
+ artifact_types = [
1968
+ ("ssp", generate_oscal_ssp),
1969
+ ("poam", generate_oscal_poam),
1970
+ ("assessment_results", generate_oscal_assessment_results),
1971
+ ("component_definition", generate_oscal_component_definition),
1972
+ ]
1973
+
1974
+ success_count = 0
1975
+ failure_count = 0
1976
+
1977
+ for artifact_name, generator_fn in artifact_types:
1978
+ try:
1979
+ result = generator_fn(
1980
+ project_id, output_dir=output_dir, db_path=db_path
1981
+ )
1982
+ results[artifact_name] = {
1983
+ "status": "success",
1984
+ "result": result,
1985
+ }
1986
+ success_count += 1
1987
+ except Exception as e:
1988
+ results[artifact_name] = {
1989
+ "status": "error",
1990
+ "error": str(e),
1991
+ }
1992
+ failure_count += 1
1993
+ print(
1994
+ f"Error generating OSCAL {artifact_name}: {e}",
1995
+ file=sys.stderr,
1996
+ )
1997
+
1998
+ summary = {
1999
+ "project_id": project_id,
2000
+ "oscal_version": OSCAL_VERSION,
2001
+ "artifacts_generated": success_count,
2002
+ "artifacts_failed": failure_count,
2003
+ "total": len(artifact_types),
2004
+ "results": results,
2005
+ }
2006
+
2007
+ print("\nOSCAL generation summary:")
2008
+ print(f" Project: {project_id}")
2009
+ print(f" OSCAL Version: {OSCAL_VERSION}")
2010
+ print(f" Generated: {success_count}/{len(artifact_types)}")
2011
+ if failure_count > 0:
2012
+ print(f" Failed: {failure_count}")
2013
+ for name, res in results.items():
2014
+ if res["status"] == "error":
2015
+ print(f" {name}: {res['error']}")
2016
+
2017
+ return summary
2018
+
2019
+
2020
+ # ---------------------------------------------------------------------------
2021
+ # CLI entrypoint
2022
+ # ---------------------------------------------------------------------------
2023
+
2024
+ def main():
2025
+ parser = argparse.ArgumentParser(
2026
+ description=(
2027
+ "NIST OSCAL 1.1.2 Artifact Generator -- "
2028
+ "Generate SSP, POA&M, Assessment Results, and "
2029
+ "Component Definition in OSCAL JSON format."
2030
+ ),
2031
+ )
2032
+ parser.add_argument(
2033
+ "--project-id",
2034
+ required=False,
2035
+ help="Project ID (required for generation)",
2036
+ )
2037
+ parser.add_argument(
2038
+ "--artifact",
2039
+ choices=[
2040
+ "ssp", "poam", "assessment_results",
2041
+ "component_definition", "all",
2042
+ ],
2043
+ default="all",
2044
+ help="Artifact type to generate (default: all)",
2045
+ )
2046
+ parser.add_argument(
2047
+ "--output-dir",
2048
+ help="Output directory for OSCAL artifacts",
2049
+ )
2050
+ parser.add_argument(
2051
+ "--format",
2052
+ choices=["json"],
2053
+ default="json",
2054
+ help="Output format (JSON; XML/YAML available with oscal-cli via oscal_tools.py --convert)",
2055
+ )
2056
+ parser.add_argument(
2057
+ "--validate",
2058
+ help="Validate an existing OSCAL JSON file (no project-id required)",
2059
+ )
2060
+ parser.add_argument(
2061
+ "--deep-validate",
2062
+ help="Deep validate an OSCAL file (structural + pydantic + Metaschema via oscal_tools.py)",
2063
+ )
2064
+ parser.add_argument(
2065
+ "--catalog-source",
2066
+ choices=["official", "sparkpilot", "auto"],
2067
+ default="auto",
2068
+ help="Catalog source: official (NIST OSCAL), icdev (custom 39-control), auto (try official first)",
2069
+ )
2070
+ parser.add_argument(
2071
+ "--json",
2072
+ action="store_true",
2073
+ help="Output results as JSON",
2074
+ )
2075
+ parser.add_argument(
2076
+ "--db-path",
2077
+ type=Path,
2078
+ help="Override database path",
2079
+ )
2080
+
2081
+ args = parser.parse_args()
2082
+
2083
+ # Validation-only mode (structural)
2084
+ if args.validate:
2085
+ result = validate_oscal(args.validate)
2086
+ if args.json:
2087
+ print(json.dumps(result, indent=2))
2088
+ else:
2089
+ if result["valid"]:
2090
+ print(f"VALID: {args.validate}")
2091
+ else:
2092
+ print(f"INVALID: {args.validate}")
2093
+ for err in result["errors"]:
2094
+ print(f" - {err}")
2095
+ sys.exit(0 if result["valid"] else 1)
2096
+
2097
+ # Deep validation mode (structural + pydantic + Metaschema, D302-D305)
2098
+ if args.deep_validate:
2099
+ try:
2100
+ from tools.compliance.oscal_tools import validate_oscal_deep
2101
+ result = validate_oscal_deep(
2102
+ args.deep_validate,
2103
+ project_id=args.project_id,
2104
+ db_path=str(args.db_path) if args.db_path else None,
2105
+ )
2106
+ except ImportError:
2107
+ result = validate_oscal(args.deep_validate)
2108
+ result["note"] = "oscal_tools not available; ran structural validation only"
2109
+ if args.json:
2110
+ print(json.dumps(result, indent=2, default=str))
2111
+ else:
2112
+ valid = result.get("overall_valid", result.get("valid", False))
2113
+ print(f"{'VALID' if valid else 'INVALID'}: {args.deep_validate}")
2114
+ for layer_name, layer_result in result.get("layers", {}).items():
2115
+ status = "PASS" if layer_result.get("valid") else ("SKIP" if layer_result.get("skipped") else "FAIL")
2116
+ print(f" [{status}] {layer_name}")
2117
+ sys.exit(0 if result.get("overall_valid", result.get("valid", False)) else 1)
2118
+
2119
+ # Generation mode requires project-id
2120
+ if not args.project_id:
2121
+ parser.error("--project-id is required for artifact generation")
2122
+
2123
+ # Dispatch to generator
2124
+ generators = {
2125
+ "ssp": generate_oscal_ssp,
2126
+ "poam": generate_oscal_poam,
2127
+ "assessment_results": generate_oscal_assessment_results,
2128
+ "component_definition": generate_oscal_component_definition,
2129
+ "all": generate_all_oscal,
2130
+ }
2131
+
2132
+ generator_fn = generators[args.artifact]
2133
+
2134
+ try:
2135
+ result = generator_fn(
2136
+ project_id=args.project_id,
2137
+ output_dir=args.output_dir,
2138
+ db_path=args.db_path,
2139
+ )
2140
+
2141
+ if args.json:
2142
+ print(json.dumps(result, indent=2, default=str))
2143
+
2144
+ except (FileNotFoundError, ValueError) as e:
2145
+ print(f"ERROR: {e}", file=sys.stderr)
2146
+ sys.exit(1)
2147
+ except Exception as e:
2148
+ print(f"ERROR: Unexpected error: {e}", file=sys.stderr)
2149
+ sys.exit(1)
2150
+
2151
+
2152
+ if __name__ == "__main__":
2153
+ main()
2154
+
2155
+ ####################################################################
2156
+ # CUI // SP-CTI | Department of Defense
2157
+ ####################################################################