cfa-kernel 0.1.8__tar.gz → 0.1.9__tar.gz

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 (236) hide show
  1. cfa_kernel-0.1.9/CFA_LLM_Demo_fixed (1).dbc +0 -0
  2. cfa_kernel-0.1.9/CFA_LLM_Demo_fixed.dbc +0 -0
  3. cfa_kernel-0.1.9/CFA_LLM_Demo_fixed.py +673 -0
  4. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/PKG-INFO +2 -2
  5. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/README.md +1 -1
  6. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/pyproject.toml +1 -1
  7. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/__init__.py +1 -1
  8. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/core/kernel.py +1 -1
  9. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/normalizer/llm.py +2 -1
  10. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/observability/promotion.py +2 -2
  11. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/reporting/engine.py +1 -1
  12. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/docs/api.md +1 -1
  13. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/docs/faq.md +2 -2
  14. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/docs/intro.md +1 -1
  15. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/docs/whitepaper.md +2 -2
  16. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/docusaurus.config.ts +1 -1
  17. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/i18n/pt-BR/docusaurus-plugin-content-docs/current/api.md +1 -1
  18. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/i18n/pt-BR/docusaurus-plugin-content-docs/current/intro.md +1 -1
  19. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/i18n/pt-BR/docusaurus-plugin-content-docs/current/whitepaper.md +1 -1
  20. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/src/pages/index.tsx +1 -1
  21. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/.gitattributes +0 -0
  22. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  23. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  24. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  25. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/.github/workflows/ci.yml +0 -0
  26. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/.github/workflows/deploy-docs.yml +0 -0
  27. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/.github/workflows/deploy-pypi.yml +0 -0
  28. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/.github/workflows/governance.yml +0 -0
  29. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/.gitignore +0 -0
  30. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/.uv-cache/.gitignore +0 -0
  31. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/.uv-cache/.lock +0 -0
  32. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/.uv-cache/CACHEDIR.TAG +0 -0
  33. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/.uv-cache/sdists-v9/.gitignore +0 -0
  34. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/CFA_LLM_Demo.ipynb +0 -0
  35. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/CODE_OF_CONDUCT.md +0 -0
  36. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/CONTRIBUTING.md +0 -0
  37. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/LICENSE +0 -0
  38. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/MANUAL_TESTING_GUIDE.md +0 -0
  39. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/SECURITY.md +0 -0
  40. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/cfa_demo_complete.ipynb +0 -0
  41. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/examples/cfa_demo.py +0 -0
  42. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/examples/fiscal_governance.yaml +0 -0
  43. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/examples/full_pipeline.py +0 -0
  44. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/examples/llm_systematizer.py +0 -0
  45. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/examples/runtime_gate.py +0 -0
  46. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/examples/standalone_governance.py +0 -0
  47. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/examples/standalone_lifecycle.py +0 -0
  48. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/examples/standalone_resolution.py +0 -0
  49. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/integrations/airflow-governance-gate/README.md +0 -0
  50. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/integrations/airflow-governance-gate/dags/cfa_governance_gate_demo.py +0 -0
  51. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/integrations/airflow-governance-gate/requirements.txt +0 -0
  52. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/integrations/airflow-governance-gate/src/governance_gate.py +0 -0
  53. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/mcp.json +0 -0
  54. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/policies/compliance-strict-v1.yaml +0 -0
  55. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/policies/finops-strict-v1.yaml +0 -0
  56. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/policies/prod-v1.yaml +0 -0
  57. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/_lazy.py +0 -0
  58. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/adapters/__init__.py +0 -0
  59. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/adapters/autogen.py +0 -0
  60. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/adapters/crewai.py +0 -0
  61. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/adapters/dspy.py +0 -0
  62. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/adapters/langgraph.py +0 -0
  63. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/adapters/openai_agents.py +0 -0
  64. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/audit/__init__.py +0 -0
  65. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/audit/context.py +0 -0
  66. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/audit/hashing.py +0 -0
  67. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/audit/trail.py +0 -0
  68. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/backends/__init__.py +0 -0
  69. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/backends/dbt.py +0 -0
  70. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/backends/pyspark.py +0 -0
  71. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/backends/sql.py +0 -0
  72. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/behavior/__init__.py +0 -0
  73. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/behavior/llm.py +0 -0
  74. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/behavior/spec.py +0 -0
  75. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/behavior/systematizer.py +0 -0
  76. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/__init__.py +0 -0
  77. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/__main__.py +0 -0
  78. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/_helpers.py +0 -0
  79. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/core/__init__.py +0 -0
  80. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/core/evaluate.py +0 -0
  81. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/core/validate.py +0 -0
  82. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/formatters.py +0 -0
  83. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/governance/__init__.py +0 -0
  84. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/governance/audit.py +0 -0
  85. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/governance/catalog.py +0 -0
  86. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/governance/policy.py +0 -0
  87. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/governance/rules.py +0 -0
  88. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/governance/signature.py +0 -0
  89. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/infrastructure/__init__.py +0 -0
  90. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/infrastructure/backend_list.py +0 -0
  91. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/infrastructure/storage.py +0 -0
  92. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/project/__init__.py +0 -0
  93. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/project/init.py +0 -0
  94. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/project/lifecycle.py +0 -0
  95. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/project/status.py +0 -0
  96. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/project/taxonomy.py +0 -0
  97. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/reporting/__init__.py +0 -0
  98. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/reporting/report.py +0 -0
  99. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/cli/reporting/serve.py +0 -0
  100. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/config.py +0 -0
  101. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/core/__init__.py +0 -0
  102. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/core/codegen.py +0 -0
  103. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/core/conditions.py +0 -0
  104. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/core/phases/__init__.py +0 -0
  105. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/core/phases/runner.py +0 -0
  106. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/core/planner.py +0 -0
  107. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/execution/__init__.py +0 -0
  108. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/execution/partial.py +0 -0
  109. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/execution/state_projection.py +0 -0
  110. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/governance/__init__.py +0 -0
  111. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/lifecycle/__init__.py +0 -0
  112. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/mcp/__init__.py +0 -0
  113. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/mcp/__main__.py +0 -0
  114. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/normalizer/__init__.py +0 -0
  115. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/normalizer/base.py +0 -0
  116. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/observability/__init__.py +0 -0
  117. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/observability/indices.py +0 -0
  118. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/observability/metrics.py +0 -0
  119. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/observability/notify.py +0 -0
  120. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/observability/otel.py +0 -0
  121. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/policy/__init__.py +0 -0
  122. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/policy/bundle.py +0 -0
  123. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/policy/catalog.py +0 -0
  124. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/policy/engine.py +0 -0
  125. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/reporting/__init__.py +0 -0
  126. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/reporting/charts.py +0 -0
  127. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/resolution/__init__.py +0 -0
  128. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/runtime/__init__.py +0 -0
  129. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/runtime/gate.py +0 -0
  130. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/sandbox/__init__.py +0 -0
  131. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/sandbox/executor.py +0 -0
  132. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/sandbox/mock.py +0 -0
  133. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/sandbox/panic.py +0 -0
  134. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/storage/__init__.py +0 -0
  135. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/testing/__init__.py +0 -0
  136. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/testing/asserts.py +0 -0
  137. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/testing/evaluate.py +0 -0
  138. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/testing/fixtures.py +0 -0
  139. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/testing/markers.py +0 -0
  140. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/types.py +0 -0
  141. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/validation/__init__.py +0 -0
  142. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/validation/runtime.py +0 -0
  143. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/validation/signature.py +0 -0
  144. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/src/cfa/validation/static.py +0 -0
  145. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/conftest.py +0 -0
  146. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_adapters.py +0 -0
  147. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_airflow_governance_gate.py +0 -0
  148. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_audit_persistent.py +0 -0
  149. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_behavior.py +0 -0
  150. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_behavior_llm.py +0 -0
  151. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_catalog.py +0 -0
  152. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_cli_validation.py +0 -0
  153. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_codegen.py +0 -0
  154. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_config.py +0 -0
  155. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_context.py +0 -0
  156. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_context_persistent.py +0 -0
  157. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_dbt_backend.py +0 -0
  158. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_hashing.py +0 -0
  159. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_indices.py +0 -0
  160. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_integration.py +0 -0
  161. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_intensive.py +0 -0
  162. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_kernel.py +0 -0
  163. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_mcp.py +0 -0
  164. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_metrics.py +0 -0
  165. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_normalizer.py +0 -0
  166. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_normalizer_llm.py +0 -0
  167. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_notify.py +0 -0
  168. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_otel.py +0 -0
  169. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_partial_execution.py +0 -0
  170. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_planner.py +0 -0
  171. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_policy.py +0 -0
  172. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_policy_bundle.py +0 -0
  173. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_promotion.py +0 -0
  174. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_reporting.py +0 -0
  175. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_runtime.py +0 -0
  176. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_runtime_validation.py +0 -0
  177. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_sandbox.py +0 -0
  178. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_serialization.py +0 -0
  179. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_signature.py +0 -0
  180. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_sql_backend.py +0 -0
  181. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_state_projection.py +0 -0
  182. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_static_validation.py +0 -0
  183. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_storage.py +0 -0
  184. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_testing.py +0 -0
  185. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_types.py +0 -0
  186. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/tests/test_user_journeys.py +0 -0
  187. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/.gitignore +0 -0
  188. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/README.md +0 -0
  189. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/blog/2019-05-28-first-blog-post.mdx +0 -0
  190. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/blog/2019-05-29-long-blog-post.mdx +0 -0
  191. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/blog/2021-08-01-mdx-blog-post.mdx +0 -0
  192. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/blog/2021-08-26-welcome/docusaurus-plushie-banner.jpeg +0 -0
  193. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/blog/2021-08-26-welcome/index.mdx +0 -0
  194. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/blog/authors.yml +0 -0
  195. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/blog/tags.yml +0 -0
  196. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/docs/architecture-notes.md +0 -0
  197. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/docs/backends.md +0 -0
  198. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/docs/behavior-spec.md +0 -0
  199. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/docs/cli.md +0 -0
  200. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/docs/getting-started.md +0 -0
  201. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/docs/guide.md +0 -0
  202. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/docs/integrations/airflow.md +0 -0
  203. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/docs/integrations/langgraph.md +0 -0
  204. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/docs/integrations/openai-agents.md +0 -0
  205. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/docs/mcp-server.md +0 -0
  206. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/docs/policy-bundles.md +0 -0
  207. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/docs/reporting.md +0 -0
  208. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/i18n/pt-BR/code.json +0 -0
  209. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/i18n/pt-BR/docusaurus-plugin-content-docs/current/architecture-notes.md +0 -0
  210. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/i18n/pt-BR/docusaurus-plugin-content-docs/current/backends.md +0 -0
  211. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/i18n/pt-BR/docusaurus-plugin-content-docs/current/behavior-spec.md +0 -0
  212. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/i18n/pt-BR/docusaurus-plugin-content-docs/current/cli.md +0 -0
  213. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/i18n/pt-BR/docusaurus-plugin-content-docs/current/faq.md +0 -0
  214. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/i18n/pt-BR/docusaurus-plugin-content-docs/current/getting-started.md +0 -0
  215. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/i18n/pt-BR/docusaurus-plugin-content-docs/current/guide.md +0 -0
  216. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/i18n/pt-BR/docusaurus-plugin-content-docs/current/integrations/airflow.md +0 -0
  217. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/i18n/pt-BR/docusaurus-plugin-content-docs/current/integrations/langgraph.md +0 -0
  218. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/i18n/pt-BR/docusaurus-plugin-content-docs/current/integrations/openai-agents.md +0 -0
  219. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/i18n/pt-BR/docusaurus-plugin-content-docs/current/mcp-server.md +0 -0
  220. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/i18n/pt-BR/docusaurus-plugin-content-docs/current/policy-bundles.md +0 -0
  221. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/i18n/pt-BR/docusaurus-plugin-content-docs/current/reporting.md +0 -0
  222. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/package-lock.json +0 -0
  223. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/package.json +0 -0
  224. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/sidebars.ts +0 -0
  225. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/src/components/HomepageFeatures/index.tsx +0 -0
  226. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/src/components/HomepageFeatures/styles.module.css +0 -0
  227. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/src/css/custom.css +0 -0
  228. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/src/pages/index.module.css +0 -0
  229. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/src/pages/markdown-page.mdx +0 -0
  230. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/static/.nojekyll +0 -0
  231. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/static/img/favicon.ico +0 -0
  232. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/static/img/logo.svg +0 -0
  233. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/static/img/undraw_docusaurus_mountain.svg +0 -0
  234. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/static/img/undraw_docusaurus_react.svg +0 -0
  235. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/static/img/undraw_docusaurus_tree.svg +0 -0
  236. {cfa_kernel-0.1.8 → cfa_kernel-0.1.9}/website/tsconfig.json +0 -0
Binary file
@@ -0,0 +1,673 @@
1
+ # Databricks notebook source
2
+ # MAGIC %md
3
+ # MAGIC # CFA — Contextual Flux Architecture
4
+ # MAGIC ## LLM-Powered Governance Demo
5
+ # MAGIC
6
+ # MAGIC | Section | Feature | LLM Role |
7
+ # MAGIC |---|---|---|
8
+ # MAGIC | S1 | Setup & Secrets | Read API key from Databricks Secret Scope |
9
+ # MAGIC | S2 | Catalog | Operational metadata |
10
+ # MAGIC | S3 | LLM Normalizer | Semantic intent resolution (replaces keywords) |
11
+ # MAGIC | S4 | Strict Mode | LLM output validated against catalog |
12
+ # MAGIC | S5 | LLM Audit Trail | Every call SHA-256 traceable |
13
+ # MAGIC | S6 | LLM Systematizer | NL governance → BehaviorSpec → PolicyRules |
14
+ # MAGIC | S7 | Full Kernel + LLM | End-to-end governed execution |
15
+ # MAGIC | S8 | Runtime Gate + LLM | Guard with LLM-backed validation |
16
+ # MAGIC | S9 | Compare Normalizers | Rule-based vs LLM side-by-side |
17
+ # MAGIC | S10 | PolicyEngine + LLM Rules | Close the NL→Rules→Engine loop |
18
+ # MAGIC
19
+ # MAGIC **API key:** stored in Databricks Secret Scope `cfa-secrets`, never in code.
20
+ # MAGIC
21
+ # MAGIC ---
22
+ # MAGIC
23
+
24
+ # COMMAND ----------
25
+
26
+ # MAGIC %md
27
+ # MAGIC ## Section 0 — Install
28
+ # MAGIC
29
+ # MAGIC Run this cell first to install dependencies.
30
+ # MAGIC
31
+
32
+ # COMMAND ----------
33
+
34
+ # MAGIC %md
35
+ # MAGIC ## Section 1 — Setup & Secrets
36
+ # MAGIC
37
+ # MAGIC API key read from Databricks Secret Scope `cfa-secrets/openai-key` or `cfa-secrets/deepseek-key`.
38
+ # MAGIC Falls back to `OPENAI_API_KEY` / `DEEPSEEK_API_KEY` env vars for local testing.
39
+ # MAGIC
40
+
41
+ # COMMAND ----------
42
+
43
+ # MAGIC %pip install -q cfa-kernel[all] openai
44
+
45
+ # COMMAND ----------
46
+
47
+ # MAGIC %restart_python
48
+
49
+ # COMMAND ----------
50
+
51
+ # --- Test if openai is importable ---
52
+ HAS_OPENAI = False
53
+ try:
54
+ import openai
55
+ print(f"openai {openai.__version__} - OK")
56
+ HAS_OPENAI = True
57
+ except ImportError as e:
58
+ print(f"ERROR: openai not importable: {e}")
59
+ print("Run: %%pip install openai")
60
+
61
+ import cfa, os
62
+ from cfa.normalizer.llm import OpenAILMProvider, LLMNormalizerBackend
63
+ from cfa.normalizer.base import IntentNormalizer, RuleBasedNormalizerBackend
64
+ from cfa.runtime import RuntimeGate
65
+ from cfa.policy.engine import PolicyEngine
66
+ from cfa.types import StateSignature
67
+ from cfa.core.kernel import KernelConfig
68
+
69
+ print(f"CFA version: {cfa.__version__}")
70
+
71
+ # --- Read API keys from secret scope ---
72
+ def _try_secret(key):
73
+ try:
74
+ return dbutils.secrets.get("cfa-secrets", key)
75
+ except Exception:
76
+ return None
77
+
78
+ # Try Databricks secrets, fall back to env vars
79
+ OPENAI_KEY = _try_secret("openai-key") or os.environ.get("OPENAI_API_KEY")
80
+ DEEPSEEK_KEY = _try_secret("deepseek-key") or os.environ.get("DEEPSEEK_API_KEY")
81
+
82
+ # Auto-select: prefer OpenAI (better reachability from Azure), fallback to DeepSeek
83
+ if OPENAI_KEY:
84
+ LLM_MODEL = "gpt-4o-mini"
85
+ LLM_BASE_URL = None # default api.openai.com
86
+ LLM_API_KEY = OPENAI_KEY
87
+ print(f"Using OpenAI ({LLM_MODEL})")
88
+ elif DEEPSEEK_KEY:
89
+ LLM_MODEL = "deepseek-chat"
90
+ LLM_BASE_URL = "https://api.deepseek.com"
91
+ LLM_API_KEY = DEEPSEEK_KEY
92
+ print(f"Using DeepSeek ({LLM_MODEL})")
93
+ else:
94
+ LLM_MODEL = None
95
+ LLM_BASE_URL = None
96
+ LLM_API_KEY = None
97
+ print("WARNING: No API key found.")
98
+ print(" Databricks: secrets create-scope cfa-secrets")
99
+ print(" Local: set OPENAI_API_KEY or DEEPSEEK_API_KEY env var")
100
+
101
+ # Combined gate: need both openai + API key
102
+ HAS_LLM = HAS_OPENAI and LLM_API_KEY is not None
103
+
104
+ # Helper: create an LLM provider with the auto-detected config
105
+ def make_provider():
106
+ """Return OpenAILMProvider with auto-detected config."""
107
+ return OpenAILMProvider(
108
+ model=LLM_MODEL,
109
+ api_key=LLM_API_KEY,
110
+ base_url=LLM_BASE_URL,
111
+ temperature=0.0,
112
+ )
113
+
114
+
115
+ # COMMAND ----------
116
+
117
+ # MAGIC %md
118
+ # MAGIC ---
119
+ # MAGIC ## Section 2 — Data Catalog
120
+ # MAGIC
121
+ # MAGIC Catalog grounds the LLM. The LLM receives it in the prompt and MUST reference real datasets.
122
+ # MAGIC
123
+
124
+ # COMMAND ----------
125
+
126
+ CATALOG = {
127
+ 'nfe_bronze': {
128
+ 'type': 'delta', 'layer': 'bronze', 'size_gb': 50,
129
+ 'classification': 'high_volume',
130
+ 'partition_by': ['processing_date'], 'pii': False,
131
+ 'pii_columns': [],
132
+ 'description': 'Notas Fiscais Eletronicas brutas',
133
+ },
134
+ 'clientes_bronze': {
135
+ 'type': 'delta', 'layer': 'bronze', 'size_gb': 10,
136
+ 'classification': 'sensitive',
137
+ 'partition_by': ['processing_date'], 'pii': True,
138
+ 'pii_columns': ['cpf', 'nome', 'endereco'],
139
+ 'description': 'Dados cadastrais com CPF e endereco',
140
+ },
141
+ 'vendas_bronze': {
142
+ 'type': 'delta', 'layer': 'bronze', 'size_gb': 2000,
143
+ 'classification': 'high_volume',
144
+ 'partition_by': ['data_venda'], 'pii': False,
145
+ 'pii_columns': [],
146
+ 'description': 'Registros de transacoes de venda',
147
+ },
148
+ 'fornecedores_bronze': {
149
+ 'type': 'delta', 'layer': 'bronze', 'size_gb': 10,
150
+ 'classification': 'internal',
151
+ 'partition_by': ['updated_at'], 'pii': False,
152
+ 'pii_columns': [],
153
+ 'description': 'Cadastro de fornecedores',
154
+ },
155
+ 'vendas_gold_agregado': {
156
+ 'type': 'delta', 'layer': 'gold', 'size_gb': 500,
157
+ 'classification': 'internal',
158
+ 'partition_by': ['data_venda'], 'pii': False,
159
+ 'pii_columns': [],
160
+ 'description': 'Agregados de vendas para BI',
161
+ },
162
+ }
163
+
164
+ from cfa.policy.catalog import validate_catalog
165
+ result = validate_catalog(CATALOG)
166
+ print(f"Catalog valid: {result.valid}")
167
+ print(f" {len(CATALOG)} datasets registered")
168
+ print(" Classifications: nfe_bronze=high_volume, clientes_bronze=sensitive,")
169
+ print(" vendas_bronze=high_volume, fornecedores_bronze=internal,")
170
+ print(" vendas_gold_agregado=internal")
171
+ for msg in result.messages:
172
+ print(f" {msg}")
173
+
174
+
175
+ # COMMAND ----------
176
+
177
+ # MAGIC %md
178
+ # MAGIC ---
179
+ # MAGIC ## Section 3 — LLM Normalizer: Semantic Intent Resolution
180
+ # MAGIC
181
+ # MAGIC Rule-based = keyword matching (`join`, `aggregate`, `anonymize`).
182
+ # MAGIC LLM = sends `intent + catalog` to DeepSeek, parses structured JSON.
183
+ # MAGIC
184
+ # MAGIC The `SemanticResolution` returned contains the resolved `StateSignature`.
185
+ # MAGIC
186
+
187
+ # COMMAND ----------
188
+
189
+ if not HAS_LLM:
190
+ print("SKIP: no API key configured.")
191
+ else:
192
+ provider = make_provider()
193
+ llm_backend = LLMNormalizerBackend(provider=provider, strict=False)
194
+ normalizer = IntentNormalizer(backend=llm_backend)
195
+
196
+ print("=" * 55)
197
+ print("LLM NORMALIZER -- Semantic Resolution")
198
+ print("=" * 55)
199
+
200
+ intents = [
201
+ "Join NFe with Clientes anonymize CPF and persist to Silver",
202
+ "Aggregate vendas by region persist to Gold",
203
+ "Export raw clientes PII to Gold",
204
+ ]
205
+
206
+ for raw in intents:
207
+ print(f'\nIntent: "{raw}"')
208
+ res = normalizer.normalize(raw, {}, CATALOG)
209
+ sig = res.signature
210
+ print(f" Domain : {sig.domain}")
211
+ print(f" Intent : {sig.intent}")
212
+ print(f" Target layer : {sig.target_layer}")
213
+ ds_names = [d.name for d in sig.datasets]
214
+ print(f" Datasets : {ds_names}")
215
+ print(f" Confidence : {res.confidence_score:.2f}")
216
+ print(f" Ambiguity : {res.ambiguity_level}")
217
+ if res.reasoning:
218
+ print(f" Reasoning : {res.reasoning[:150]}...")
219
+
220
+ print("\nLLM normalizer baseline complete")
221
+
222
+
223
+ # COMMAND ----------
224
+
225
+ # MAGIC %md
226
+ # MAGIC ---
227
+ # MAGIC ## Section 4 — Strict Mode: Catalog-Grounded LLM
228
+ # MAGIC
229
+ # MAGIC `strict=True` validates the LLM output against the catalog.
230
+ # MAGIC Hallucinated datasets/references raise `ValueError`.
231
+ # MAGIC
232
+
233
+ # COMMAND ----------
234
+
235
+ if not HAS_LLM:
236
+ print("SKIP: no API key available")
237
+ else:
238
+ sp = make_provider()
239
+ sb = LLMNormalizerBackend(provider=sp, strict=True)
240
+ sn = IntentNormalizer(backend=sb)
241
+
242
+ print("=" * 55)
243
+ print("STRICT MODE — Catalog-grounded LLM")
244
+ print("=" * 55)
245
+ print(" strict=True: LLM output validated against catalog.")
246
+ print(" Hallucinated datasets or invalid classifications raise ValueError.")
247
+ print()
248
+
249
+ test_cases = [
250
+ # (intent, expect_pass)
251
+ ("Join NFe with Clientes anonymize CPF persist to Silver", True),
252
+ ("Full scan vendas without partition to Gold", False),
253
+ ]
254
+
255
+ for raw, expect_pass in test_cases:
256
+ print(f"Intent: \"{raw}\"")
257
+ try:
258
+ res = sn.normalize(raw, {}, CATALOG)
259
+ status = "PASSED " if expect_pass else "UNEXPECTED PASS"
260
+ print(f" {status} | confidence={res.confidence_score:.2f} layer={res.signature.target_layer}")
261
+ except ValueError as e:
262
+ status = "REJECTED (expected)" if not expect_pass else "REJECTED (unexpected)"
263
+ print(f" {status} | {str(e)[:120]}")
264
+ print()
265
+
266
+ print("Strict mode demo complete")
267
+
268
+
269
+ # COMMAND ----------
270
+
271
+ # MAGIC %md
272
+ # MAGIC ---
273
+ # MAGIC ## Section 5 — LLM Audit Trail
274
+ # MAGIC
275
+ # MAGIC Every LLM call is SHA-256 hashed (prompt, response, catalog).
276
+ # MAGIC Full traceability for compliance audits.
277
+ # MAGIC
278
+
279
+ # COMMAND ----------
280
+
281
+ if not HAS_LLM:
282
+ print("SKIP: no API key available")
283
+ else:
284
+ # 'sb' is the strict backend created in Section 4.
285
+ # Guard against running this cell out of order.
286
+ try:
287
+ records = sb.audit_records
288
+ except NameError:
289
+ print("NOTE: 'sb' not found — run Section 4 first, or re-run from Section 1.")
290
+ records = []
291
+
292
+ print("=" * 55)
293
+ print("LLM AUDIT TRAIL — Tamper-evident LLM calls")
294
+ print("=" * 55)
295
+ print(f" Total LLM calls recorded: {len(records)}")
296
+
297
+ for i, rec in enumerate(records):
298
+ print(f"\n Call {i+1}:")
299
+ print(f" Model : {rec.model}")
300
+ print(f" Prompt hash : {rec.prompt_hash[:16]}...")
301
+ print(f" Response hash : {rec.response_hash[:16]}...")
302
+ print(f" Catalog hash : {rec.catalog_hash[:16]}...")
303
+ if rec.catalog_validation_errors:
304
+ for err in rec.catalog_validation_errors:
305
+ print(f" Val. error : {err}")
306
+ if rec.parsed_json:
307
+ keys = list(rec.parsed_json.keys())
308
+ print(f" Parsed keys : {keys[:8]}")
309
+
310
+ print("\nLLM audit trail complete")
311
+
312
+
313
+ # COMMAND ----------
314
+
315
+ # MAGIC %md
316
+ # MAGIC ---
317
+ # MAGIC ## Section 6 — LLM Systematizer: NL → PolicyRules
318
+ # MAGIC
319
+ # MAGIC Describe governance in natural language. LLM produces `BehaviorSpec`.
320
+ # MAGIC `Systematizer` converts it to executable `PolicyRule` objects.
321
+ # MAGIC
322
+
323
+ # COMMAND ----------
324
+
325
+ from cfa.behavior.llm import OpenAISystematizerBackend
326
+ from cfa.behavior import Systematizer
327
+
328
+ taxonomy, rules = None, None
329
+
330
+ if not HAS_LLM:
331
+ print("SKIP: no LLM available (missing openai or API key)")
332
+ else:
333
+ try:
334
+ print("=" * 55)
335
+ print("LLM SYSTEMATIZER -- NL to Policy Rules")
336
+ print("=" * 55)
337
+
338
+ governance_desc = """\
339
+ Fiscal ETL pipeline governance:
340
+ 1. All datasets moving from Bronze to Silver/Gold MUST anonymize PII (CPF, nome, endereco)
341
+ 2. Every Silver and Gold write requires a merge_key (upsert, not append)
342
+ 3. Datasets larger than 100GB MUST have partition_by defined
343
+ 4. No raw PII columns may appear in Gold layer
344
+ 5. Maximum cost per pipeline run: 50 DBU
345
+ """
346
+
347
+ sys_backend = OpenAISystematizerBackend(
348
+ model=LLM_MODEL,
349
+ api_key=LLM_API_KEY,
350
+ base_url=LLM_BASE_URL,
351
+ temperature=0.0,
352
+ max_tokens=2048,
353
+ )
354
+
355
+ taxonomy, rules = Systematizer().systematize_from_nl(
356
+ governance_desc,
357
+ backend=sys_backend,
358
+ context="Fiscal ETL: NFe, Clientes, Vendas, Fornecedores on Databricks Delta Lake",
359
+ target_layer="silver",
360
+ )
361
+
362
+ print(f" Categories : {taxonomy.category_count}")
363
+ print(f" Rules generated : {len(rules)}")
364
+ print()
365
+
366
+ for rule in rules:
367
+ print(f" Rule : {rule.name}")
368
+ print(f" code : {rule.fault_code}")
369
+ print(f" action : {rule.action.value}")
370
+ print(f" severity : {rule.severity.value}")
371
+ print()
372
+
373
+ test_intents = taxonomy.generate_test_intents(3)
374
+ print(f" CI test intents generated: {len(test_intents)}")
375
+ for intent in test_intents:
376
+ print(f" - {intent}")
377
+
378
+ print("\nLLM Systematizer complete")
379
+ except Exception as e:
380
+ print(f" LLM call failed: {type(e).__name__}: {str(e)[:100]}")
381
+
382
+
383
+ # COMMAND ----------
384
+
385
+ # MAGIC %md
386
+ # MAGIC ---
387
+ # MAGIC ## Section 7 — Full Kernel with LLM Normalizer
388
+ # MAGIC
389
+ # MAGIC Same 5-phase pipeline (Formalize → Govern → Generate → Execute → Validate/Audit).
390
+ # MAGIC Only the **Formalize** phase switches from keyword-matching to DeepSeek.
391
+ # MAGIC
392
+
393
+ # COMMAND ----------
394
+
395
+ from cfa import KernelOrchestrator
396
+
397
+ if not HAS_LLM:
398
+ print("SKIP: no API key available")
399
+ else:
400
+ provider = make_provider()
401
+ # strict=False: LLM resolves intent semantically; catalog used for grounding
402
+ # but validation errors do not block execution (strict mode is for S4 demo only)
403
+ backend = LLMNormalizerBackend(provider=provider, strict=False)
404
+
405
+ kernel = KernelOrchestrator(
406
+ catalog=CATALOG,
407
+ config=KernelConfig(
408
+ policy_bundle_version="fiscal-prod-v1.0",
409
+ backend="pyspark",
410
+ ),
411
+ normalizer_backend=backend,
412
+ )
413
+
414
+ print("=" * 55)
415
+ print("FULL KERNEL + LLM NORMALIZER")
416
+ print("=" * 55)
417
+
418
+ for intent in [
419
+ "Join NFe with Clientes anonymize CPF and persist to Silver",
420
+ "Aggregate vendas by region persist to Gold",
421
+ "Export raw clientes PII to Gold",
422
+ ]:
423
+ print(f"\nIntent: \"{intent}\"")
424
+ try:
425
+ result = kernel.process(intent)
426
+ print(f" -> Decision : {result.state.value.upper()}")
427
+ if result.signature is not None:
428
+ print(f" -> Sig hash : {result.signature.signature_hash[:24]}...")
429
+ if result.replan_history:
430
+ print(f" -> Replans : {len(result.replan_history)}")
431
+ if result.generated_code and result.generated_code.code:
432
+ lines = result.generated_code.code.splitlines()
433
+ print(f" -> Code gen : {len(lines)} lines ({result.generated_code.language})")
434
+ preview = [l for l in lines if l.strip()][:6]
435
+ for line in preview:
436
+ print(f" {line}")
437
+ if len(lines) > 6:
438
+ print(f" ... ({len(lines) - 6} more lines)")
439
+ except Exception as e:
440
+ print(f" -> BLOCKED : {type(e).__name__} | {str(e)[:100]}")
441
+
442
+ calls = backend.audit_records
443
+ print(f"\n LLM calls by kernel: {len(calls)}")
444
+ for rec in calls:
445
+ print(f" prompt={rec.prompt_hash[:16]}... response={rec.response_hash[:16]}...")
446
+
447
+ print("\nFull kernel + LLM complete")
448
+
449
+
450
+ # COMMAND ----------
451
+
452
+ # MAGIC %md
453
+ # MAGIC ---
454
+ # MAGIC ## Section 8 — Runtime Gate
455
+ # MAGIC
456
+ # MAGIC `RuntimeGate` validates intents before execution.
457
+ # MAGIC With `policy_rules` from LLM Systematizer, the gate inherits NL-defined governance.
458
+ # MAGIC
459
+
460
+ # COMMAND ----------
461
+
462
+ import traceback
463
+ print("=" * 55)
464
+ print("RUNTIME GATE")
465
+ print("=" * 55)
466
+
467
+ # Guard: 'rules' is set by Section 6 (LLM Systematizer).
468
+ # If that section was skipped or failed, fall back to default rules gracefully.
469
+ try:
470
+ _rules = rules
471
+ except NameError:
472
+ _rules = None
473
+
474
+ if _rules is None:
475
+ print("NOTE: LLM-generated rules not available (Section 6 skipped or no API key).")
476
+ print(" Using default CFA policy rules instead.")
477
+ else:
478
+ print(f" Using {len(_rules)} LLM-generated rules from Section 6")
479
+
480
+ try:
481
+ gate = RuntimeGate(
482
+ catalog=CATALOG,
483
+ policy_rules=_rules,
484
+ )
485
+
486
+ result = gate.validate("Join NFe with Clientes and persist to Silver")
487
+ print(f" validate() -> state={result.state.value} passed={result.passed}")
488
+ print(f" gate_id={result.gate_id} execution_id={result.execution_id[:8]}...")
489
+
490
+ @gate.guard("aggregate sales data with PII protected")
491
+ def my_pipeline():
492
+ return "pipeline executed"
493
+
494
+ print(f" @gate.guard -> {my_pipeline()}")
495
+ print("\nRuntime Gate demo complete")
496
+ except Exception as e:
497
+ print(f" RUNTIME GATE FAILED: {type(e).__name__}")
498
+ traceback.print_exc()
499
+
500
+
501
+ # COMMAND ----------
502
+
503
+ # MAGIC %md
504
+ # MAGIC ---
505
+ # MAGIC ## Section 9 — Comparing Normalizers: Rule-Based vs LLM
506
+ # MAGIC
507
+ # MAGIC Same intent, two backends — side-by-side comparison.
508
+ # MAGIC
509
+
510
+ # COMMAND ----------
511
+
512
+ print("=" * 55)
513
+ print("NORMALIZER COMPARISON: Rule-Based vs LLM")
514
+ print("=" * 55)
515
+
516
+ rule_norm = IntentNormalizer(backend=RuleBasedNormalizerBackend())
517
+ llm_norm = None
518
+ if HAS_LLM:
519
+ provider = make_provider()
520
+ # strict=False for comparison — we want to see the LLM output, not block it
521
+ llm_norm = IntentNormalizer(backend=LLMNormalizerBackend(provider=provider, strict=False))
522
+
523
+ header = f"{'Intent':<50s} | {'Method':<12s} | {'Domain':<14s} | {'Layer':<8s} | {'Confidence':>10s}"
524
+ print(header)
525
+ print("-" * len(header))
526
+
527
+ for raw in [
528
+ "Join NFe with Clientes anonymize CPF and persist to Silver",
529
+ "Aggregate vendas by region persist to Gold",
530
+ "Export raw clientes PII to Gold",
531
+ ]:
532
+ # Rule-based
533
+ rb = rule_norm.normalize(raw, {}, CATALOG)
534
+ sig_rb = rb.signature
535
+ print(f"{raw[:47]:<50s} | {'rule-based':<12s} | {sig_rb.domain:<14s} | {str(sig_rb.target_layer):<8s} | {rb.confidence_score:>9.2f}")
536
+ # LLM
537
+ if llm_norm is not None:
538
+ try:
539
+ llm = llm_norm.normalize(raw, {}, CATALOG)
540
+ sig_llm = llm.signature
541
+ print(f"{'':50s} | {'LLM':<12s} | {sig_llm.domain:<14s} | {str(sig_llm.target_layer):<8s} | {llm.confidence_score:>9.2f}")
542
+ except Exception as e:
543
+ print(f"{'':50s} | {'LLM':<12s} | ERROR: {type(e).__name__}: {str(e)[:60]}")
544
+ else:
545
+ print(f"{'':50s} | {'LLM':<12s} | (no API key)")
546
+ print()
547
+
548
+ print("Normalizer comparison complete")
549
+
550
+ # COMMAND ----------
551
+
552
+ # MAGIC %md
553
+ # MAGIC ---
554
+ # MAGIC ## Section 10 — PolicyEngine with LLM-Generated Rules
555
+ # MAGIC
556
+ # MAGIC Rules from `LLMSystematizer` (Section 6) feed `PolicyEngine`.
557
+ # MAGIC Closes the loop: NL governance → LLM → BehaviorSpec → PolicyRules → Engine.
558
+ # MAGIC
559
+
560
+ # COMMAND ----------
561
+
562
+ from cfa.types import DatasetRef, SignatureConstraints, TargetLayer, ExecutionContext
563
+
564
+ print("=" * 55)
565
+ print("POLICY ENGINE WITH LLM-GENERATED RULES")
566
+ print("=" * 55)
567
+
568
+ # Guard: 'rules' is set by Section 6 (LLM Systematizer).
569
+ try:
570
+ _rules_s10 = rules
571
+ except NameError:
572
+ _rules_s10 = None
573
+
574
+ if _rules_s10 is None:
575
+ print("NOTE: LLM-generated rules not available (Section 6 skipped or no API key).")
576
+ print(" Using default CFA policy rules instead.")
577
+ engine = PolicyEngine() # default rules
578
+ else:
579
+ print(f" Using {len(_rules_s10)} LLM-generated rules from Section 6")
580
+ engine = PolicyEngine(rules=_rules_s10)
581
+
582
+ # --- Safe signature ---
583
+ sig_safe = StateSignature(
584
+ domain="fiscal",
585
+ intent="Join NFe with Clientes anonymize CPF persist to Silver",
586
+ source_intent_raw="Join NFe with Clientes anonymize CPF persist to Silver",
587
+ target_layer=TargetLayer.SILVER,
588
+ datasets=(
589
+ DatasetRef(name="nfe_bronze"),
590
+ DatasetRef(name="clientes_bronze", pii_columns=("cpf", "nome")),
591
+ ),
592
+ constraints=SignatureConstraints(
593
+ no_pii_raw=True,
594
+ merge_key_required=True,
595
+ partition_by=("processing_date",),
596
+ ),
597
+ execution_context=ExecutionContext(
598
+ policy_bundle_version="v1.0",
599
+ catalog_snapshot_version="catalog_default",
600
+ context_registry_version_id="ctx-default",
601
+ ),
602
+ )
603
+
604
+ r = engine.evaluate(sig_safe)
605
+ print(f"\n Safe signature -> {r.action.value.upper()} faults={len(r.faults)}")
606
+
607
+ # --- Unsafe signature ---
608
+ sig_unsafe = StateSignature(
609
+ domain="fiscal",
610
+ intent="Export raw clientes PII to Gold",
611
+ source_intent_raw="Export raw clientes PII to Gold",
612
+ target_layer=TargetLayer.GOLD,
613
+ datasets=(
614
+ DatasetRef(name="clientes_bronze", pii_columns=("cpf", "nome", "endereco")),
615
+ ),
616
+ constraints=SignatureConstraints(
617
+ no_pii_raw=False,
618
+ merge_key_required=False,
619
+ partition_by=(),
620
+ ),
621
+ execution_context=ExecutionContext(
622
+ policy_bundle_version="v1.0",
623
+ catalog_snapshot_version="catalog_default",
624
+ context_registry_version_id="ctx-default",
625
+ ),
626
+ )
627
+
628
+ r2 = engine.evaluate(sig_unsafe)
629
+ print(f" Unsafe signature -> {r2.action.value.upper()} faults={len(r2.faults)}")
630
+ for fault in r2.faults[:4]:
631
+ print(f" [{fault.severity.value.upper():<10s}] {fault.code}")
632
+
633
+ print("\nLLM-rules PolicyEngine complete")
634
+
635
+
636
+ # COMMAND ----------
637
+
638
+ # MAGIC %md
639
+ # MAGIC ---
640
+ # MAGIC ## Summary
641
+ # MAGIC
642
+ # MAGIC | LLM Feature | Status | Notes |
643
+ # MAGIC |---|---|---|
644
+ # MAGIC | LLM Normalizer | ✓ | Semantic intent resolution via DeepSeek/OpenAI |
645
+ # MAGIC | Strict Mode | ✓ | LLM output validated against catalog |
646
+ # MAGIC | LLM Audit Trail | ✓ | Every call SHA-256 traceable |
647
+ # MAGIC | LLM Systematizer | ✓ | NL → BehaviorSpec → PolicyRules |
648
+ # MAGIC | Full Kernel + LLM | ✓ | End-to-end with LLM normalizer |
649
+ # MAGIC | Runtime Gate | ✓ | Guard with LLM-generated policy rules |
650
+ # MAGIC | Normalizer Comparison | ✓ | Rule-based vs LLM side-by-side |
651
+ # MAGIC | Secret Management | ✓ | Databricks Secret Scope `cfa-secrets` |
652
+ # MAGIC
653
+ # MAGIC **Key differences from rule-based:**
654
+ # MAGIC
655
+ # MAGIC - LLM understands intent **semantics**, not just keywords
656
+ # MAGIC - Natural language governance descriptions → executable rules
657
+ # MAGIC - Every LLM call is audited (prompt/response/catalog SHA-256)
658
+ # MAGIC - Strict mode prevents hallucinations by validating against catalog
659
+ # MAGIC - API key stored in **Databricks Secret Scope** — never in code
660
+ # MAGIC
661
+ # MAGIC **Secret scope setup (one-time):**
662
+ # MAGIC ```bash
663
+ # MAGIC databricks secrets create-scope cfa-secrets
664
+ # MAGIC databricks secrets put-secret cfa-secrets deepseek-key
665
+ # MAGIC ```
666
+ # MAGIC
667
+ # MAGIC ---
668
+ # MAGIC
669
+ # MAGIC **Links**
670
+ # MAGIC - [Documentation](https://marquesantero.github.io/cfa/docs/intro)
671
+ # MAGIC - [PyPI](https://pypi.org/project/cfa-kernel/)
672
+ # MAGIC - [GitHub](https://github.com/marquesantero/cfa)
673
+ # MAGIC
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cfa-kernel
3
- Version: 0.1.8
3
+ Version: 0.1.9
4
4
  Summary: CFA — Governed execution for AI agents and data systems
5
5
  Project-URL: Homepage, https://marquesantero.github.io/cfa/
6
6
  Project-URL: Repository, https://github.com/marquesantero/cfa
@@ -38,7 +38,7 @@ Provides-Extra: yaml
38
38
  Requires-Dist: pyyaml>=6.0; extra == 'yaml'
39
39
  Description-Content-Type: text/markdown
40
40
 
41
- # CFA v0.1.8
41
+ # CFA v0.1.9
42
42
 
43
43
  [![CI](https://github.com/marquesantero/cfa/actions/workflows/ci.yml/badge.svg)](https://github.com/marquesantero/cfa/actions/workflows/ci.yml)
44
44
  [![codecov](https://codecov.io/github/marquesantero/cfa/graph/badge.svg?token=P5NFQBZGYT)](https://codecov.io/github/marquesantero/cfa)
@@ -1,4 +1,4 @@
1
- # CFA v0.1.8
1
+ # CFA v0.1.9
2
2
 
3
3
  [![CI](https://github.com/marquesantero/cfa/actions/workflows/ci.yml/badge.svg)](https://github.com/marquesantero/cfa/actions/workflows/ci.yml)
4
4
  [![codecov](https://codecov.io/github/marquesantero/cfa/graph/badge.svg?token=P5NFQBZGYT)](https://codecov.io/github/marquesantero/cfa)