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,1182 @@
1
+ # [TEMPLATE: CUI // SP-CTI]
2
+ """OSCAL ecosystem integration — oscal-cli, oscal-pydantic, NIST OSCAL Content.
3
+
4
+ Composes three independently optional external tools behind a unified interface:
5
+ 1. oscal-cli (NIST, public domain) — Metaschema validation, profile resolution,
6
+ format conversion (JSON/XML/YAML). Requires Java 11+.
7
+ 2. oscal-pydantic (MIT) — Pydantic model validation for OSCAL artifacts
8
+ (v1/v2 compatible via 3-strategy cascade: native → v1_compat → builtin_v2).
9
+ 3. NIST OSCAL Content (public domain) — Authoritative 800-53 Rev 5 catalog.
10
+
11
+ All three degrade gracefully when absent (air-gap safe, D134 compatible).
12
+
13
+ Architecture Decisions: D302 (oscal-cli subprocess), D303 (pydantic layer),
14
+ D304 (catalog adapter), D305 (single orchestrator), D306 (validation log).
15
+
16
+ Usage:
17
+ python tools/compliance/oscal_tools.py --detect --json
18
+ python tools/compliance/oscal_tools.py --validate /path/ssp.oscal.json --json
19
+ python tools/compliance/oscal_tools.py --convert /path/ssp.json --format xml --json
20
+ python tools/compliance/oscal_tools.py --resolve-profile /path/profile.json --json
21
+ python tools/compliance/oscal_tools.py --catalog-lookup AC-2 --json
22
+ python tools/compliance/oscal_tools.py --catalog-list --family AC --json
23
+ python tools/compliance/oscal_tools.py --catalog-stats --json
24
+ """
25
+
26
+ import argparse
27
+ import json
28
+ import logging
29
+ import os
30
+ import shutil
31
+ import sqlite3
32
+ import subprocess
33
+ import sys
34
+ import time
35
+ from datetime import datetime, timezone
36
+ from pathlib import Path
37
+ from tools.db.storage import get_connection
38
+ DB_PATH = None # Storage layer handles path resolution (D-DB-20)
39
+
40
+ logger = logging.getLogger(__name__)
41
+
42
+ BASE_DIR = Path(__file__).resolve().parent.parent.parent
43
+ CONFIG_PATH = BASE_DIR / "args" / "oscal_tools_config.yaml"
44
+
45
+ # ---------------------------------------------------------------------------
46
+ # Cached detection results (D302)
47
+ # ---------------------------------------------------------------------------
48
+ _JAVA_INFO = None # {"available": bool, "version": str, "path": str}
49
+ _OSCAL_CLI_INFO = None # {"available": bool, "version": str, "jar_path": str}
50
+ _PYDANTIC_INFO = None # {"available": bool, "version": str}
51
+
52
+ # OSCAL JSON key → internal artifact type mapping (shared across validators)
53
+ _OSCAL_TYPE_MAP = {
54
+ "system-security-plan": "ssp",
55
+ "plan-of-action-and-milestones": "poam",
56
+ "assessment-results": "assessment_results",
57
+ "component-definition": "component_definition",
58
+ }
59
+ _OSCAL_JSON_KEY = {v: k for k, v in _OSCAL_TYPE_MAP.items()}
60
+
61
+ # oscal-pydantic module/class mapping
62
+ _OSCAL_PYDANTIC_MAP = {
63
+ "ssp": ("oscal_pydantic.ssp", "SystemSecurityPlan"),
64
+ "poam": ("oscal_pydantic.poam", "PlanOfActionAndMilestones"),
65
+ "assessment_results": ("oscal_pydantic.assessment_results", "AssessmentResults"),
66
+ "component_definition": ("oscal_pydantic.component_definition", "ComponentDefinition"),
67
+ }
68
+
69
+ # Model class cache: {artifact_type: (model_cls, compat_mode, is_document_model)}
70
+ _OSCAL_MODEL_CACHE = {}
71
+
72
+
73
+ def _get_pydantic_version():
74
+ """Return installed pydantic major version (0 if not installed)."""
75
+ try:
76
+ import pydantic
77
+ return int(pydantic.VERSION.split(".")[0])
78
+ except Exception:
79
+ return 0
80
+
81
+
82
+ def _load_config():
83
+ """Load oscal_tools_config.yaml. Returns dict or defaults."""
84
+ try:
85
+ import yaml
86
+ if CONFIG_PATH.exists():
87
+ with open(CONFIG_PATH, "r", encoding="utf-8") as f:
88
+ return yaml.safe_load(f) or {}
89
+ except ImportError:
90
+ pass
91
+ return {}
92
+
93
+
94
+ # ---------------------------------------------------------------------------
95
+ # Tool Detection (D302-D304)
96
+ # ---------------------------------------------------------------------------
97
+
98
+ def _detect_java():
99
+ """Detect Java Runtime availability and version."""
100
+ global _JAVA_INFO
101
+ if _JAVA_INFO is not None:
102
+ return _JAVA_INFO
103
+
104
+ config = _load_config()
105
+ java_cmd = config.get("oscal_cli", {}).get("java_cmd", "java")
106
+
107
+ # Check JAVA_HOME first
108
+ java_home = os.environ.get("JAVA_HOME")
109
+ if java_home:
110
+ candidate = Path(java_home) / "bin" / "java"
111
+ if candidate.exists():
112
+ java_cmd = str(candidate)
113
+ elif (candidate.parent / "java.exe").exists():
114
+ java_cmd = str(candidate.parent / "java.exe")
115
+
116
+ try:
117
+ proc = subprocess.run(
118
+ [java_cmd, "-version"],
119
+ capture_output=True, text=True, timeout=10,
120
+ stdin=subprocess.DEVNULL,
121
+ )
122
+ # Java outputs version to stderr
123
+ output = proc.stderr or proc.stdout or ""
124
+ # Extract version like "11.0.20" or "17.0.8"
125
+ import re
126
+ match = re.search(r'"?(\d+)[\._](\d+)', output)
127
+ version = match.group(0).strip('"') if match else "unknown"
128
+ major = int(match.group(1)) if match else 0
129
+
130
+ _JAVA_INFO = {
131
+ "available": major >= 11,
132
+ "version": version,
133
+ "path": shutil.which(java_cmd) or java_cmd,
134
+ "error": None if major >= 11 else f"Java {major} found, need 11+",
135
+ }
136
+ except (FileNotFoundError, subprocess.TimeoutExpired, OSError) as exc:
137
+ _JAVA_INFO = {"available": False, "version": None, "path": None, "error": str(exc)}
138
+
139
+ return _JAVA_INFO
140
+
141
+
142
+ def _cli_env(java_info=None):
143
+ """Build subprocess environment with JAVACMD set for wrapper scripts."""
144
+ env = os.environ.copy()
145
+ if java_info is None:
146
+ java_info = _detect_java()
147
+ java_path = java_info.get("path")
148
+ if java_path:
149
+ env["JAVACMD"] = java_path
150
+ # Also ensure JAVA_HOME is set for scripts that use it
151
+ java_bin = Path(java_path).parent
152
+ if java_bin.name == "bin":
153
+ env["JAVA_HOME"] = str(java_bin.parent)
154
+ return env
155
+
156
+
157
+ def _find_oscal_cli():
158
+ """Find oscal-cli executable or JAR.
159
+
160
+ Returns:
161
+ Tuple of (path, mode) where mode is 'wrapper' or 'jar', or (None, None).
162
+ """
163
+ # 1. Environment variable
164
+ env_path = os.environ.get("OSCAL_CLI_PATH")
165
+ if env_path and Path(env_path).exists():
166
+ p = Path(env_path)
167
+ if p.suffix == ".jar":
168
+ return str(p), "jar"
169
+ return str(p), "wrapper"
170
+
171
+ config = _load_config()
172
+
173
+ # 2. Vendor directory — standard distribution (bin/oscal-cli or bin/oscal-cli.bat)
174
+ vendor_dir = BASE_DIR / "vendor" / "oscal-cli"
175
+ if vendor_dir.exists():
176
+ if os.name == "nt":
177
+ # On Windows, prefer .bat (subprocess.run can't execute Unix shell scripts)
178
+ bat = vendor_dir / "bin" / "oscal-cli.bat"
179
+ if bat.exists():
180
+ return str(bat), "wrapper"
181
+ else:
182
+ sh = vendor_dir / "bin" / "oscal-cli"
183
+ if sh.exists():
184
+ return str(sh), "wrapper"
185
+ # Fallback: single fat JAR
186
+ jar_rel = config.get("oscal_cli", {}).get("jar_path", "vendor/oscal-cli/oscal-cli.jar")
187
+ jar_path = BASE_DIR / jar_rel
188
+ if jar_path.exists():
189
+ return str(jar_path), "jar"
190
+
191
+ # 3. oscal-cli on system PATH
192
+ on_path = shutil.which("oscal-cli")
193
+ if on_path:
194
+ return on_path, "wrapper"
195
+
196
+ return None, None
197
+
198
+
199
+ def _detect_oscal_cli():
200
+ """Detect oscal-cli availability."""
201
+ global _OSCAL_CLI_INFO
202
+ if _OSCAL_CLI_INFO is not None:
203
+ return _OSCAL_CLI_INFO
204
+
205
+ java = _detect_java()
206
+ cli_path, cli_mode = _find_oscal_cli()
207
+
208
+ if not java["available"]:
209
+ _OSCAL_CLI_INFO = {
210
+ "available": False, "version": None, "jar_path": cli_path,
211
+ "mode": cli_mode,
212
+ "error": f"Java not available: {java.get('error', 'not found')}",
213
+ }
214
+ elif not cli_path:
215
+ _OSCAL_CLI_INFO = {
216
+ "available": False, "version": None, "jar_path": None,
217
+ "mode": None,
218
+ "error": "oscal-cli not found (set OSCAL_CLI_PATH or place in vendor/oscal-cli/)",
219
+ }
220
+ else:
221
+ # Try to get version
222
+ version = None
223
+ try:
224
+ env = _cli_env(java)
225
+ if cli_mode == "wrapper":
226
+ cmd = [cli_path, "--version"]
227
+ else:
228
+ config = _load_config()
229
+ java_cmd = java.get("path", "java")
230
+ jvm_args = config.get("oscal_cli", {}).get("jvm_args", ["-Xmx512m"])
231
+ cmd = [java_cmd] + jvm_args + ["-jar", cli_path, "--version"]
232
+ proc = subprocess.run(
233
+ cmd, capture_output=True, text=True, timeout=15,
234
+ stdin=subprocess.DEVNULL, env=env,
235
+ )
236
+ version = (proc.stdout or proc.stderr or "").strip()
237
+ except Exception:
238
+ version = "unknown"
239
+
240
+ _OSCAL_CLI_INFO = {
241
+ "available": True, "version": version, "jar_path": cli_path,
242
+ "mode": cli_mode, "error": None,
243
+ }
244
+
245
+ return _OSCAL_CLI_INFO
246
+
247
+
248
+ def _detect_oscal_pydantic():
249
+ """Detect OSCAL Pydantic validation capability.
250
+
251
+ Reports availability based on three possible sources:
252
+ - oscal-pydantic package with compatible pydantic version (native)
253
+ - oscal-pydantic package with pydantic v2 (v1_compat or builtin fallback)
254
+ - Built-in v2 models when pydantic >= 2 (no oscal-pydantic needed)
255
+ """
256
+ global _PYDANTIC_INFO
257
+ if _PYDANTIC_INFO is not None:
258
+ return _PYDANTIC_INFO
259
+
260
+ pv = _get_pydantic_version()
261
+ oscal_pkg = None
262
+ try:
263
+ import importlib.metadata
264
+ oscal_pkg = importlib.metadata.version("oscal-pydantic")
265
+ except Exception:
266
+ pass
267
+
268
+ if oscal_pkg and pv >= 2:
269
+ # oscal-pydantic installed + pydantic v2 → v1_compat or builtin fallback
270
+ _PYDANTIC_INFO = {
271
+ "available": True, "version": oscal_pkg,
272
+ "pydantic_version": pv, "compat_mode": "v1_compat_or_builtin_v2",
273
+ "error": None,
274
+ }
275
+ elif oscal_pkg and pv >= 1:
276
+ # oscal-pydantic + pydantic v1 → native
277
+ _PYDANTIC_INFO = {
278
+ "available": True, "version": oscal_pkg,
279
+ "pydantic_version": pv, "compat_mode": "native",
280
+ "error": None,
281
+ }
282
+ elif pv >= 2:
283
+ # No oscal-pydantic but pydantic v2 → builtin models
284
+ _PYDANTIC_INFO = {
285
+ "available": True, "version": f"builtin_v2 (pydantic {pv})",
286
+ "pydantic_version": pv, "compat_mode": "builtin_v2",
287
+ "error": None,
288
+ }
289
+ else:
290
+ _PYDANTIC_INFO = {
291
+ "available": pv > 0, "version": None,
292
+ "pydantic_version": pv, "compat_mode": None,
293
+ "error": ("pydantic not installed" if pv == 0
294
+ else "oscal-pydantic not installed (pip install oscal-pydantic)"),
295
+ }
296
+
297
+ return _PYDANTIC_INFO
298
+
299
+
300
+ def _detect_nist_catalog():
301
+ """Detect whether official NIST OSCAL catalog is present."""
302
+ config = _load_config()
303
+ sources = config.get("nist_catalog", {}).get("catalog_sources", [])
304
+ if not sources:
305
+ sources = [
306
+ "context/oscal/NIST_SP-800-53_rev5_catalog.json",
307
+ "context/compliance/nist_800_53.json",
308
+ ]
309
+
310
+ for src in sources:
311
+ path = BASE_DIR / src
312
+ if path.exists():
313
+ try:
314
+ with open(path, "r", encoding="utf-8") as f:
315
+ data = json.load(f)
316
+ is_official = "catalog" in data
317
+ count = 0
318
+ if is_official:
319
+ for g in data.get("catalog", {}).get("groups", []):
320
+ count += len(g.get("controls", []))
321
+ for c in g.get("controls", []):
322
+ count += len(c.get("controls", []))
323
+ else:
324
+ count = len(data.get("controls", []))
325
+
326
+ return {
327
+ "available": True,
328
+ "path": str(path),
329
+ "format": "nist_oscal" if is_official else "icdev_custom",
330
+ "controls_count": count,
331
+ "error": None,
332
+ }
333
+ except Exception as exc:
334
+ return {"available": False, "path": str(path), "error": str(exc)}
335
+
336
+ return {"available": False, "path": None, "error": "No catalog file found"}
337
+
338
+
339
+ def detect_oscal_tools():
340
+ """Detect which OSCAL ecosystem tools are available.
341
+
342
+ Returns:
343
+ Dict with detection results for each tool.
344
+ """
345
+ return {
346
+ "oscal_cli": _detect_oscal_cli(),
347
+ "java": _detect_java(),
348
+ "oscal_pydantic": _detect_oscal_pydantic(),
349
+ "nist_catalog": _detect_nist_catalog(),
350
+ }
351
+
352
+
353
+ # ---------------------------------------------------------------------------
354
+ # oscal-cli subprocess wrapper (D302)
355
+ # ---------------------------------------------------------------------------
356
+
357
+ def _run_oscal_cli(subcommand, cli_args, timeout=None):
358
+ """Run oscal-cli via subprocess.
359
+
360
+ Args:
361
+ subcommand: e.g., "ssp validate", "ssp convert", "profile resolve"
362
+ cli_args: List of additional CLI arguments.
363
+ timeout: Seconds (default from config).
364
+
365
+ Returns:
366
+ Dict with stdout, stderr, returncode, success.
367
+ """
368
+ cli_info = _detect_oscal_cli()
369
+ if not cli_info["available"]:
370
+ return {"error": cli_info["error"], "available": False}
371
+
372
+ config = _load_config()
373
+ if timeout is None:
374
+ timeout = config.get("oscal_cli", {}).get("timeout", 120)
375
+
376
+ mode = cli_info.get("mode", "jar")
377
+ if mode == "wrapper":
378
+ cmd = [cli_info["jar_path"]]
379
+ else:
380
+ java_info = _detect_java()
381
+ java_cmd = java_info.get("path", "java")
382
+ jvm_args = config.get("oscal_cli", {}).get("jvm_args", ["-Xmx512m"])
383
+ cmd = [java_cmd] + jvm_args + ["-jar", cli_info["jar_path"]]
384
+ cmd.extend(subcommand.split())
385
+ if cli_args:
386
+ cmd.extend(cli_args)
387
+
388
+ try:
389
+ env = _cli_env()
390
+ proc = subprocess.run(
391
+ cmd, capture_output=True, text=True, timeout=timeout,
392
+ cwd=str(BASE_DIR), stdin=subprocess.DEVNULL, env=env,
393
+ )
394
+ return {
395
+ "success": proc.returncode == 0,
396
+ "returncode": proc.returncode,
397
+ "stdout": proc.stdout,
398
+ "stderr": proc.stderr,
399
+ }
400
+ except subprocess.TimeoutExpired:
401
+ return {"error": f"oscal-cli timed out after {timeout}s", "success": False}
402
+ except Exception as exc:
403
+ return {"error": str(exc), "success": False}
404
+
405
+
406
+ # ---------------------------------------------------------------------------
407
+ # Multi-layer Validation (D302, D303, D306)
408
+ # ---------------------------------------------------------------------------
409
+
410
+ def _validate_structural(file_path, artifact_type=None):
411
+ """Layer 1: ICDEV built-in structural validation (always available)."""
412
+ start = time.monotonic()
413
+ try:
414
+ from tools.compliance.oscal_generator import validate_oscal
415
+ result = validate_oscal(file_path, artifact_type)
416
+ except ImportError:
417
+ result = {"valid": False, "errors": ["oscal_generator not available"]}
418
+
419
+ elapsed = int((time.monotonic() - start) * 1000)
420
+ return {
421
+ "validator": "icdev_structural",
422
+ "valid": result.get("valid", False),
423
+ "errors": result.get("errors", []),
424
+ "duration_ms": elapsed,
425
+ }
426
+
427
+
428
+ def _import_via_v1_compat(module_name, class_name):
429
+ """Import oscal-pydantic model under pydantic v1 compatibility namespace.
430
+
431
+ Pydantic v2 ships ``pydantic.v1`` for backward compatibility. This
432
+ temporarily redirects ``sys.modules["pydantic"]`` so oscal-pydantic's
433
+ v1-style models (``__root__``, ``class Config``, ``regex=`` in Field)
434
+ can load without modification.
435
+
436
+ Note: NOT thread-safe — suitable for CLI/subprocess execution only.
437
+ """
438
+ import importlib
439
+ import warnings
440
+
441
+ try:
442
+ with warnings.catch_warnings():
443
+ warnings.simplefilter("ignore")
444
+ import pydantic.v1 as pydantic_v1 # noqa: F401
445
+ except ImportError:
446
+ return None
447
+
448
+ # Save current pydantic modules
449
+ saved_pydantic = {}
450
+ for key in list(sys.modules.keys()):
451
+ if key == "pydantic" or key.startswith("pydantic."):
452
+ saved_pydantic[key] = sys.modules.pop(key)
453
+
454
+ # Remove cached oscal_pydantic submodules so they re-import under v1
455
+ for key in list(sys.modules.keys()):
456
+ if key.startswith("oscal_pydantic."):
457
+ del sys.modules[key]
458
+
459
+ try:
460
+ # Install v1 compat as 'pydantic'
461
+ sys.modules["pydantic"] = pydantic_v1
462
+ with warnings.catch_warnings():
463
+ warnings.simplefilter("ignore")
464
+ mod = importlib.import_module(module_name)
465
+ return getattr(mod, class_name, None)
466
+ except Exception:
467
+ return None
468
+ finally:
469
+ # Restore pydantic v2 modules
470
+ for key in list(sys.modules.keys()):
471
+ if key == "pydantic" or key.startswith("pydantic."):
472
+ if key not in saved_pydantic:
473
+ del sys.modules[key]
474
+ sys.modules.update(saved_pydantic)
475
+
476
+
477
+ def _get_builtin_v2_model(artifact_type):
478
+ """Create lightweight Pydantic v2 OSCAL document model.
479
+
480
+ Validates required OSCAL document structure (UUID, metadata, required
481
+ sections) without the full schema depth of oscal-pydantic (~154 classes).
482
+ Used as fallback when oscal-pydantic models are not v2-compatible.
483
+
484
+ Returns a *document-level* model (wraps the full JSON, including the
485
+ top-level ``system-security-plan`` / ``plan-of-action-and-milestones``
486
+ key), unlike oscal-pydantic which provides content-level models.
487
+ """
488
+ try:
489
+ from pydantic import BaseModel as PydanticBaseModel
490
+ from pydantic import ConfigDict, Field
491
+ except ImportError:
492
+ return None
493
+
494
+ class _Metadata(PydanticBaseModel):
495
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
496
+ title: str
497
+ last_modified: str = Field(alias="last-modified")
498
+ version: str
499
+ oscal_version: str = Field(alias="oscal-version")
500
+
501
+ if artifact_type == "ssp":
502
+ class _SSP(PydanticBaseModel):
503
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
504
+ uuid: str
505
+ metadata: _Metadata
506
+ import_profile: dict = Field(alias="import-profile")
507
+ system_characteristics: dict = Field(alias="system-characteristics")
508
+ system_implementation: dict = Field(alias="system-implementation")
509
+ control_implementation: dict = Field(alias="control-implementation")
510
+
511
+ class _Doc(PydanticBaseModel):
512
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
513
+ system_security_plan: _SSP = Field(alias="system-security-plan")
514
+ return _Doc
515
+
516
+ elif artifact_type == "poam":
517
+ class _POAM(PydanticBaseModel):
518
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
519
+ uuid: str
520
+ metadata: _Metadata
521
+
522
+ class _Doc(PydanticBaseModel):
523
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
524
+ poam: _POAM = Field(alias="plan-of-action-and-milestones")
525
+ return _Doc
526
+
527
+ elif artifact_type == "assessment_results":
528
+ class _AR(PydanticBaseModel):
529
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
530
+ uuid: str
531
+ metadata: _Metadata
532
+
533
+ class _Doc(PydanticBaseModel):
534
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
535
+ assessment_results: _AR = Field(alias="assessment-results")
536
+ return _Doc
537
+
538
+ elif artifact_type == "component_definition":
539
+ class _CD(PydanticBaseModel):
540
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
541
+ uuid: str
542
+ metadata: _Metadata
543
+
544
+ class _Doc(PydanticBaseModel):
545
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
546
+ component_definition: _CD = Field(alias="component-definition")
547
+ return _Doc
548
+
549
+ return None
550
+
551
+
552
+ def _load_oscal_model(artifact_type):
553
+ """Load OSCAL pydantic model class via cascading strategies.
554
+
555
+ Strategies (in order):
556
+ 1. Direct import of oscal-pydantic (native v2 or v1 + pydantic v1)
557
+ 2. Import via pydantic.v1 compat namespace (v1 package under pydantic v2)
558
+ 3. Built-in lightweight Pydantic v2 models (always works with pydantic >= 2)
559
+
560
+ Returns:
561
+ Tuple of (model_class, compat_mode, is_document_model).
562
+ compat_mode: ``"native"`` | ``"v1_compat"`` | ``"builtin_v2"`` | ``None``
563
+ is_document_model: True if model wraps the full JSON document.
564
+ """
565
+ if artifact_type in _OSCAL_MODEL_CACHE:
566
+ return _OSCAL_MODEL_CACHE[artifact_type]
567
+
568
+ mapping = _OSCAL_PYDANTIC_MAP.get(artifact_type)
569
+ if not mapping:
570
+ result = (None, None, False)
571
+ _OSCAL_MODEL_CACHE[artifact_type] = result
572
+ return result
573
+
574
+ module_name, class_name = mapping
575
+
576
+ # Strategy 1: Direct import of oscal-pydantic
577
+ try:
578
+ import importlib
579
+ import warnings
580
+ with warnings.catch_warnings():
581
+ warnings.simplefilter("ignore")
582
+ mod = importlib.import_module(module_name)
583
+ cls = getattr(mod, class_name, None)
584
+ if cls:
585
+ result = (cls, "native", False)
586
+ _OSCAL_MODEL_CACHE[artifact_type] = result
587
+ return result
588
+ except (ImportError, TypeError):
589
+ # Clean up partial imports from failed attempt
590
+ if module_name in sys.modules:
591
+ del sys.modules[module_name]
592
+
593
+ # Strategy 2: pydantic.v1 compat shim
594
+ if _get_pydantic_version() >= 2:
595
+ cls = _import_via_v1_compat(module_name, class_name)
596
+ if cls:
597
+ result = (cls, "v1_compat", False)
598
+ _OSCAL_MODEL_CACHE[artifact_type] = result
599
+ return result
600
+
601
+ # Strategy 3: Built-in v2 models
602
+ if _get_pydantic_version() >= 2:
603
+ cls = _get_builtin_v2_model(artifact_type)
604
+ if cls:
605
+ result = (cls, "builtin_v2", True)
606
+ _OSCAL_MODEL_CACHE[artifact_type] = result
607
+ return result
608
+
609
+ result = (None, None, False)
610
+ _OSCAL_MODEL_CACHE[artifact_type] = result
611
+ return result
612
+
613
+
614
+ def _validate_pydantic(file_path, artifact_type=None):
615
+ """Layer 2: Pydantic model validation (optional, D303).
616
+
617
+ Uses cascading strategy to load models:
618
+ 1. Native oscal-pydantic import (v2-compatible or v1 + pydantic v1)
619
+ 2. pydantic.v1 compat namespace (v1 package under pydantic v2)
620
+ 3. Built-in lightweight Pydantic v2 OSCAL models
621
+
622
+ Skipped only when pydantic is not installed at all.
623
+ """
624
+ pv = _get_pydantic_version()
625
+ if pv == 0:
626
+ return {"validator": "oscal_pydantic", "skipped": True,
627
+ "reason": "pydantic not installed"}
628
+
629
+ start = time.monotonic()
630
+ errors = []
631
+ compat_mode = None
632
+
633
+ try:
634
+ with open(file_path, "r", encoding="utf-8") as f:
635
+ data = json.load(f)
636
+
637
+ # Auto-detect artifact type from JSON keys
638
+ if artifact_type is None:
639
+ for key, at in _OSCAL_TYPE_MAP.items():
640
+ if key in data:
641
+ artifact_type = at
642
+ break
643
+
644
+ if artifact_type is None:
645
+ errors.append("Cannot determine OSCAL artifact type for pydantic validation")
646
+ else:
647
+ model_cls, compat_mode, is_document = _load_oscal_model(artifact_type)
648
+
649
+ if model_cls is None:
650
+ errors.append(
651
+ f"No pydantic model available for artifact type: {artifact_type}")
652
+ else:
653
+ # For content models (oscal-pydantic), extract inner object;
654
+ # for document models (builtin_v2), pass the full JSON.
655
+ validate_data = data
656
+ if not is_document:
657
+ json_key = _OSCAL_JSON_KEY.get(artifact_type)
658
+ if json_key and json_key in data:
659
+ validate_data = data[json_key]
660
+
661
+ # Validate using the appropriate API (v2: model_validate, v1: parse_obj)
662
+ if hasattr(model_cls, "model_validate"):
663
+ model_cls.model_validate(validate_data)
664
+ elif hasattr(model_cls, "parse_obj"):
665
+ model_cls.parse_obj(validate_data)
666
+ else:
667
+ model_cls(**validate_data)
668
+
669
+ except (json.JSONDecodeError, OSError) as exc:
670
+ errors.append(f"File read error: {exc}")
671
+ except Exception as exc:
672
+ errors.append(f"Pydantic validation error: {exc}")
673
+
674
+ elapsed = int((time.monotonic() - start) * 1000)
675
+ info = _detect_oscal_pydantic()
676
+ result = {
677
+ "validator": "oscal_pydantic",
678
+ "valid": len(errors) == 0,
679
+ "errors": errors,
680
+ "duration_ms": elapsed,
681
+ }
682
+ if compat_mode:
683
+ result["compat_mode"] = compat_mode
684
+ if info.get("version"):
685
+ result["version"] = info["version"]
686
+ return result
687
+
688
+
689
+ def _validate_metaschema(file_path, artifact_type=None):
690
+ """Layer 3: oscal-cli Metaschema validation (optional, D302)."""
691
+ cli_info = _detect_oscal_cli()
692
+ if not cli_info["available"]:
693
+ return {"validator": "oscal_cli_metaschema", "skipped": True, "reason": cli_info["error"]}
694
+
695
+ start = time.monotonic()
696
+
697
+ # Map artifact type to oscal-cli subcommand
698
+ subcmd_map = {
699
+ "ssp": "ssp",
700
+ "poam": "poam",
701
+ "assessment_results": "assessment-results",
702
+ "component_definition": "component-definition",
703
+ }
704
+
705
+ # Auto-detect from file content if needed
706
+ if artifact_type is None:
707
+ try:
708
+ with open(file_path, "r", encoding="utf-8") as f:
709
+ data = json.load(f)
710
+ for key, at in {"system-security-plan": "ssp", "plan-of-action-and-milestones": "poam",
711
+ "assessment-results": "assessment_results",
712
+ "component-definition": "component_definition"}.items():
713
+ if key in data:
714
+ artifact_type = at
715
+ break
716
+ except Exception:
717
+ pass
718
+
719
+ subcmd = subcmd_map.get(artifact_type, "ssp")
720
+ result = _run_oscal_cli(f"{subcmd} validate", [str(file_path)])
721
+
722
+ elapsed = int((time.monotonic() - start) * 1000)
723
+
724
+ if "error" in result and not result.get("success", True):
725
+ errors = [result["error"]]
726
+ elif not result.get("success", True):
727
+ # Parse validation errors from stderr
728
+ raw = result.get("stderr", "") or result.get("stdout", "")
729
+ errors = [line.strip() for line in raw.splitlines() if line.strip()]
730
+ else:
731
+ errors = []
732
+
733
+ return {
734
+ "validator": "oscal_cli_metaschema",
735
+ "valid": result.get("success", False),
736
+ "errors": errors,
737
+ "duration_ms": elapsed,
738
+ "version": cli_info.get("version"),
739
+ }
740
+
741
+
742
+ def _log_validation(project_id, artifact_type, file_path, validator_result, db_path=None):
743
+ """Record validation attempt in oscal_validation_log (D306, append-only)."""
744
+ if db_path is None:
745
+ db_path = DB_PATH
746
+ db_path = Path(db_path)
747
+ if not db_path.exists():
748
+ return
749
+
750
+ try:
751
+ conn = sqlite3.connect(str(db_path))
752
+ conn.execute(
753
+ """INSERT INTO oscal_validation_log
754
+ (project_id, artifact_type, file_path, validator, valid,
755
+ error_count, errors, duration_ms, created_at)
756
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)""",
757
+ (
758
+ project_id,
759
+ artifact_type,
760
+ str(file_path),
761
+ validator_result.get("validator", "unknown"),
762
+ 1 if validator_result.get("valid") else 0,
763
+ len(validator_result.get("errors", [])),
764
+ json.dumps(validator_result.get("errors", [])),
765
+ validator_result.get("duration_ms", 0),
766
+ datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"),
767
+ ),
768
+ )
769
+ conn.commit()
770
+ conn.close()
771
+ except Exception as exc:
772
+ logger.debug("Failed to log validation: %s", exc)
773
+
774
+
775
+ def validate_oscal_deep(file_path, artifact_type=None, validators=None,
776
+ project_id=None, db_path=None):
777
+ """Multi-layer OSCAL validation pipeline (D305).
778
+
779
+ Runs up to 3 validation layers in order:
780
+ 1. ICDEV structural (always)
781
+ 2. oscal-pydantic model (if installed)
782
+ 3. oscal-cli Metaschema (if installed + Java present)
783
+
784
+ Each layer is independent — skipped layers are reported as such.
785
+
786
+ Args:
787
+ file_path: Path to OSCAL file to validate.
788
+ artifact_type: ssp|poam|assessment_results|component_definition (auto-detected).
789
+ validators: List of specific validators to run. Default: all available.
790
+ project_id: Optional project ID for audit logging.
791
+ db_path: Override database path.
792
+
793
+ Returns:
794
+ Dict with overall valid status, per-validator results, and aggregated errors.
795
+ """
796
+ file_path = str(Path(file_path))
797
+ results = []
798
+ all_errors = []
799
+
800
+ pipeline = validators or ["icdev_structural", "oscal_pydantic", "oscal_cli_metaschema"]
801
+
802
+ dispatch = {
803
+ "icdev_structural": lambda: _validate_structural(file_path, artifact_type),
804
+ "oscal_pydantic": lambda: _validate_pydantic(file_path, artifact_type),
805
+ "oscal_cli_metaschema": lambda: _validate_metaschema(file_path, artifact_type),
806
+ }
807
+
808
+ for layer in pipeline:
809
+ if layer in dispatch:
810
+ result = dispatch[layer]()
811
+ results.append(result)
812
+
813
+ if not result.get("skipped", False):
814
+ _log_validation(project_id, artifact_type, file_path, result, db_path)
815
+ all_errors.extend(result.get("errors", []))
816
+
817
+ # Overall: valid only if all non-skipped layers pass
818
+ active_results = [r for r in results if not r.get("skipped", False)]
819
+ overall_valid = all(r.get("valid", False) for r in active_results) if active_results else False
820
+
821
+ return {
822
+ "valid": overall_valid,
823
+ "errors": all_errors,
824
+ "error_count": len(all_errors),
825
+ "validators": results,
826
+ "validators_run": len(active_results),
827
+ "validators_skipped": len(results) - len(active_results),
828
+ "file_path": file_path,
829
+ "artifact_type": artifact_type,
830
+ }
831
+
832
+
833
+ # ---------------------------------------------------------------------------
834
+ # Format Conversion (D302)
835
+ # ---------------------------------------------------------------------------
836
+
837
+ def convert_oscal_format(input_path, output_format, output_path=None):
838
+ """Convert OSCAL artifact between JSON, XML, and YAML.
839
+
840
+ Requires oscal-cli + Java. Returns error if unavailable.
841
+
842
+ Args:
843
+ input_path: Path to source OSCAL file.
844
+ output_format: Target format — "json", "xml", or "yaml".
845
+ output_path: Optional output path. Auto-generated if omitted.
846
+
847
+ Returns:
848
+ Dict with output_path on success, or error.
849
+ """
850
+ input_path = Path(input_path)
851
+ if not input_path.exists():
852
+ return {"error": f"File not found: {input_path}", "success": False}
853
+
854
+ if output_format not in ("json", "xml", "yaml"):
855
+ return {"error": f"Unsupported format: {output_format}", "success": False}
856
+
857
+ if output_path is None:
858
+ output_path = input_path.with_suffix(f".{output_format}")
859
+ output_path = Path(output_path)
860
+
861
+ # Auto-detect artifact type from file content
862
+ subcmd = "ssp"
863
+ try:
864
+ with open(input_path, "r", encoding="utf-8") as f:
865
+ data = json.load(f)
866
+ for key, cmd in {"system-security-plan": "ssp",
867
+ "plan-of-action-and-milestones": "poam",
868
+ "assessment-results": "assessment-results",
869
+ "component-definition": "component-definition"}.items():
870
+ if key in data:
871
+ subcmd = cmd
872
+ break
873
+ except Exception:
874
+ pass
875
+
876
+ result = _run_oscal_cli(
877
+ f"{subcmd} convert",
878
+ ["--to", output_format, str(input_path), str(output_path)],
879
+ )
880
+
881
+ if result.get("error") and not result.get("success", True):
882
+ return {"error": result["error"], "success": False}
883
+
884
+ if result.get("success"):
885
+ return {
886
+ "success": True,
887
+ "input_path": str(input_path),
888
+ "output_path": str(output_path),
889
+ "output_format": output_format,
890
+ }
891
+
892
+ return {
893
+ "success": False,
894
+ "error": result.get("stderr", "Unknown conversion error"),
895
+ }
896
+
897
+
898
+ # ---------------------------------------------------------------------------
899
+ # Profile Resolution (D302)
900
+ # ---------------------------------------------------------------------------
901
+
902
+ def resolve_oscal_profile(profile_path, output_path=None):
903
+ """Flatten an OSCAL Profile into a resolved Catalog.
904
+
905
+ Requires oscal-cli + Java. Returns error if unavailable.
906
+
907
+ Args:
908
+ profile_path: Path to OSCAL Profile file.
909
+ output_path: Optional output path for resolved catalog.
910
+
911
+ Returns:
912
+ Dict with output_path on success, or error.
913
+ """
914
+ profile_path = Path(profile_path)
915
+ if not profile_path.exists():
916
+ return {"error": f"Profile not found: {profile_path}", "success": False}
917
+
918
+ if output_path is None:
919
+ output_path = profile_path.with_name(
920
+ profile_path.stem + "-resolved" + profile_path.suffix
921
+ )
922
+ output_path = Path(output_path)
923
+
924
+ result = _run_oscal_cli(
925
+ "profile resolve",
926
+ [str(profile_path), str(output_path)],
927
+ )
928
+
929
+ if result.get("error") and not result.get("success", True):
930
+ return {"error": result["error"], "success": False}
931
+
932
+ if result.get("success"):
933
+ return {
934
+ "success": True,
935
+ "profile_path": str(profile_path),
936
+ "output_path": str(output_path),
937
+ }
938
+
939
+ return {
940
+ "success": False,
941
+ "error": result.get("stderr", "Unknown resolution error"),
942
+ }
943
+
944
+
945
+ # ---------------------------------------------------------------------------
946
+ # Catalog Operations (D304)
947
+ # ---------------------------------------------------------------------------
948
+
949
+ def catalog_lookup(control_id, catalog_source="auto", catalog_path=None):
950
+ """Look up a control from the NIST catalog.
951
+
952
+ Args:
953
+ control_id: Control ID (e.g., "AC-2").
954
+ catalog_source: "auto" (official first), "official", or "sparkpilot".
955
+ catalog_path: Direct path to a catalog file (overrides catalog_source).
956
+
957
+ Returns:
958
+ Control dict or error dict.
959
+ """
960
+ from tools.compliance.oscal_catalog_adapter import OscalCatalogAdapter
961
+
962
+ if catalog_path:
963
+ adapter = OscalCatalogAdapter(catalog_path=catalog_path)
964
+ else:
965
+ sources = None
966
+ if catalog_source == "official":
967
+ sources = [str(BASE_DIR / "context" / "oscal" / "NIST_SP-800-53_rev5_catalog.json")]
968
+ elif catalog_source == "sparkpilot":
969
+ sources = [str(BASE_DIR / "context" / "compliance" / "nist_800_53.json")]
970
+ adapter = OscalCatalogAdapter(catalog_sources=sources)
971
+
972
+ ctrl = adapter.get_control(control_id)
973
+
974
+ if ctrl:
975
+ return ctrl
976
+ return {"error": f"Control '{control_id}' not found", "catalog_source": catalog_source}
977
+
978
+
979
+ def catalog_list(family=None, catalog_source="auto", catalog_path=None):
980
+ """List controls from the NIST catalog.
981
+
982
+ Args:
983
+ family: Optional family filter (e.g., "AC").
984
+ catalog_source: "auto", "official", or "sparkpilot".
985
+ catalog_path: Direct path to a catalog file (overrides catalog_source).
986
+
987
+ Returns:
988
+ Dict with controls list and count.
989
+ """
990
+ from tools.compliance.oscal_catalog_adapter import OscalCatalogAdapter
991
+
992
+ if catalog_path:
993
+ adapter = OscalCatalogAdapter(catalog_path=catalog_path)
994
+ else:
995
+ sources = None
996
+ if catalog_source == "official":
997
+ sources = [str(BASE_DIR / "context" / "oscal" / "NIST_SP-800-53_rev5_catalog.json")]
998
+ elif catalog_source == "sparkpilot":
999
+ sources = [str(BASE_DIR / "context" / "compliance" / "nist_800_53.json")]
1000
+ adapter = OscalCatalogAdapter(catalog_sources=sources)
1001
+ controls = adapter.list_controls(family=family)
1002
+
1003
+ return {
1004
+ "controls": controls,
1005
+ "count": len(controls),
1006
+ "catalog_stats": adapter.get_catalog_stats(),
1007
+ }
1008
+
1009
+
1010
+ def catalog_stats(catalog_source="auto", catalog_path=None):
1011
+ """Get catalog statistics.
1012
+
1013
+ Args:
1014
+ catalog_source: "auto", "official", or "sparkpilot".
1015
+ catalog_path: Direct path to a catalog file (overrides catalog_source).
1016
+
1017
+ Returns:
1018
+ Dict with catalog metadata and counts.
1019
+ """
1020
+ from tools.compliance.oscal_catalog_adapter import OscalCatalogAdapter
1021
+
1022
+ if catalog_path:
1023
+ adapter = OscalCatalogAdapter(catalog_path=catalog_path)
1024
+ else:
1025
+ sources = None
1026
+ if catalog_source == "official":
1027
+ sources = [str(BASE_DIR / "context" / "oscal" / "NIST_SP-800-53_rev5_catalog.json")]
1028
+ elif catalog_source == "sparkpilot":
1029
+ sources = [str(BASE_DIR / "context" / "compliance" / "nist_800_53.json")]
1030
+ adapter = OscalCatalogAdapter(catalog_sources=sources)
1031
+ return adapter.get_catalog_stats()
1032
+
1033
+
1034
+ # ---------------------------------------------------------------------------
1035
+ # CLI Entry Point
1036
+ # ---------------------------------------------------------------------------
1037
+
1038
+ def main():
1039
+ """CLI entry point for OSCAL ecosystem tools."""
1040
+ parser = argparse.ArgumentParser(
1041
+ description="OSCAL Ecosystem Tools — validation, conversion, catalog (D302-D306)"
1042
+ )
1043
+ group = parser.add_mutually_exclusive_group()
1044
+ group.add_argument("--detect", action="store_true",
1045
+ help="Detect available OSCAL ecosystem tools")
1046
+ group.add_argument("--validate", metavar="FILE",
1047
+ help="Deep-validate an OSCAL artifact (multi-layer pipeline)")
1048
+ group.add_argument("--convert", metavar="FILE",
1049
+ help="Convert OSCAL artifact to another format")
1050
+ group.add_argument("--resolve-profile", metavar="FILE",
1051
+ help="Resolve OSCAL Profile into flattened Catalog")
1052
+ group.add_argument("--catalog-lookup", metavar="CONTROL_ID",
1053
+ help="Look up a control by ID (e.g., AC-2)")
1054
+ group.add_argument("--catalog-list", action="store_true",
1055
+ help="List catalog controls")
1056
+ group.add_argument("--catalog-stats", action="store_true",
1057
+ help="Show catalog statistics")
1058
+
1059
+ parser.add_argument("--format", choices=["json", "xml", "yaml"],
1060
+ help="Output format for --convert")
1061
+ parser.add_argument("--output", help="Output file path")
1062
+ parser.add_argument("--artifact-type",
1063
+ choices=["ssp", "poam", "assessment_results", "component_definition"],
1064
+ help="OSCAL artifact type (auto-detected if omitted)")
1065
+ parser.add_argument("--catalog-source", choices=["auto", "official", "sparkpilot"],
1066
+ default="auto", help="Catalog source preference")
1067
+ parser.add_argument("--family", help="Filter by control family (e.g., AC)")
1068
+ parser.add_argument("--project-id", help="Project ID for audit logging")
1069
+ parser.add_argument("--db-path", help="Override database path")
1070
+ parser.add_argument("--json", action="store_true", help="JSON output")
1071
+ parser.add_argument("--human", action="store_true", help="Human-readable output")
1072
+ args = parser.parse_args()
1073
+
1074
+ if args.detect:
1075
+ result = detect_oscal_tools()
1076
+ if args.json:
1077
+ print(json.dumps(result, indent=2))
1078
+ else:
1079
+ for tool, info in result.items():
1080
+ avail = "AVAILABLE" if info.get("available") else "NOT AVAILABLE"
1081
+ ver = info.get("version", "")
1082
+ err = info.get("error", "")
1083
+ print(f" {tool:20s} {avail:15s} {ver or ''}")
1084
+ if err:
1085
+ print(f" {'':20s} {err}")
1086
+ sys.exit(0)
1087
+
1088
+ if args.validate:
1089
+ result = validate_oscal_deep(
1090
+ args.validate, artifact_type=args.artifact_type,
1091
+ project_id=args.project_id, db_path=args.db_path,
1092
+ )
1093
+ if args.json:
1094
+ print(json.dumps(result, indent=2))
1095
+ else:
1096
+ status = "VALID" if result["valid"] else "INVALID"
1097
+ print(f"{status}: {args.validate}")
1098
+ print(f" Validators run: {result['validators_run']}, "
1099
+ f"skipped: {result['validators_skipped']}")
1100
+ for v in result["validators"]:
1101
+ name = v["validator"]
1102
+ if v.get("skipped"):
1103
+ print(f" [{name}] SKIPPED — {v.get('reason', '')}")
1104
+ else:
1105
+ s = "PASS" if v.get("valid") else "FAIL"
1106
+ print(f" [{name}] {s} ({v.get('duration_ms', 0)}ms)")
1107
+ for err in v.get("errors", [])[:5]:
1108
+ print(f" - {err}")
1109
+ if result["errors"]:
1110
+ print(f"\n{result['error_count']} total error(s)")
1111
+ sys.exit(0 if result["valid"] else 1)
1112
+
1113
+ if args.convert:
1114
+ if not args.format:
1115
+ parser.error("--format is required with --convert")
1116
+ result = convert_oscal_format(args.convert, args.format, args.output)
1117
+ if args.json:
1118
+ print(json.dumps(result, indent=2))
1119
+ else:
1120
+ if result.get("success"):
1121
+ print(f"Converted: {result['output_path']}")
1122
+ else:
1123
+ print(f"ERROR: {result.get('error', 'unknown')}")
1124
+ sys.exit(0 if result.get("success") else 1)
1125
+
1126
+ if args.resolve_profile:
1127
+ result = resolve_oscal_profile(args.resolve_profile, args.output)
1128
+ if args.json:
1129
+ print(json.dumps(result, indent=2))
1130
+ else:
1131
+ if result.get("success"):
1132
+ print(f"Resolved: {result['output_path']}")
1133
+ else:
1134
+ print(f"ERROR: {result.get('error', 'unknown')}")
1135
+ sys.exit(0 if result.get("success") else 1)
1136
+
1137
+ if args.catalog_lookup:
1138
+ result = catalog_lookup(args.catalog_lookup, args.catalog_source)
1139
+ if args.json:
1140
+ print(json.dumps(result, indent=2))
1141
+ else:
1142
+ if "error" in result:
1143
+ print(result["error"])
1144
+ else:
1145
+ print(f"{result['id']}: {result['title']}")
1146
+ print(f" Family: {result['family']}")
1147
+ desc = result.get("description", "")
1148
+ print(f" Description: {desc[:200]}{'...' if len(desc) > 200 else ''}")
1149
+ if result.get("params"):
1150
+ print(f" Parameters: {len(result['params'])}")
1151
+ sys.exit(0 if "error" not in result else 1)
1152
+
1153
+ if args.catalog_list:
1154
+ result = catalog_list(family=args.family, catalog_source=args.catalog_source)
1155
+ if args.json:
1156
+ print(json.dumps(result, indent=2))
1157
+ else:
1158
+ for ctrl in result["controls"]:
1159
+ enh = " (enhancement)" if ctrl.get("is_enhancement") else ""
1160
+ wd = " [WITHDRAWN]" if ctrl.get("withdrawn") else ""
1161
+ print(f" {ctrl['id']}: {ctrl['title']}{enh}{wd}")
1162
+ print(f"\n{result['count']} controls")
1163
+ sys.exit(0)
1164
+
1165
+ if args.catalog_stats:
1166
+ result = catalog_stats(catalog_source=args.catalog_source)
1167
+ if args.json:
1168
+ print(json.dumps(result, indent=2))
1169
+ else:
1170
+ print(f"Source: {result.get('source_path', 'none')}")
1171
+ print(f"Format: {result.get('source_format', 'none')}")
1172
+ print(f"Controls: {result.get('total_controls', 0)} total "
1173
+ f"({result.get('base_controls', 0)} base, "
1174
+ f"{result.get('enhancements', 0)} enhancements)")
1175
+ print(f"Families: {result.get('family_count', 0)}")
1176
+ sys.exit(0)
1177
+
1178
+ parser.print_help()
1179
+
1180
+
1181
+ if __name__ == "__main__":
1182
+ main()