sengol 0.8.0__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 (688) hide show
  1. sengol-0.8.0/.claude/skills/pr-review/SKILL.md +60 -0
  2. sengol-0.8.0/.cursorrules +134 -0
  3. sengol-0.8.0/.dockerignore +16 -0
  4. sengol-0.8.0/.github/copilot-instructions.md +92 -0
  5. sengol-0.8.0/.github/workflows/ci.yml +84 -0
  6. sengol-0.8.0/.github/workflows/deploy.yml +86 -0
  7. sengol-0.8.0/.github/workflows/integration.yml +70 -0
  8. sengol-0.8.0/.github/workflows/publish.yml +41 -0
  9. sengol-0.8.0/.gitignore +48 -0
  10. sengol-0.8.0/.mcp.json +30 -0
  11. sengol-0.8.0/CHANGELOG.md +277 -0
  12. sengol-0.8.0/CLAUDE.md +214 -0
  13. sengol-0.8.0/Dockerfile +40 -0
  14. sengol-0.8.0/LICENSE +201 -0
  15. sengol-0.8.0/PKG-INFO +80 -0
  16. sengol-0.8.0/README.md +2 -0
  17. sengol-0.8.0/alembic/env.py +104 -0
  18. sengol-0.8.0/alembic/script.py.mako +26 -0
  19. sengol-0.8.0/alembic/versions/0001_create_audit_records.py +46 -0
  20. sengol-0.8.0/alembic/versions/0002_audit_records_controlbook_columns.py +50 -0
  21. sengol-0.8.0/alembic/versions/0003_create_gold_score_records.py +75 -0
  22. sengol-0.8.0/alembic/versions/0004_create_saturation_events.py +74 -0
  23. sengol-0.8.0/alembic/versions/0005_create_evaluation_runs.py +111 -0
  24. sengol-0.8.0/alembic/versions/0006_hash_chain_idempotency_schema_versioning.py +120 -0
  25. sengol-0.8.0/alembic/versions/0007_auth_keyring.py +134 -0
  26. sengol-0.8.0/alembic/versions/0008_signing_keys_active_unique.py +39 -0
  27. sengol-0.8.0/alembic/versions/0009_agent_inherent_risk_tier.py +38 -0
  28. sengol-0.8.0/alembic/versions/0010_certification_records.py +73 -0
  29. sengol-0.8.0/alembic/versions/0011_human_review_items.py +61 -0
  30. sengol-0.8.0/alembic/versions/0012_certification_tenant_id.py +56 -0
  31. sengol-0.8.0/alembic/versions/0013_control_books.py +58 -0
  32. sengol-0.8.0/alembic/versions/0014_audit_record_span_id.py +32 -0
  33. sengol-0.8.0/alembic/versions/0015_human_review_requested_action.py +32 -0
  34. sengol-0.8.0/alembic/versions/0016_evidence_countersignatures_anchor_receipts.py +84 -0
  35. sengol-0.8.0/alembic/versions/0017_anchor_receipts_unique_seq_high.py +39 -0
  36. sengol-0.8.0/alembic/versions/0018_add_signing_backend_field.py +52 -0
  37. sengol-0.8.0/alembic/versions/0019_widen_key_id_for_kms_arn.py +53 -0
  38. sengol-0.8.0/alembic/versions/0020_add_console_access_log_table.py +64 -0
  39. sengol-0.8.0/alembic/versions/0021_add_users_and_api_tokens_tables.py +59 -0
  40. sengol-0.8.0/alembic/versions/0022_add_api_token_issuance_log_table.py +55 -0
  41. sengol-0.8.0/alembic/versions/0023_add_github_workflow_audit_log_table.py +63 -0
  42. sengol-0.8.0/alembic/versions/0024_add_reports_table.py +73 -0
  43. sengol-0.8.0/alembic/versions/0025_add_authority_model_version_to_audit_records.py +33 -0
  44. sengol-0.8.0/alembic/versions/0026_add_labels_to_agent_registrations.py +29 -0
  45. sengol-0.8.0/alembic/versions/0027_add_tenant_id_to_human_review_items.py +44 -0
  46. sengol-0.8.0/alembic/versions/0028_agent_declared_capabilities.py +40 -0
  47. sengol-0.8.0/alembic/versions/0029_agent_call_delegation_data.py +25 -0
  48. sengol-0.8.0/alembic.ini +38 -0
  49. sengol-0.8.0/console/index.html +12 -0
  50. sengol-0.8.0/console/package-lock.json +4445 -0
  51. sengol-0.8.0/console/package.json +32 -0
  52. sengol-0.8.0/console/src/App.tsx +28 -0
  53. sengol-0.8.0/console/src/components/DriftBadge.test.tsx +33 -0
  54. sengol-0.8.0/console/src/components/DriftBadge.tsx +46 -0
  55. sengol-0.8.0/console/src/components/GoldScoreGauge.tsx +33 -0
  56. sengol-0.8.0/console/src/components/LiveTrajectory.tsx +38 -0
  57. sengol-0.8.0/console/src/components/PassRateChart.test.tsx +25 -0
  58. sengol-0.8.0/console/src/components/PassRateChart.tsx +50 -0
  59. sengol-0.8.0/console/src/components/QuarterTrend.tsx +23 -0
  60. sengol-0.8.0/console/src/components/badges.test.tsx +28 -0
  61. sengol-0.8.0/console/src/components/badges.tsx +40 -0
  62. sengol-0.8.0/console/src/index.css +8 -0
  63. sengol-0.8.0/console/src/lib/apiClient.test.ts +43 -0
  64. sengol-0.8.0/console/src/lib/apiClient.ts +129 -0
  65. sengol-0.8.0/console/src/lib/sse.test.ts +33 -0
  66. sengol-0.8.0/console/src/lib/sse.ts +111 -0
  67. sengol-0.8.0/console/src/lib/types.ts +236 -0
  68. sengol-0.8.0/console/src/live/LiveContext.test.tsx +36 -0
  69. sengol-0.8.0/console/src/live/LiveContext.tsx +103 -0
  70. sengol-0.8.0/console/src/main.tsx +20 -0
  71. sengol-0.8.0/console/src/pages/agents/AgentsPage.test.tsx +57 -0
  72. sengol-0.8.0/console/src/pages/agents/AgentsPage.tsx +85 -0
  73. sengol-0.8.0/console/src/pages/agents/AlertTimeline.tsx +57 -0
  74. sengol-0.8.0/console/src/pages/agents/hooks.ts +18 -0
  75. sengol-0.8.0/console/src/pages/governance/GovernancePage.tsx +430 -0
  76. sengol-0.8.0/console/src/pages/governance/hooks.ts +10 -0
  77. sengol-0.8.0/console/src/pages/overview/OverviewPage.test.tsx +45 -0
  78. sengol-0.8.0/console/src/pages/overview/OverviewPage.tsx +83 -0
  79. sengol-0.8.0/console/src/pages/overview/hooks.ts +10 -0
  80. sengol-0.8.0/console/src/pages/reports/ReportsPage.test.tsx +46 -0
  81. sengol-0.8.0/console/src/pages/reports/ReportsPage.tsx +113 -0
  82. sengol-0.8.0/console/src/pages/reports/hooks.ts +25 -0
  83. sengol-0.8.0/console/src/pages/review/DecisionPanel.test.tsx +32 -0
  84. sengol-0.8.0/console/src/pages/review/DecisionPanel.tsx +60 -0
  85. sengol-0.8.0/console/src/pages/review/HumanReviewPage.test.tsx +12 -0
  86. sengol-0.8.0/console/src/pages/review/HumanReviewPage.tsx +14 -0
  87. sengol-0.8.0/console/src/pages/review/ReviewCard.test.tsx +27 -0
  88. sengol-0.8.0/console/src/pages/review/ReviewCard.tsx +51 -0
  89. sengol-0.8.0/console/src/pages/review/ReviewQueue.test.tsx +35 -0
  90. sengol-0.8.0/console/src/pages/review/ReviewQueue.tsx +78 -0
  91. sengol-0.8.0/console/src/pages/review/hooks.test.tsx +24 -0
  92. sengol-0.8.0/console/src/pages/review/hooks.ts +40 -0
  93. sengol-0.8.0/console/src/pages/settings/SettingsPage.test.tsx +40 -0
  94. sengol-0.8.0/console/src/pages/settings/SettingsPage.tsx +126 -0
  95. sengol-0.8.0/console/src/pages/settings/hooks.ts +34 -0
  96. sengol-0.8.0/console/src/pages/traces/CallGraph.tsx +74 -0
  97. sengol-0.8.0/console/src/pages/traces/TraceDetail.tsx +46 -0
  98. sengol-0.8.0/console/src/pages/traces/TracesPage.test.tsx +39 -0
  99. sengol-0.8.0/console/src/pages/traces/TracesPage.tsx +167 -0
  100. sengol-0.8.0/console/src/pages/traces/hooks.ts +26 -0
  101. sengol-0.8.0/console/src/shell/AlertFeed.test.tsx +29 -0
  102. sengol-0.8.0/console/src/shell/AlertFeed.tsx +65 -0
  103. sengol-0.8.0/console/src/shell/AppShell.test.tsx +40 -0
  104. sengol-0.8.0/console/src/shell/AppShell.tsx +69 -0
  105. sengol-0.8.0/console/src/test/fakeSse.tsx +16 -0
  106. sengol-0.8.0/console/src/test/harness.test.tsx +9 -0
  107. sengol-0.8.0/console/src/test/server.ts +100 -0
  108. sengol-0.8.0/console/src/test/setup.ts +19 -0
  109. sengol-0.8.0/console/src/test/utils.tsx +13 -0
  110. sengol-0.8.0/console/tsconfig.json +18 -0
  111. sengol-0.8.0/console/tsconfig.test.json +7 -0
  112. sengol-0.8.0/console/vite.config.ts +22 -0
  113. sengol-0.8.0/docker-compose.yml +67 -0
  114. sengol-0.8.0/docs/decisions/DEFERRED-DECISIONS.md +22 -0
  115. sengol-0.8.0/docs/decisions/README.md +220 -0
  116. sengol-0.8.0/docs/decisions/adr/ADR-0001-policyid-open-str.md +54 -0
  117. sengol-0.8.0/docs/decisions/adr/ADR-0002-evalscore-binary-passed.md +60 -0
  118. sengol-0.8.0/docs/decisions/adr/ADR-0003-deterministic-first-execution.md +90 -0
  119. sengol-0.8.0/docs/decisions/adr/ADR-0004-controlbook-drives-reports.md +72 -0
  120. sengol-0.8.0/docs/decisions/adr/ADR-0005-feature-gate-file.md +92 -0
  121. sengol-0.8.0/docs/decisions/adr/ADR-0006-auditrecord-hmac-payload-scope.md +79 -0
  122. sengol-0.8.0/docs/decisions/adr/ADR-0007-evaluator-registry-classmethod.md +74 -0
  123. sengol-0.8.0/docs/decisions/adr/ADR-0008-audit-store-append-only.md +76 -0
  124. sengol-0.8.0/docs/decisions/adr/ADR-0009-policy-catalog-yaml-extensibility.md +82 -0
  125. sengol-0.8.0/docs/decisions/adr/ADR-0010-controlbook-validate-warn-on-unknown.md +71 -0
  126. sengol-0.8.0/docs/decisions/adr/ADR-0011-synthetic-no-llm-no-pii.md +84 -0
  127. sengol-0.8.0/docs/decisions/adr/ADR-0012-catalog-schema-version.md +54 -0
  128. sengol-0.8.0/docs/decisions/adr/ADR-0013-evalsuite-exception-coercion.md +84 -0
  129. sengol-0.8.0/docs/decisions/adr/ADR-0014-llmjudge-as-protocol.md +57 -0
  130. sengol-0.8.0/docs/decisions/adr/ADR-0015-policies-field-rename.md +53 -0
  131. sengol-0.8.0/docs/decisions/adr/ADR-0016-saturation-detector.md +69 -0
  132. sengol-0.8.0/docs/decisions/adr/ADR-0017-pure-asgi-stub.md +64 -0
  133. sengol-0.8.0/docs/decisions/adr/ADR-0018-tests-suite-package-collision.md +45 -0
  134. sengol-0.8.0/docs/decisions/adr/ADR-0019-policy-agnostic-pdf-via-catalog.md +69 -0
  135. sengol-0.8.0/docs/decisions/adr/ADR-0020-reportmetadata-fallback-chain.md +65 -0
  136. sengol-0.8.0/docs/decisions/adr/ADR-0021-plain-language-evaluator-map.md +70 -0
  137. sengol-0.8.0/docs/decisions/adr/ADR-0022-word-boundary-policy-matching.md +80 -0
  138. sengol-0.8.0/docs/decisions/adr/ADR-0023-hmac-verify-records-before-report.md +63 -0
  139. sengol-0.8.0/docs/decisions/adr/ADR-0024-policy-overlap-filter.md +56 -0
  140. sengol-0.8.0/docs/decisions/adr/ADR-0025-compliance-report-hmac-scope.md +68 -0
  141. sengol-0.8.0/docs/decisions/adr/ADR-0026-obligation-strictness.md +77 -0
  142. sengol-0.8.0/docs/decisions/adr/ADR-0027-no-records-observed-failure-mode.md +72 -0
  143. sengol-0.8.0/docs/decisions/adr/ADR-0028-goldscore-minimum-floor-snap.md +80 -0
  144. sengol-0.8.0/docs/decisions/adr/ADR-0029-guardrailpolicy-no-evaluators-field.md +71 -0
  145. sengol-0.8.0/docs/decisions/adr/ADR-0030-pre-failure-degrades-to-block-under-retry.md +69 -0
  146. sengol-0.8.0/docs/decisions/adr/ADR-0031-promotiongate-toughest-obligation-wins.md +80 -0
  147. sengol-0.8.0/docs/decisions/adr/ADR-0032-synthetic-guardrail-outcome-score.md +82 -0
  148. sengol-0.8.0/docs/decisions/adr/ADR-0033-tpr-tnr-only-never-accuracy.md +59 -0
  149. sengol-0.8.0/docs/decisions/adr/ADR-0034-memory-audit-uri-scheme.md +66 -0
  150. sengol-0.8.0/docs/decisions/adr/ADR-0035-commit-body-must-match-file-list.md +74 -0
  151. sengol-0.8.0/docs/decisions/adr/ADR-0036-phase2d-session1-core-types.md +94 -0
  152. sengol-0.8.0/docs/decisions/adr/ADR-0037-phase2d-session2-new-stores.md +129 -0
  153. sengol-0.8.0/docs/decisions/adr/ADR-0038-phase2d-session3-pii-disclosure-evaluators.md +104 -0
  154. sengol-0.8.0/docs/decisions/adr/ADR-0039-phase2d-session4-structlog-integration-tests.md +88 -0
  155. sengol-0.8.0/docs/decisions/adr/ADR-0040-phase2d-session5-action-outputs.md +54 -0
  156. sengol-0.8.0/docs/decisions/adr/ADR-0041-plain-language-cli-flag.md +61 -0
  157. sengol-0.8.0/docs/decisions/adr/ADR-0042-obligation-result-count-fields.md +85 -0
  158. sengol-0.8.0/docs/decisions/adr/ADR-0043-no-agent-activity-sub-mode.md +78 -0
  159. sengol-0.8.0/docs/decisions/adr/ADR-0044-guardrail-constant-move.md +63 -0
  160. sengol-0.8.0/docs/decisions/adr/ADR-0046-llm-judge-client-architecture.md +63 -0
  161. sengol-0.8.0/docs/decisions/adr/ADR-0047-evaluator-wiring.md +67 -0
  162. sengol-0.8.0/docs/decisions/adr/ADR-0048-obligation-result-hmac-update.md +57 -0
  163. sengol-0.8.0/docs/decisions/adr/ADR-0049-no-agent-activity-gha-annotation-strategy.md +61 -0
  164. sengol-0.8.0/docs/decisions/adr/ADR-0050-phase3-tech-debt-resolution.md +63 -0
  165. sengol-0.8.0/docs/decisions/adr/ADR-0051-model-category-mismatch.md +60 -0
  166. sengol-0.8.0/docs/decisions/adr/ADR-0052-cli-to-api-boundary.md +352 -0
  167. sengol-0.8.0/docs/decisions/adr/ADR-0053-workload-taxonomy.md +251 -0
  168. sengol-0.8.0/docs/decisions/adr/ADR-0054-hash-chain.md +270 -0
  169. sengol-0.8.0/docs/decisions/adr/ADR-0055-idempotency.md +226 -0
  170. sengol-0.8.0/docs/decisions/adr/ADR-0056-workload-identity.md +262 -0
  171. sengol-0.8.0/docs/decisions/adr/ADR-0057-schema-versioning.md +260 -0
  172. sengol-0.8.0/docs/decisions/adr/ADR-0058-key-rotation.md +295 -0
  173. sengol-0.8.0/docs/decisions/adr/ADR-0059-basic-otlp-span-export.md +113 -0
  174. sengol-0.8.0/docs/decisions/adr/ADR-0060-agent-risk-taxonomy.md +101 -0
  175. sengol-0.8.0/docs/decisions/adr/ADR-0061-certification-lifecycle.md +73 -0
  176. sengol-0.8.0/docs/decisions/adr/ADR-0062-raw-trace-store.md +72 -0
  177. sengol-0.8.0/docs/decisions/adr/ADR-0063-trace-capture-and-sampling.md +67 -0
  178. sengol-0.8.0/docs/decisions/adr/ADR-0064-tracemine-dual-store-join.md +51 -0
  179. sengol-0.8.0/docs/decisions/adr/ADR-0065-human-review-queue.md +61 -0
  180. sengol-0.8.0/docs/decisions/adr/ADR-0066-certification-tenant-binding.md +60 -0
  181. sengol-0.8.0/docs/decisions/adr/ADR-0067-controlbook-store-and-console-write-scopes.md +51 -0
  182. sengol-0.8.0/docs/decisions/adr/ADR-0068-exporter-plugin-system.md +73 -0
  183. sengol-0.8.0/docs/decisions/adr/ADR-0069-online-trace-sink-plugin-system.md +103 -0
  184. sengol-0.8.0/docs/decisions/adr/ADR-0070-drift-evidence-policy.md +120 -0
  185. sengol-0.8.0/docs/decisions/adr/ADR-0071-otel-genai-alignment.md +70 -0
  186. sengol-0.8.0/docs/decisions/adr/ADR-0072-verifiable-evidence-anchoring.md +82 -0
  187. sengol-0.8.0/docs/decisions/adr/ADR-0073-obligation-coverage-gate.md +71 -0
  188. sengol-0.8.0/docs/decisions/adr/ADR-0074-kms-signing-backend.md +54 -0
  189. sengol-0.8.0/docs/decisions/adr/ADR-0075-console-oidc-sso.md +56 -0
  190. sengol-0.8.0/docs/decisions/adr/ADR-0076-local-user-self-service.md +64 -0
  191. sengol-0.8.0/docs/decisions/adr/ADR-0077-federated-workload-identity.md +66 -0
  192. sengol-0.8.0/docs/decisions/adr/ADR-0078-gdpr-pipeda-right-to-erasure.md +58 -0
  193. sengol-0.8.0/docs/decisions/adr/ADR-0079-governance-authority-model-v1.md +61 -0
  194. sengol-0.8.0/docs/decisions/adr/ADR-0080-compiled-regulation-stateless-yaml-view.md +74 -0
  195. sengol-0.8.0/docs/decisions/adr/ADR-0081-cross-framework-taxonomy-ir.md +33 -0
  196. sengol-0.8.0/docs/decisions/adr/ADR-0082-pluggable-red-team-backend.md +41 -0
  197. sengol-0.8.0/docs/decisions/adr/ADR-0083-delegation-chain-evidence.md +39 -0
  198. sengol-0.8.0/docs/decisions/adr/ADR-0084-client-auto-intercept-guardrails.md +129 -0
  199. sengol-0.8.0/docs/decisions/adr/INDEX.md +88 -0
  200. sengol-0.8.0/docs/decisions/design/PHASE-1-sdk-core.md +143 -0
  201. sengol-0.8.0/docs/decisions/design/PHASE-2-cro-demo.md +209 -0
  202. sengol-0.8.0/docs/decisions/future/PHASE-1-future-needs.md +180 -0
  203. sengol-0.8.0/docs/decisions/future/PHASE-2-future-needs.md +256 -0
  204. sengol-0.8.0/docs/decisions/gaps/PHASE-1-gaps.md +211 -0
  205. sengol-0.8.0/docs/decisions/gaps/PHASE-2-gaps.md +114 -0
  206. sengol-0.8.0/docs/reference/architecture.md +309 -0
  207. sengol-0.8.0/docs/reference/cli.md +67 -0
  208. sengol-0.8.0/docs/reference/console.md +134 -0
  209. sengol-0.8.0/docs/reference/env.md +153 -0
  210. sengol-0.8.0/docs/reference/redteam-configuration.md +201 -0
  211. sengol-0.8.0/docs/reference/redteam-ops-checklist.md +187 -0
  212. sengol-0.8.0/docs/reference/regulations.md +197 -0
  213. sengol-0.8.0/docs/reference/reports.md +89 -0
  214. sengol-0.8.0/docs/reference/sinks.md +182 -0
  215. sengol-0.8.0/docs/superpowers/plans/2026-06-05-console-5f-reports-settings.md +1453 -0
  216. sengol-0.8.0/docs/superpowers/plans/2026-06-10-console-v2-live-drift.md +1571 -0
  217. sengol-0.8.0/docs/tech-debt/TECH-DEBT-REGISTER.md +19 -0
  218. sengol-0.8.0/examples/acme_controlbook.yaml +70 -0
  219. sengol-0.8.0/examples/demo_adapters_and_exporters.py +184 -0
  220. sengol-0.8.0/examples/demo_end_to_end.py +248 -0
  221. sengol-0.8.0/examples/demo_otlp_traces.py +80 -0
  222. sengol-0.8.0/examples/osfi_e23_controlbook.yaml +175 -0
  223. sengol-0.8.0/examples/sample_traces.jsonl +12 -0
  224. sengol-0.8.0/examples/sengol.yaml +40 -0
  225. sengol-0.8.0/examples/synthetic_osfi_config.yaml +29 -0
  226. sengol-0.8.0/examples/us_treasury_controlbook.yaml +198 -0
  227. sengol-0.8.0/helm/sengol/Chart.yaml +16 -0
  228. sengol-0.8.0/helm/sengol/README.md +102 -0
  229. sengol-0.8.0/helm/sengol/templates/_helpers.tpl +38 -0
  230. sengol-0.8.0/helm/sengol/templates/configmap.yaml +10 -0
  231. sengol-0.8.0/helm/sengol/templates/deployment.yaml +53 -0
  232. sengol-0.8.0/helm/sengol/templates/hpa.yaml +22 -0
  233. sengol-0.8.0/helm/sengol/templates/ingress.yaml +31 -0
  234. sengol-0.8.0/helm/sengol/templates/secret.yaml +13 -0
  235. sengol-0.8.0/helm/sengol/templates/service.yaml +15 -0
  236. sengol-0.8.0/helm/sengol/values-aws.yaml +32 -0
  237. sengol-0.8.0/helm/sengol/values.yaml +67 -0
  238. sengol-0.8.0/pyproject.toml +123 -0
  239. sengol-0.8.0/sengol/__init__.py +44 -0
  240. sengol-0.8.0/sengol/adapters/__init__.py +38 -0
  241. sengol-0.8.0/sengol/adapters/base.py +125 -0
  242. sengol-0.8.0/sengol/adapters/jsonl.py +139 -0
  243. sengol-0.8.0/sengol/adapters/mlflow.py +229 -0
  244. sengol-0.8.0/sengol/adapters/registry.py +174 -0
  245. sengol-0.8.0/sengol/analysis/__init__.py +27 -0
  246. sengol-0.8.0/sengol/analysis/sampler.py +154 -0
  247. sengol-0.8.0/sengol/analysis/trace_analyzer.py +373 -0
  248. sengol-0.8.0/sengol/analysis/transition_matrix.py +234 -0
  249. sengol-0.8.0/sengol/api/CLAUDE.md +17 -0
  250. sengol-0.8.0/sengol/api/__init__.py +25 -0
  251. sengol-0.8.0/sengol/api/agent_call_builder.py +160 -0
  252. sengol-0.8.0/sengol/api/anchor.py +315 -0
  253. sengol-0.8.0/sengol/api/app.py +1322 -0
  254. sengol-0.8.0/sengol/api/auth_oidc.py +335 -0
  255. sengol-0.8.0/sengol/api/countersign.py +148 -0
  256. sengol-0.8.0/sengol/api/drift_events.py +97 -0
  257. sengol-0.8.0/sengol/api/dynamodb_audit_store.py +628 -0
  258. sengol-0.8.0/sengol/api/eval_run_sink.py +174 -0
  259. sengol-0.8.0/sengol/api/gold_score_sink.py +138 -0
  260. sengol-0.8.0/sengol/api/middleware/__init__.py +0 -0
  261. sengol-0.8.0/sengol/api/middleware/auth.py +227 -0
  262. sengol-0.8.0/sengol/api/middleware/rate_limit.py +208 -0
  263. sengol-0.8.0/sengol/api/openapi.yaml +4390 -0
  264. sengol-0.8.0/sengol/api/otlp_ingest.py +360 -0
  265. sengol-0.8.0/sengol/api/postgres_audit_store.py +532 -0
  266. sengol-0.8.0/sengol/api/postgres_certification_store.py +260 -0
  267. sengol-0.8.0/sengol/api/postgres_controlbook_store.py +117 -0
  268. sengol-0.8.0/sengol/api/postgres_eval_run_store.py +250 -0
  269. sengol-0.8.0/sengol/api/postgres_evidence_store.py +279 -0
  270. sengol-0.8.0/sengol/api/postgres_gold_score_store.py +250 -0
  271. sengol-0.8.0/sengol/api/postgres_human_review_store.py +213 -0
  272. sengol-0.8.0/sengol/api/postgres_report_store.py +224 -0
  273. sengol-0.8.0/sengol/api/postgres_saturation_store.py +240 -0
  274. sengol-0.8.0/sengol/api/s3_audit_store.py +465 -0
  275. sengol-0.8.0/sengol/api/saturation_sink.py +129 -0
  276. sengol-0.8.0/sengol/api/signing_kms.py +203 -0
  277. sengol-0.8.0/sengol/api/sink.py +598 -0
  278. sengol-0.8.0/sengol/api/sse_broker.py +74 -0
  279. sengol-0.8.0/sengol/api/v1/__init__.py +0 -0
  280. sengol-0.8.0/sengol/api/v1/agents.py +182 -0
  281. sengol-0.8.0/sengol/api/v1/audit.py +124 -0
  282. sengol-0.8.0/sengol/api/v1/auth.py +431 -0
  283. sengol-0.8.0/sengol/api/v1/console.py +826 -0
  284. sengol-0.8.0/sengol/api/v1/console_audit.py +253 -0
  285. sengol-0.8.0/sengol/api/v1/controlbook.py +82 -0
  286. sengol-0.8.0/sengol/api/v1/github_oidc.py +186 -0
  287. sengol-0.8.0/sengol/api/v1/keys.py +401 -0
  288. sengol-0.8.0/sengol/api/v1/lifecycle.py +200 -0
  289. sengol-0.8.0/sengol/api/v1/regulations.py +211 -0
  290. sengol-0.8.0/sengol/api/v1/reports.py +242 -0
  291. sengol-0.8.0/sengol/api/v1/review.py +201 -0
  292. sengol-0.8.0/sengol/api/v1/token_issuance_log.py +129 -0
  293. sengol-0.8.0/sengol/api/v1/users.py +581 -0
  294. sengol-0.8.0/sengol/build/__init__.py +15 -0
  295. sengol-0.8.0/sengol/build/gate.py +256 -0
  296. sengol-0.8.0/sengol/build/regression.py +129 -0
  297. sengol-0.8.0/sengol/build/suite.py +617 -0
  298. sengol-0.8.0/sengol/capture/__init__.py +26 -0
  299. sengol-0.8.0/sengol/capture/config.py +166 -0
  300. sengol-0.8.0/sengol/capture/redaction.py +44 -0
  301. sengol-0.8.0/sengol/capture/store.py +174 -0
  302. sengol-0.8.0/sengol/capture/types.py +36 -0
  303. sengol-0.8.0/sengol/cicd/__init__.py +10 -0
  304. sengol-0.8.0/sengol/cicd/_render.py +273 -0
  305. sengol-0.8.0/sengol/cicd/azure_pipelines.py +321 -0
  306. sengol-0.8.0/sengol/cicd/github.py +525 -0
  307. sengol-0.8.0/sengol/cli/__init__.py +0 -0
  308. sengol-0.8.0/sengol/cli/main.py +3859 -0
  309. sengol-0.8.0/sengol/core/__init__.py +7 -0
  310. sengol-0.8.0/sengol/core/drift.py +148 -0
  311. sengol-0.8.0/sengol/core/evaluator.py +106 -0
  312. sengol-0.8.0/sengol/core/judge.py +71 -0
  313. sengol-0.8.0/sengol/core/judge_validation.py +196 -0
  314. sengol-0.8.0/sengol/core/keyring.py +60 -0
  315. sengol-0.8.0/sengol/core/merkle.py +43 -0
  316. sengol-0.8.0/sengol/core/payload_registry.py +322 -0
  317. sengol-0.8.0/sengol/core/registry.py +231 -0
  318. sengol-0.8.0/sengol/core/severity.py +33 -0
  319. sengol-0.8.0/sengol/core/signing.py +89 -0
  320. sengol-0.8.0/sengol/core/types.py +840 -0
  321. sengol-0.8.0/sengol/dataset/__init__.py +10 -0
  322. sengol-0.8.0/sengol/dataset/_hash.py +96 -0
  323. sengol-0.8.0/sengol/dataset/loader.py +258 -0
  324. sengol-0.8.0/sengol/dataset/registry.py +277 -0
  325. sengol-0.8.0/sengol/evaluators/CLAUDE.md +17 -0
  326. sengol-0.8.0/sengol/evaluators/__init__.py +151 -0
  327. sengol-0.8.0/sengol/evaluators/deterministic/__init__.py +33 -0
  328. sengol-0.8.0/sengol/evaluators/deterministic/disclosure.py +148 -0
  329. sengol-0.8.0/sengol/evaluators/deterministic/drift_monitor.py +60 -0
  330. sengol-0.8.0/sengol/evaluators/deterministic/exact_match.py +68 -0
  331. sengol-0.8.0/sengol/evaluators/deterministic/keyword.py +103 -0
  332. sengol-0.8.0/sengol/evaluators/deterministic/pii.py +180 -0
  333. sengol-0.8.0/sengol/evaluators/deterministic/regex.py +66 -0
  334. sengol-0.8.0/sengol/evaluators/deterministic/response_length.py +78 -0
  335. sengol-0.8.0/sengol/evaluators/deterministic/schema_validation.py +82 -0
  336. sengol-0.8.0/sengol/evaluators/deterministic/trajectory.py +244 -0
  337. sengol-0.8.0/sengol/evaluators/deterministic/unauthorized_delegation.py +68 -0
  338. sengol-0.8.0/sengol/evaluators/ensemble.py +243 -0
  339. sengol-0.8.0/sengol/evaluators/llm/__init__.py +37 -0
  340. sengol-0.8.0/sengol/evaluators/llm/adversarial_robustness.py +112 -0
  341. sengol-0.8.0/sengol/evaluators/llm/explainability.py +127 -0
  342. sengol-0.8.0/sengol/evaluators/llm/faithfulness.py +83 -0
  343. sengol-0.8.0/sengol/evaluators/llm/groundedness.py +178 -0
  344. sengol-0.8.0/sengol/evaluators/llm/hallucination.py +85 -0
  345. sengol-0.8.0/sengol/evaluators/llm/pii.py +72 -0
  346. sengol-0.8.0/sengol/evaluators/llm/refusal.py +125 -0
  347. sengol-0.8.0/sengol/evaluators/llm/relevance.py +137 -0
  348. sengol-0.8.0/sengol/evaluators/llm/toxicity.py +159 -0
  349. sengol-0.8.0/sengol/evaluators/llm/trajectory.py +295 -0
  350. sengol-0.8.0/sengol/evaluators/model/__init__.py +1 -0
  351. sengol-0.8.0/sengol/evaluators/model/ab_evaluator.py +208 -0
  352. sengol-0.8.0/sengol/evaluators/model/auc.py +146 -0
  353. sengol-0.8.0/sengol/evaluators/model/champion_challenger.py +154 -0
  354. sengol-0.8.0/sengol/evaluators/model/fairness.py +236 -0
  355. sengol-0.8.0/sengol/evaluators/model/outcome_monitor.py +166 -0
  356. sengol-0.8.0/sengol/evaluators/model/psi.py +175 -0
  357. sengol-0.8.0/sengol/evaluators/redteam/__init__.py +17 -0
  358. sengol-0.8.0/sengol/evaluators/redteam/base.py +155 -0
  359. sengol-0.8.0/sengol/evaluators/redteam/garak_backend.py +127 -0
  360. sengol-0.8.0/sengol/governance/CLAUDE.md +13 -0
  361. sengol-0.8.0/sengol/governance/__init__.py +0 -0
  362. sengol-0.8.0/sengol/governance/_license.py +86 -0
  363. sengol-0.8.0/sengol/governance/audit_store.py +329 -0
  364. sengol-0.8.0/sengol/governance/certification_store.py +111 -0
  365. sengol-0.8.0/sengol/governance/controlbook_store.py +56 -0
  366. sengol-0.8.0/sengol/governance/controlbook_validator.py +291 -0
  367. sengol-0.8.0/sengol/governance/drift_evidence.py +602 -0
  368. sengol-0.8.0/sengol/governance/eval_run_store.py +117 -0
  369. sengol-0.8.0/sengol/governance/evidence_store.py +150 -0
  370. sengol-0.8.0/sengol/governance/gold_score.py +207 -0
  371. sengol-0.8.0/sengol/governance/gold_score_store.py +171 -0
  372. sengol-0.8.0/sengol/governance/human_review_store.py +168 -0
  373. sengol-0.8.0/sengol/governance/offline_verify.py +407 -0
  374. sengol-0.8.0/sengol/governance/report_base.py +780 -0
  375. sengol-0.8.0/sengol/governance/report_enterprise.py +780 -0
  376. sengol-0.8.0/sengol/governance/report_store.py +173 -0
  377. sengol-0.8.0/sengol/governance/saturation_store.py +175 -0
  378. sengol-0.8.0/sengol/instrument/__init__.py +73 -0
  379. sengol-0.8.0/sengol/instrument/_runner.py +342 -0
  380. sengol-0.8.0/sengol/instrument/anthropic_patch.py +108 -0
  381. sengol-0.8.0/sengol/instrument/config.py +52 -0
  382. sengol-0.8.0/sengol/instrument/exceptions.py +16 -0
  383. sengol-0.8.0/sengol/instrument/extractor.py +113 -0
  384. sengol-0.8.0/sengol/instrument/openai_patch.py +103 -0
  385. sengol-0.8.0/sengol/instrument/registry.py +58 -0
  386. sengol-0.8.0/sengol/judges/__init__.py +22 -0
  387. sengol-0.8.0/sengol/judges/_base.py +147 -0
  388. sengol-0.8.0/sengol/judges/_exceptions.py +11 -0
  389. sengol-0.8.0/sengol/judges/_prompt.py +73 -0
  390. sengol-0.8.0/sengol/judges/anthropic.py +78 -0
  391. sengol-0.8.0/sengol/judges/openai_compatible.py +84 -0
  392. sengol-0.8.0/sengol/logging.py +76 -0
  393. sengol-0.8.0/sengol/observability/__init__.py +36 -0
  394. sengol-0.8.0/sengol/observability/config.py +156 -0
  395. sengol-0.8.0/sengol/observability/spans.py +128 -0
  396. sengol-0.8.0/sengol/observability/tracer.py +135 -0
  397. sengol-0.8.0/sengol/policies/__init__.py +27 -0
  398. sengol-0.8.0/sengol/policies/catalog.yaml +385 -0
  399. sengol-0.8.0/sengol/policies/compiled.py +177 -0
  400. sengol-0.8.0/sengol/policies/evaluator_routing.yaml +375 -0
  401. sengol-0.8.0/sengol/policies/evaluator_translations.yaml +14 -0
  402. sengol-0.8.0/sengol/policies/loader.py +358 -0
  403. sengol-0.8.0/sengol/policies/taxonomy.py +194 -0
  404. sengol-0.8.0/sengol/policies/taxonomy.yaml +105 -0
  405. sengol-0.8.0/sengol/policies/taxonomy_crosswalk.yaml +68 -0
  406. sengol-0.8.0/sengol/runtime/__init__.py +26 -0
  407. sengol-0.8.0/sengol/runtime/async_worker.py +216 -0
  408. sengol-0.8.0/sengol/runtime/drift.py +147 -0
  409. sengol-0.8.0/sengol/runtime/guardrails.py +695 -0
  410. sengol-0.8.0/sengol/runtime/inline_evaluator.py +129 -0
  411. sengol-0.8.0/sengol/runtime/sampling/__init__.py +6 -0
  412. sengol-0.8.0/sengol/runtime/sampling/clustering.py +168 -0
  413. sengol-0.8.0/sengol/runtime/sampling/feedback.py +22 -0
  414. sengol-0.8.0/sengol/runtime/sampling/random.py +41 -0
  415. sengol-0.8.0/sengol/runtime/sqs_eval_worker.py +292 -0
  416. sengol-0.8.0/sengol/runtime/webhook.py +108 -0
  417. sengol-0.8.0/sengol/sinks/__init__.py +48 -0
  418. sengol-0.8.0/sengol/sinks/base.py +121 -0
  419. sengol-0.8.0/sengol/sinks/dispatch.py +186 -0
  420. sengol-0.8.0/sengol/sinks/langfuse.py +171 -0
  421. sengol-0.8.0/sengol/sinks/otlp.py +277 -0
  422. sengol-0.8.0/sengol/sinks/registry.py +164 -0
  423. sengol-0.8.0/sengol/sinks/semconv.py +51 -0
  424. sengol-0.8.0/sengol/synthetic/__init__.py +26 -0
  425. sengol-0.8.0/sengol/synthetic/config.py +55 -0
  426. sengol-0.8.0/sengol/synthetic/generator.py +210 -0
  427. sengol-0.8.0/sengol/synthetic/trace_extractor.py +167 -0
  428. sengol-0.8.0/sengol/trajectory/__init__.py +24 -0
  429. sengol-0.8.0/sengol/trajectory/mapping.py +355 -0
  430. sengol-0.8.0/sengol/trajectory/types.py +42 -0
  431. sengol-0.8.0/sengol.yaml +65 -0
  432. sengol-0.8.0/terraform/aws/.gitignore +9 -0
  433. sengol-0.8.0/terraform/aws/environments/dev.tfvars +6 -0
  434. sengol-0.8.0/terraform/aws/environments/prod.tfvars +7 -0
  435. sengol-0.8.0/terraform/aws/environments/staging.tfvars +6 -0
  436. sengol-0.8.0/terraform/aws/main.tf +125 -0
  437. sengol-0.8.0/terraform/aws/modules/alb/main.tf +85 -0
  438. sengol-0.8.0/terraform/aws/modules/alb/outputs.tf +24 -0
  439. sengol-0.8.0/terraform/aws/modules/alb/variables.tf +26 -0
  440. sengol-0.8.0/terraform/aws/modules/ecr/main.tf +30 -0
  441. sengol-0.8.0/terraform/aws/modules/ecr/outputs.tf +9 -0
  442. sengol-0.8.0/terraform/aws/modules/ecr/variables.tf +15 -0
  443. sengol-0.8.0/terraform/aws/modules/ecs/main.tf +181 -0
  444. sengol-0.8.0/terraform/aws/modules/ecs/outputs.tf +24 -0
  445. sengol-0.8.0/terraform/aws/modules/ecs/variables.tf +109 -0
  446. sengol-0.8.0/terraform/aws/modules/kms/main.tf +57 -0
  447. sengol-0.8.0/terraform/aws/modules/kms/outputs.tf +14 -0
  448. sengol-0.8.0/terraform/aws/modules/kms/variables.tf +64 -0
  449. sengol-0.8.0/terraform/aws/modules/rds/main.tf +56 -0
  450. sengol-0.8.0/terraform/aws/modules/rds/outputs.tf +14 -0
  451. sengol-0.8.0/terraform/aws/modules/rds/variables.tf +52 -0
  452. sengol-0.8.0/terraform/aws/modules/s3_audit/main.tf +54 -0
  453. sengol-0.8.0/terraform/aws/modules/s3_audit/outputs.tf +9 -0
  454. sengol-0.8.0/terraform/aws/modules/s3_audit/variables.tf +35 -0
  455. sengol-0.8.0/terraform/aws/modules/sqs/main.tf +27 -0
  456. sengol-0.8.0/terraform/aws/modules/sqs/outputs.tf +19 -0
  457. sengol-0.8.0/terraform/aws/modules/sqs/variables.tf +27 -0
  458. sengol-0.8.0/terraform/aws/modules/vpc/main.tf +89 -0
  459. sengol-0.8.0/terraform/aws/modules/vpc/outputs.tf +19 -0
  460. sengol-0.8.0/terraform/aws/modules/vpc/variables.tf +21 -0
  461. sengol-0.8.0/terraform/aws/outputs.tf +46 -0
  462. sengol-0.8.0/terraform/aws/providers.tf +16 -0
  463. sengol-0.8.0/terraform/aws/variables.tf +113 -0
  464. sengol-0.8.0/terraform/aws/versions.tf +13 -0
  465. sengol-0.8.0/tests/CLAUDE.md +14 -0
  466. sengol-0.8.0/tests/__init__.py +0 -0
  467. sengol-0.8.0/tests/adapters/__init__.py +0 -0
  468. sengol-0.8.0/tests/adapters/test_jsonl.py +124 -0
  469. sengol-0.8.0/tests/adapters/test_mlflow.py +303 -0
  470. sengol-0.8.0/tests/adapters/test_registry.py +206 -0
  471. sengol-0.8.0/tests/analysis/__init__.py +0 -0
  472. sengol-0.8.0/tests/analysis/test_data_analysis_sampler.py +426 -0
  473. sengol-0.8.0/tests/analysis/test_trace_analyzer.py +222 -0
  474. sengol-0.8.0/tests/analysis/test_transition_matrix.py +304 -0
  475. sengol-0.8.0/tests/api/__init__.py +0 -0
  476. sengol-0.8.0/tests/api/conftest.py +42 -0
  477. sengol-0.8.0/tests/api/test_agents_list.py +65 -0
  478. sengol-0.8.0/tests/api/test_anchor_scheduler.py +228 -0
  479. sengol-0.8.0/tests/api/test_api_app.py +552 -0
  480. sengol-0.8.0/tests/api/test_api_sink.py +461 -0
  481. sengol-0.8.0/tests/api/test_app.py +46 -0
  482. sengol-0.8.0/tests/api/test_audit_severity.py +92 -0
  483. sengol-0.8.0/tests/api/test_auth_console_token.py +226 -0
  484. sengol-0.8.0/tests/api/test_auth_oidc.py +779 -0
  485. sengol-0.8.0/tests/api/test_certification_routes.py +164 -0
  486. sengol-0.8.0/tests/api/test_console_access_log.py +428 -0
  487. sengol-0.8.0/tests/api/test_console_auth_status.py +199 -0
  488. sengol-0.8.0/tests/api/test_console_reports.py +165 -0
  489. sengol-0.8.0/tests/api/test_console_routes.py +350 -0
  490. sengol-0.8.0/tests/api/test_console_static.py +67 -0
  491. sengol-0.8.0/tests/api/test_console_stream.py +317 -0
  492. sengol-0.8.0/tests/api/test_controlbook_upload.py +154 -0
  493. sengol-0.8.0/tests/api/test_countersign_dispatcher.py +157 -0
  494. sengol-0.8.0/tests/api/test_countersign_signer.py +94 -0
  495. sengol-0.8.0/tests/api/test_durable_spool.py +222 -0
  496. sengol-0.8.0/tests/api/test_dynamodb_audit_store.py +393 -0
  497. sengol-0.8.0/tests/api/test_eval_browse_route.py +86 -0
  498. sengol-0.8.0/tests/api/test_eval_run_routes.py +201 -0
  499. sengol-0.8.0/tests/api/test_github_oidc.py +354 -0
  500. sengol-0.8.0/tests/api/test_license_gate.py +133 -0
  501. sengol-0.8.0/tests/api/test_local_user_auth.py +679 -0
  502. sengol-0.8.0/tests/api/test_openapi_contract.py +198 -0
  503. sengol-0.8.0/tests/api/test_otlp_agent_call_ingest.py +175 -0
  504. sengol-0.8.0/tests/api/test_otlp_ingest.py +465 -0
  505. sengol-0.8.0/tests/api/test_postgres_audit_store.py +171 -0
  506. sengol-0.8.0/tests/api/test_postgres_gold_score_store.py +77 -0
  507. sengol-0.8.0/tests/api/test_postgres_report_store.py +240 -0
  508. sengol-0.8.0/tests/api/test_postgres_saturation_store.py +75 -0
  509. sengol-0.8.0/tests/api/test_rate_limit.py +212 -0
  510. sengol-0.8.0/tests/api/test_regulations_api.py +252 -0
  511. sengol-0.8.0/tests/api/test_reports_db.py +169 -0
  512. sengol-0.8.0/tests/api/test_reports_generate.py +88 -0
  513. sengol-0.8.0/tests/api/test_review_routes.py +247 -0
  514. sengol-0.8.0/tests/api/test_s3_audit_store.py +261 -0
  515. sengol-0.8.0/tests/api/test_signing_kms.py +261 -0
  516. sengol-0.8.0/tests/api/test_token_issuance_log.py +933 -0
  517. sengol-0.8.0/tests/api/test_verification_keys.py +107 -0
  518. sengol-0.8.0/tests/build/__init__.py +0 -0
  519. sengol-0.8.0/tests/build/test_gate.py +367 -0
  520. sengol-0.8.0/tests/build/test_regression.py +128 -0
  521. sengol-0.8.0/tests/build/test_suite_flake.py +198 -0
  522. sengol-0.8.0/tests/capture/__init__.py +0 -0
  523. sengol-0.8.0/tests/capture/test_config.py +240 -0
  524. sengol-0.8.0/tests/capture/test_redaction.py +55 -0
  525. sengol-0.8.0/tests/capture/test_store.py +182 -0
  526. sengol-0.8.0/tests/cicd/__init__.py +0 -0
  527. sengol-0.8.0/tests/cicd/test_azure_pipelines.py +273 -0
  528. sengol-0.8.0/tests/cicd/test_github.py +746 -0
  529. sengol-0.8.0/tests/cli/__init__.py +0 -0
  530. sengol-0.8.0/tests/cli/test_analyze.py +95 -0
  531. sengol-0.8.0/tests/cli/test_audit_verify.py +194 -0
  532. sengol-0.8.0/tests/cli/test_audit_verify_offline.py +273 -0
  533. sengol-0.8.0/tests/cli/test_controlbook_validate.py +95 -0
  534. sengol-0.8.0/tests/cli/test_dataset.py +393 -0
  535. sengol-0.8.0/tests/cli/test_eval_browse.py +51 -0
  536. sengol-0.8.0/tests/cli/test_eval_health.py +140 -0
  537. sengol-0.8.0/tests/cli/test_eval_list.py +75 -0
  538. sengol-0.8.0/tests/cli/test_eval_suggest.py +38 -0
  539. sengol-0.8.0/tests/cli/test_exporters_e2e.py +154 -0
  540. sengol-0.8.0/tests/cli/test_github_oidc_exchange.py +113 -0
  541. sengol-0.8.0/tests/cli/test_judge_validate.py +155 -0
  542. sengol-0.8.0/tests/cli/test_lifecycle_certify.py +154 -0
  543. sengol-0.8.0/tests/cli/test_policy_list.py +99 -0
  544. sengol-0.8.0/tests/cli/test_regulation_cli.py +181 -0
  545. sengol-0.8.0/tests/cli/test_report_generate.py +484 -0
  546. sengol-0.8.0/tests/cli/test_review_cli.py +198 -0
  547. sengol-0.8.0/tests/cli/test_run_suite.py +354 -0
  548. sengol-0.8.0/tests/cli/test_sinks_e2e.py +112 -0
  549. sengol-0.8.0/tests/core/__init__.py +0 -0
  550. sengol-0.8.0/tests/core/test_agent_call_record.py +74 -0
  551. sengol-0.8.0/tests/core/test_controlbook.py +214 -0
  552. sengol-0.8.0/tests/core/test_evidence_types.py +194 -0
  553. sengol-0.8.0/tests/core/test_judge_validation.py +176 -0
  554. sengol-0.8.0/tests/core/test_merkle.py +76 -0
  555. sengol-0.8.0/tests/core/test_payload_registry.py +313 -0
  556. sengol-0.8.0/tests/core/test_payload_version_unchanged.py +81 -0
  557. sengol-0.8.0/tests/core/test_registry.py +292 -0
  558. sengol-0.8.0/tests/core/test_risk_taxonomy.py +164 -0
  559. sengol-0.8.0/tests/core/test_severity.py +68 -0
  560. sengol-0.8.0/tests/core/test_signing.py +325 -0
  561. sengol-0.8.0/tests/core/test_signing_backend_field.py +231 -0
  562. sengol-0.8.0/tests/core/test_types.py +356 -0
  563. sengol-0.8.0/tests/dataset/__init__.py +0 -0
  564. sengol-0.8.0/tests/dataset/test_loader.py +342 -0
  565. sengol-0.8.0/tests/dataset/test_registry.py +216 -0
  566. sengol-0.8.0/tests/evaluators/__init__.py +0 -0
  567. sengol-0.8.0/tests/evaluators/conftest.py +32 -0
  568. sengol-0.8.0/tests/evaluators/deterministic/__init__.py +0 -0
  569. sengol-0.8.0/tests/evaluators/deterministic/test_benchmark.py +91 -0
  570. sengol-0.8.0/tests/evaluators/deterministic/test_disclosure.py +131 -0
  571. sengol-0.8.0/tests/evaluators/deterministic/test_drift_monitor.py +79 -0
  572. sengol-0.8.0/tests/evaluators/deterministic/test_exact_match.py +53 -0
  573. sengol-0.8.0/tests/evaluators/deterministic/test_keyword.py +66 -0
  574. sengol-0.8.0/tests/evaluators/deterministic/test_pii.py +232 -0
  575. sengol-0.8.0/tests/evaluators/deterministic/test_regex.py +46 -0
  576. sengol-0.8.0/tests/evaluators/deterministic/test_response_length.py +54 -0
  577. sengol-0.8.0/tests/evaluators/deterministic/test_schema_validation.py +62 -0
  578. sengol-0.8.0/tests/evaluators/deterministic/test_trajectory.py +220 -0
  579. sengol-0.8.0/tests/evaluators/deterministic/test_unauthorized_delegation.py +88 -0
  580. sengol-0.8.0/tests/evaluators/llm/__init__.py +0 -0
  581. sengol-0.8.0/tests/evaluators/llm/test_adversarial_robustness.py +136 -0
  582. sengol-0.8.0/tests/evaluators/llm/test_explainability.py +152 -0
  583. sengol-0.8.0/tests/evaluators/llm/test_faithfulness.py +108 -0
  584. sengol-0.8.0/tests/evaluators/llm/test_groundedness.py +194 -0
  585. sengol-0.8.0/tests/evaluators/llm/test_hallucination.py +110 -0
  586. sengol-0.8.0/tests/evaluators/llm/test_pii_deprecation.py +60 -0
  587. sengol-0.8.0/tests/evaluators/llm/test_refusal.py +133 -0
  588. sengol-0.8.0/tests/evaluators/llm/test_relevance.py +189 -0
  589. sengol-0.8.0/tests/evaluators/llm/test_stubs.py +74 -0
  590. sengol-0.8.0/tests/evaluators/llm/test_toxicity.py +188 -0
  591. sengol-0.8.0/tests/evaluators/llm/test_trajectory.py +204 -0
  592. sengol-0.8.0/tests/evaluators/model/__init__.py +0 -0
  593. sengol-0.8.0/tests/evaluators/model/test_ab_evaluator.py +492 -0
  594. sengol-0.8.0/tests/evaluators/model/test_auc.py +190 -0
  595. sengol-0.8.0/tests/evaluators/model/test_champion_challenger.py +166 -0
  596. sengol-0.8.0/tests/evaluators/model/test_fairness.py +295 -0
  597. sengol-0.8.0/tests/evaluators/model/test_outcome_monitor.py +148 -0
  598. sengol-0.8.0/tests/evaluators/model/test_psi.py +226 -0
  599. sengol-0.8.0/tests/evaluators/redteam/__init__.py +0 -0
  600. sengol-0.8.0/tests/evaluators/redteam/test_base.py +133 -0
  601. sengol-0.8.0/tests/evaluators/redteam/test_garak_backend.py +78 -0
  602. sengol-0.8.0/tests/evaluators/test_ensemble.py +399 -0
  603. sengol-0.8.0/tests/fixtures/datasets/sample.csv +4 -0
  604. sengol-0.8.0/tests/fixtures/datasets/sample.jsonl +3 -0
  605. sengol-0.8.0/tests/fixtures/datasets/sample.parquet +0 -0
  606. sengol-0.8.0/tests/governance/__init__.py +0 -0
  607. sengol-0.8.0/tests/governance/test_audit_store.py +163 -0
  608. sengol-0.8.0/tests/governance/test_certification_store.py +172 -0
  609. sengol-0.8.0/tests/governance/test_controlbook_store.py +35 -0
  610. sengol-0.8.0/tests/governance/test_controlbook_validator.py +561 -0
  611. sengol-0.8.0/tests/governance/test_evidence_store.py +164 -0
  612. sengol-0.8.0/tests/governance/test_gold_score.py +235 -0
  613. sengol-0.8.0/tests/governance/test_gold_score_store.py +180 -0
  614. sengol-0.8.0/tests/governance/test_human_review_store.py +230 -0
  615. sengol-0.8.0/tests/governance/test_inmemory_report_store.py +187 -0
  616. sengol-0.8.0/tests/governance/test_license.py +101 -0
  617. sengol-0.8.0/tests/governance/test_report_base.py +778 -0
  618. sengol-0.8.0/tests/governance/test_report_enterprise.py +631 -0
  619. sengol-0.8.0/tests/governance/test_report_enterprise_8g.py +297 -0
  620. sengol-0.8.0/tests/governance/test_report_tenant_filter.py +149 -0
  621. sengol-0.8.0/tests/governance/test_saturation_store.py +147 -0
  622. sengol-0.8.0/tests/governance/test_word_boundary_matching.py +148 -0
  623. sengol-0.8.0/tests/instrument/__init__.py +0 -0
  624. sengol-0.8.0/tests/instrument/test_instrument.py +444 -0
  625. sengol-0.8.0/tests/integration/__init__.py +0 -0
  626. sengol-0.8.0/tests/integration/conftest.py +89 -0
  627. sengol-0.8.0/tests/integration/test_alembic_migrations.py +137 -0
  628. sengol-0.8.0/tests/integration/test_audit_store_postgres.py +77 -0
  629. sengol-0.8.0/tests/integration/test_gold_score_store_postgres.py +118 -0
  630. sengol-0.8.0/tests/integration/test_phase4_e2e.py +304 -0
  631. sengol-0.8.0/tests/integration/test_report_generate_postgres.py +168 -0
  632. sengol-0.8.0/tests/judges/__init__.py +0 -0
  633. sengol-0.8.0/tests/judges/test_anthropic.py +162 -0
  634. sengol-0.8.0/tests/judges/test_base.py +152 -0
  635. sengol-0.8.0/tests/judges/test_openai_compatible.py +193 -0
  636. sengol-0.8.0/tests/judges/test_prompt.py +116 -0
  637. sengol-0.8.0/tests/observability/test_config.py +175 -0
  638. sengol-0.8.0/tests/observability/test_linkage.py +169 -0
  639. sengol-0.8.0/tests/observability/test_spans.py +83 -0
  640. sengol-0.8.0/tests/observability/test_tracer.py +32 -0
  641. sengol-0.8.0/tests/policies/__init__.py +0 -0
  642. sengol-0.8.0/tests/policies/test_compiled.py +167 -0
  643. sengol-0.8.0/tests/policies/test_compiled_taxonomy.py +25 -0
  644. sengol-0.8.0/tests/policies/test_loader.py +180 -0
  645. sengol-0.8.0/tests/policies/test_osfi_e23_pack.py +185 -0
  646. sengol-0.8.0/tests/policies/test_report_metadata.py +103 -0
  647. sengol-0.8.0/tests/policies/test_taxonomy.py +92 -0
  648. sengol-0.8.0/tests/policies/test_us_treasury_pack.py +166 -0
  649. sengol-0.8.0/tests/runtime/__init__.py +0 -0
  650. sengol-0.8.0/tests/runtime/sampling/test_clustering_sampler.py +94 -0
  651. sengol-0.8.0/tests/runtime/test_async_eval_worker.py +272 -0
  652. sengol-0.8.0/tests/runtime/test_guardrail_capture.py +489 -0
  653. sengol-0.8.0/tests/runtime/test_guardrail_from_config.py +121 -0
  654. sengol-0.8.0/tests/runtime/test_guardrails.py +550 -0
  655. sengol-0.8.0/tests/runtime/test_inline_evaluator.py +261 -0
  656. sengol-0.8.0/tests/runtime/test_sampling.py +67 -0
  657. sengol-0.8.0/tests/runtime/test_sqs_eval_worker.py +289 -0
  658. sengol-0.8.0/tests/runtime/test_sqs_eval_worker_integration.py +111 -0
  659. sengol-0.8.0/tests/sinks/__init__.py +0 -0
  660. sengol-0.8.0/tests/sinks/test_dispatch.py +191 -0
  661. sengol-0.8.0/tests/sinks/test_import_boundary.py +95 -0
  662. sengol-0.8.0/tests/sinks/test_langfuse_sink.py +164 -0
  663. sengol-0.8.0/tests/sinks/test_otlp_sink.py +239 -0
  664. sengol-0.8.0/tests/sinks/test_registry.py +178 -0
  665. sengol-0.8.0/tests/suite/__init__.py +0 -0
  666. sengol-0.8.0/tests/suite/test_saturation_detector.py +69 -0
  667. sengol-0.8.0/tests/suite/test_suite.py +594 -0
  668. sengol-0.8.0/tests/synthetic/__init__.py +0 -0
  669. sengol-0.8.0/tests/synthetic/test_augment.py +100 -0
  670. sengol-0.8.0/tests/synthetic/test_generator.py +120 -0
  671. sengol-0.8.0/tests/test_adapters_and_exporters_demo.py +80 -0
  672. sengol-0.8.0/tests/test_api_eval_run_sink.py +209 -0
  673. sengol-0.8.0/tests/test_drift.py +1333 -0
  674. sengol-0.8.0/tests/test_end_to_end_demo.py +113 -0
  675. sengol-0.8.0/tests/test_eval_run_record.py +111 -0
  676. sengol-0.8.0/tests/test_eval_run_store.py +136 -0
  677. sengol-0.8.0/tests/test_governance_routes.py +247 -0
  678. sengol-0.8.0/tests/test_hash_chain.py +253 -0
  679. sengol-0.8.0/tests/test_idempotency.py +214 -0
  680. sengol-0.8.0/tests/test_logging.py +74 -0
  681. sengol-0.8.0/tests/test_run_suite_workload.py +769 -0
  682. sengol-0.8.0/tests/test_schema_versioning.py +234 -0
  683. sengol-0.8.0/tests/test_structured_logging.py +341 -0
  684. sengol-0.8.0/tests/trajectory/__init__.py +0 -0
  685. sengol-0.8.0/tests/trajectory/fixtures/openinference_trace.json +63 -0
  686. sengol-0.8.0/tests/trajectory/fixtures/otelgenai_trace.json +65 -0
  687. sengol-0.8.0/tests/trajectory/test_mapping_snapshot.py +122 -0
  688. sengol-0.8.0/uv.lock +6159 -0
@@ -0,0 +1,60 @@
1
+ ---
2
+ name: pr-review
3
+ description: Triage and resolve review comments on sengol/product PRs — gather (haiku) → decide FIX/REJECT/SKIP (opus) → implement (sonnet) → verify+ship (haiku). Use when a PR has review comments to work through. Args: one or more "<owner>/<repo>#<number>".
4
+ ---
5
+
6
+ # PR Review Triage — four stages, model pinned per stage
7
+
8
+ Cost rule: each stage runs on its named model. The expensive model (opus/fable) sees ONLY the
9
+ gathered comment list — never raw diffs or whole files. Announce the model switch before each
10
+ stage; if the harness can't switch models, say so and continue, keeping stage boundaries.
11
+
12
+ ## Stage 1 — GATHER (haiku). No judgments, no fixes, no file edits.
13
+
14
+ For each PR argument, fetch via GitHub MCP tools (fall back to `gh` with `--jq` only if MCP
15
+ is unavailable): review comment threads, review summaries, and issue comments.
16
+
17
+ Output ONE numbered list, grouped by repo:
18
+ ```
19
+ [N] repo · file:line · author · priority badge if present
20
+ verbatim body (strip bot boilerplate/badges)
21
+ type: question / requested-change / suggestion / nit / informational
22
+ ```
23
+ End with counts by type. STOP — next stage decides.
24
+
25
+ ## Stage 2 — DECIDE (opus or fable). One verdict per item: FIX / REJECT / SKIP.
26
+
27
+ Decide against the session brief (product `phases/phase-<N>/session-<Nx>.md`) and the repo
28
+ invariants. Standing REJECT grounds:
29
+ - **Out of scope** — expands into another session's territory (cite the brief).
30
+ - **Invariant violation** — would weaken: binary `EvalScore.passed` (Rule 2); ControlBook
31
+ drives reports (Rule 4); ADR-0052 store boundary; append-only AuditStore + HMAC payload
32
+ scope; sinks/exporters never fail the gate or add latency; credentials from env only,
33
+ never `sengol.yaml`; `...` is valid in Protocol bodies (PEP 544).
34
+ - **Vendor brokering** — Sengol never maps/holds vendor credentials.
35
+
36
+ Standing SKIP: bot overview wrappers, duplicates, pure informational.
37
+
38
+ Output a decision table (#, item, verdict, one-sentence action or reply), flag the 2–3
39
+ riskiest FIXes, then STOP for the user's approval. **If zero FIXes: recommend merging and
40
+ stop — do not run stages 3–4.**
41
+
42
+ ## Stage 3 — IMPLEMENT (sonnet). Only after explicit approval.
43
+
44
+ - Trivial fixes first, then functional. Touch only files the comments implicate.
45
+ - Post each approved REJECT reply verbatim on its thread (one comment per thread, never a
46
+ new thread). SKIPs stay silent.
47
+ - Test rules: no full-suite runs while iterating; SSE/streaming tested via the async
48
+ generator with bounded reads + `aclose()` — never GET through TestClient; never "fix" a
49
+ hang by raising a timeout.
50
+ - When all fixes are written: STOP. Stage 4 verifies.
51
+
52
+ ## Stage 4 — VERIFY + SHIP (haiku).
53
+
54
+ 1. Changed test files only, each bounded:
55
+ `uv run pytest <files> -q --timeout=30 -p no:cacheprovider` (never pipe through tail/head).
56
+ 2. Green → full fast suite ONCE (`-m "not llm and not integration"`) + `npx vitest run` ONCE
57
+ if frontend files changed.
58
+ 3. Push (the PR updates automatically), confirm CI green via MCP check-runs, report a
59
+ one-line status per PR. A code fix needed mid-verify goes back to Stage 3 — never fixed
60
+ on haiku. If still red after one full pass: STOP and report the failure output verbatim.
@@ -0,0 +1,134 @@
1
+ # Sengol v3.6 — Cursor Rules (Phases 1–2)
2
+
3
+ ## Identity
4
+ Sengol — Apache 2.0 Python 3.12 SDK. AI governance for regulated financial institutions.
5
+ Building Phases 1–2: SDK core + OSFI E-23 PDF compliance report.
6
+
7
+ ## Critical Rules — Never Violate
8
+
9
+ ### 1. PolicyId is open str — NEVER Literal
10
+ ```python
11
+ # ✓ CORRECT — any org can define their own
12
+ PolicyId = str # "OSFI_E23", "MY_BANK_POLICY_V3", "MAS_TRM" all valid
13
+
14
+ # ✗ WRONG — breaks for Singapore, Saudi, Indian banks
15
+ PolicyId = Literal["OSFI_E23", "FINTRAC_6F"]
16
+ ```
17
+
18
+ ### 2. EvalScore.passed is binary bool — NEVER float
19
+ ```python
20
+ # ✓ CORRECT
21
+ EvalScore(passed=True, failure_mode=None)
22
+ EvalScore(passed=False, failure_mode="REQUIRED_DISCLOSURE_MISSING")
23
+
24
+ # ✗ WRONG
25
+ EvalScore(score=0.87) # NEVER — pre-commit blocks this
26
+ ```
27
+
28
+ ### 3. Deterministic before LLM — asyncio.gather() for LLM
29
+ ```python
30
+ # EvalSuite runs in this order:
31
+ # 1. All DeterministicEvaluator — sync, <1ms, no API
32
+ # 2. Short-circuit if CRITICAL failure (skip LLM)
33
+ # 3. All LLMEvaluator — asyncio.gather() — O(1) not O(n)
34
+ ```
35
+
36
+ ### 4. ControlBook drives reports — never bypass it
37
+ ```python
38
+ # ✓ CORRECT — works for any regulation
39
+ ComplianceReportGenerator(controlbook=controlbook).generate(agent_id, period)
40
+
41
+ # ✗ WRONG — hardcoded, breaks for non-OSFI customers
42
+ OSFIReportGenerator().generate(agent_id, period)
43
+ ```
44
+
45
+ ### 5. Audit records: sign before write, append-only
46
+ ```python
47
+ # ✓ CORRECT
48
+ signed = record.sign(signing_key)
49
+ await audit_store.write(signed)
50
+
51
+ # ✗ WRONG — audit_store has no update() method
52
+ await audit_store.update(record_id, new_data)
53
+ ```
54
+
55
+ ## Code Patterns to Suggest
56
+
57
+ ### Deterministic evaluator skeleton
58
+ ```python
59
+ from sengol.core.evaluator import DeterministicEvaluator
60
+ from sengol.core.types import LLMEvalInput, EvalScore
61
+
62
+ class RequiredDisclosureEvaluator(DeterministicEvaluator):
63
+ """Checks OSFI E-23 required disclosure phrases. Observed at: Canadian retail bank."""
64
+ name = "RequiredDisclosureEvaluator"
65
+ failure_mode = "REQUIRED_DISCLOSURE_MISSING"
66
+ policies: list[str] = ["OSFI_E23"]
67
+ version: str = "1.0.0"
68
+
69
+ def evaluate(self, input: LLMEvalInput) -> EvalScore:
70
+ passed = "not a guarantee" in input.response.lower()
71
+ return EvalScore(
72
+ evaluator=self.name,
73
+ passed=passed,
74
+ failure_mode=None if passed else self.failure_mode,
75
+ reason="Disclosure present" if passed else "Missing required disclosure",
76
+ )
77
+ ```
78
+
79
+ ### LLM evaluator stub (Phase 1)
80
+ ```python
81
+ class FaithfulnessEvaluator(LLMEvaluator):
82
+ name = "FaithfulnessEvaluator"
83
+ failure_mode = "FAITHFULNESS_FAILURE"
84
+ policies: list[str] = ["OSFI_E23"]
85
+
86
+ async def evaluate_async(self, input: LLMEvalInput) -> EvalScore:
87
+ # Phase 1 stub — Phase 3 wires real LLM judge
88
+ return EvalScore(evaluator=self.name, passed=True, failure_mode=None)
89
+ ```
90
+
91
+ ### AuditRecord (sign before write)
92
+ ```python
93
+ signed = record.sign(os.getenv("SENGOL_SIGNING_KEY"))
94
+ await audit_store.write(signed)
95
+ assert await audit_store.verify(signed.record_id)
96
+ ```
97
+
98
+ ### ControlBook-driven report
99
+ ```python
100
+ report = ComplianceReportGenerator(
101
+ audit_store=audit_store,
102
+ controlbook=controlbook,
103
+ ).generate(
104
+ agent_id="rag-advisor-001",
105
+ period_from=datetime(2026, 1, 1),
106
+ period_to=datetime(2026, 5, 1),
107
+ )
108
+ # report.pdf_path — hand to CRO
109
+ # report.json_path — machine-readable evidence
110
+ ```
111
+
112
+ ## Never Suggest
113
+ - `PolicyId = Literal[...]` — must be `str`
114
+ - `EvalScore(score=0.87)` — float primary output
115
+ - `print()` — use `structlog`
116
+ - `logging.basicConfig()` — use `structlog`
117
+ - Sequential LLM evaluator calls — use `asyncio.gather()`
118
+ - `UPDATE` or `DELETE` on `audit_records`
119
+ - Hardcoded OSFI-only report generator
120
+ - `import openai` — respect `ControlBook.judge_by_tier`
121
+
122
+ ## File Locations
123
+ - New evaluator → `sengol/evaluators/{deterministic|llm}/{name}.py`
124
+ - New type → `sengol/core/types.py` (check spec §5 first)
125
+ - New API route → `sengol/api/routes/{name}.py`
126
+ - New CLI command → `sengol/cli/main.py` (Typer)
127
+ - Policy catalog → `sengol/policies/catalog.yaml`
128
+
129
+ ## Logging
130
+ ```python
131
+ import structlog
132
+ log = structlog.get_logger()
133
+ log.info("eval.complete", evaluator="MyEval", passed=True, latency_ms=12)
134
+ ```
@@ -0,0 +1,16 @@
1
+ # Files excluded from the Docker build context.
2
+ #
3
+ # IMPORTANT: do NOT add `*.md` or `README.md` here — the Dockerfile COPYs
4
+ # `README.md` and uv requires it to resolve the package metadata.
5
+
6
+ .git
7
+ .github
8
+ .claude
9
+ .pytest_cache
10
+ .ruff_cache
11
+ .venv
12
+ .coverage
13
+ **/__pycache__
14
+ *.pyc
15
+ tests
16
+ docs
@@ -0,0 +1,92 @@
1
+ # GitHub Copilot — sengol (Phases 1–2)
2
+ # .github/copilot-instructions.md
3
+
4
+ ## Project
5
+ Sengol — Apache 2.0 Python 3.12 SDK for AI governance in regulated financial institutions.
6
+ Building Phases 1–2: SDK core → OSFI E-23 compliance PDF report.
7
+
8
+ ## Always Suggest
9
+
10
+ ### Evaluator pattern (deterministic — no LLM)
11
+ ```python
12
+ from sengol.core.evaluator import DeterministicEvaluator
13
+ from sengol.core.types import LLMEvalInput, EvalScore
14
+
15
+ class RequiredDisclosureEvaluator(DeterministicEvaluator):
16
+ """Checks OSFI E-23 required disclosure phrases are present. Observed at: Canadian retail bank."""
17
+ name = "RequiredDisclosureEvaluator"
18
+ failure_mode = "REQUIRED_DISCLOSURE_MISSING"
19
+ policies: list[str] = ["OSFI_E23"] # list of str — not Literal
20
+
21
+ def evaluate(self, input: LLMEvalInput) -> EvalScore:
22
+ passed = "not a guarantee" in input.response.lower()
23
+ return EvalScore(
24
+ evaluator=self.name,
25
+ passed=passed, # bool — always
26
+ failure_mode=None if passed else self.failure_mode,
27
+ reason="Disclosure present" if passed else "Missing required disclosure",
28
+ )
29
+ ```
30
+
31
+ ### LLM evaluator stub pattern (Phase 1)
32
+ ```python
33
+ class FaithfulnessEvaluator(LLMEvaluator):
34
+ name = "FaithfulnessEvaluator"
35
+ failure_mode = "FAITHFULNESS_FAILURE"
36
+ policies: list[str] = ["OSFI_E23"]
37
+
38
+ async def evaluate_async(self, input: LLMEvalInput) -> EvalScore:
39
+ # Phase 1: stub — returns True
40
+ # Phase 3: wire real LLM judge here
41
+ return EvalScore(evaluator=self.name, passed=True, failure_mode=None)
42
+ ```
43
+
44
+ ### AuditRecord write (always sign before write)
45
+ ```python
46
+ signed = record.sign(os.getenv("SENGOL_SIGNING_KEY"))
47
+ await audit_store.write(signed) # only write signed records
48
+ # verify immediately after
49
+ assert await audit_store.verify(signed.record_id)
50
+ ```
51
+
52
+ ### ControlBook-driven report
53
+ ```python
54
+ # Always ControlBook-driven — works for any regulation
55
+ report = ComplianceReportGenerator(
56
+ audit_store=audit_store,
57
+ controlbook=controlbook, # loads from acme_controlbook.yaml
58
+ ).generate(agent_id="rag-advisor-001", period_from=..., period_to=...)
59
+ # report.pdf_path — hand to CRO
60
+ # report.json_path — machine-readable evidence
61
+ ```
62
+
63
+ ### Logging
64
+ ```python
65
+ import structlog
66
+ log = structlog.get_logger()
67
+ log.info("eval.complete", evaluator="MyEval", passed=True, latency_ms=12)
68
+ ```
69
+
70
+ ## Never Suggest
71
+
72
+ - `PolicyId = Literal["OSFI_E23", ...]` — it must be `str`
73
+ - Float as `EvalScore.passed` — always `bool`
74
+ - `print()` for logging — always `structlog`
75
+ - Sequential LLM evaluator calls — always `asyncio.gather()`
76
+ - `UPDATE` or `DELETE` on `audit_records` table
77
+ - Hardcoded OSFI-only reports — use `ComplianceReportGenerator(controlbook=...)`
78
+ - `import openai` — for judge calls, respect `ControlBook.judge_by_tier`
79
+
80
+ ## Test Pattern
81
+ ```python
82
+ @pytest.mark.asyncio
83
+ async def test_evaluator_fails_missing_disclosure():
84
+ ev = RequiredDisclosureEvaluator()
85
+ result = ev.evaluate(LLMEvalInput(
86
+ agent_id="test", agent_version="1.0",
87
+ prompt="What should I know?",
88
+ response="Buy this fund now.", # missing disclosure
89
+ ))
90
+ assert result.passed is False
91
+ assert result.failure_mode == "REQUIRED_DISCLOSURE_MISSING"
92
+ ```
@@ -0,0 +1,84 @@
1
+ name: ci
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ ci:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - name: Install uv
15
+ uses: astral-sh/setup-uv@v3
16
+ with:
17
+ enable-cache: true
18
+ - name: Set up Python
19
+ run: uv python install 3.11
20
+ - name: Install dependencies
21
+ run: uv sync --all-extras
22
+ - name: Lint
23
+ run: uv run ruff check .
24
+ - name: Format check
25
+ run: uv run ruff format --check .
26
+ - name: Fast tests
27
+ run: uv run pytest -v -m "not llm and not integration"
28
+ - name: Generate OpenAPI spec
29
+ env:
30
+ SENGOL_SIGNING_KEY: ci-placeholder
31
+ SENGOL_AUDIT_URI: memory://
32
+ run: |
33
+ uv run python -c "
34
+ import yaml
35
+ from sengol.api.app import app
36
+ with open('sengol/api/openapi_ci.yaml', 'w') as f:
37
+ yaml.safe_dump(app.openapi(), f, sort_keys=False, allow_unicode=True, width=120)
38
+ "
39
+ - name: Check for breaking API changes (ADR-0057)
40
+ uses: tufin/oasdiff-action@v1
41
+ with:
42
+ base: sengol/api/openapi.yaml
43
+ revision: sengol/api/openapi_ci.yaml
44
+ fail-on-diff: breaking
45
+
46
+ terraform-plan:
47
+ runs-on: ubuntu-latest
48
+ defaults:
49
+ run:
50
+ working-directory: terraform/aws
51
+ steps:
52
+ - uses: actions/checkout@v4
53
+ - name: Set up Terraform
54
+ uses: hashicorp/setup-terraform@v3
55
+ with:
56
+ terraform_version: "1.9.8"
57
+ - name: Terraform init
58
+ run: terraform init -backend=false -input=false
59
+ - name: Terraform validate
60
+ run: terraform validate
61
+ - name: Terraform fmt check
62
+ run: terraform fmt -check -recursive
63
+ - name: Terraform plan (no apply — mock credentials baked into providers.tf)
64
+ run: terraform plan -var-file=environments/dev.tfvars -input=false
65
+
66
+ frontend:
67
+ runs-on: ubuntu-latest
68
+ defaults:
69
+ run:
70
+ working-directory: console
71
+ steps:
72
+ - uses: actions/checkout@v4
73
+ - name: Set up Node
74
+ uses: actions/setup-node@v4
75
+ with:
76
+ node-version: 20
77
+ cache: npm
78
+ cache-dependency-path: console/package-lock.json
79
+ - name: Install dependencies
80
+ run: npm ci
81
+ - name: Test
82
+ run: npm test
83
+ - name: Build
84
+ run: npm run build
@@ -0,0 +1,86 @@
1
+ name: Deploy
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ workflow_dispatch:
8
+ inputs:
9
+ environment:
10
+ description: "Target environment"
11
+ required: true
12
+ default: staging
13
+ type: choice
14
+ options:
15
+ - dev
16
+ - staging
17
+ - production
18
+
19
+ permissions:
20
+ id-token: write
21
+ contents: read
22
+
23
+ jobs:
24
+ deploy:
25
+ name: Deploy to ${{ github.event_name == 'workflow_dispatch' && inputs.environment || 'staging' }}
26
+ runs-on: ubuntu-latest
27
+ environment: ${{ inputs.environment || 'staging' }}
28
+
29
+ env:
30
+ DEPLOY_ENV: ${{ github.event_name == 'workflow_dispatch' && inputs.environment || 'staging' }}
31
+
32
+ steps:
33
+ - name: Checkout
34
+ uses: actions/checkout@v4
35
+
36
+ - name: Configure AWS credentials (OIDC)
37
+ uses: aws-actions/configure-aws-credentials@v4
38
+ with:
39
+ role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
40
+ aws-region: ${{ secrets.KUBE_CLUSTER_REGION }}
41
+
42
+ - name: Login to Amazon ECR
43
+ id: ecr-login
44
+ uses: aws-actions/amazon-ecr-login@v2
45
+
46
+ - name: Build and push Docker image to ECR
47
+ env:
48
+ IMAGE_URI: ${{ secrets.ECR_REGISTRY }}/${{ secrets.ECR_REPOSITORY }}:${{ github.sha }}
49
+ run: |
50
+ docker build -t "${IMAGE_URI}" .
51
+ docker push "${IMAGE_URI}"
52
+ echo "image_uri=${IMAGE_URI}" >> "${GITHUB_OUTPUT}"
53
+ id: build
54
+
55
+ - name: Set up kubectl
56
+ uses: azure/setup-kubectl@v3
57
+
58
+ - name: Set up Helm
59
+ uses: azure/setup-helm@v3
60
+ with:
61
+ version: v3.14.0
62
+
63
+ - name: Update kubeconfig for EKS
64
+ run: |
65
+ aws eks update-kubeconfig \
66
+ --name ${{ secrets.KUBE_CLUSTER_NAME }} \
67
+ --region ${{ secrets.KUBE_CLUSTER_REGION }}
68
+
69
+ - name: Helm upgrade/install
70
+ run: |
71
+ helm upgrade --install sengol ./helm/sengol \
72
+ --namespace sengol \
73
+ --create-namespace \
74
+ -f helm/sengol/values-aws.yaml \
75
+ --set image.repository=${{ secrets.ECR_REGISTRY }}/${{ secrets.ECR_REPOSITORY }} \
76
+ --set image.tag=${{ github.sha }} \
77
+ --set secrets.SENGOL_SIGNING_KEY="${{ secrets.SENGOL_SIGNING_KEY }}" \
78
+ --set secrets.SENGOL_KMS_KEY_ID="${{ secrets.SENGOL_KMS_KEY_ID }}" \
79
+ --set config.SENGOL_AWS_REGION=${{ secrets.KUBE_CLUSTER_REGION }} \
80
+ --wait --timeout 5m
81
+
82
+ - name: Smoke test
83
+ run: |
84
+ SENGOL_URL="${{ secrets.SENGOL_URL }}"
85
+ curl --fail --retry 3 --retry-delay 5 "${SENGOL_URL}/health"
86
+ echo "Smoke test passed"
@@ -0,0 +1,70 @@
1
+ name: Integration tests (Postgres)
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths:
7
+ - 'sengol/core/types.py'
8
+ - 'sengol/governance/audit_store.py'
9
+ - 'sengol/governance/gold_score_store.py'
10
+ - 'sengol/governance/saturation_store.py'
11
+ - 'sengol/governance/report_base.py'
12
+ - 'sengol/cli/main.py'
13
+ - 'sengol/logging.py'
14
+ - 'alembic/**'
15
+ - 'tests/integration/**'
16
+ pull_request:
17
+ paths:
18
+ - 'sengol/core/types.py'
19
+ - 'sengol/governance/audit_store.py'
20
+ - 'sengol/governance/gold_score_store.py'
21
+ - 'sengol/governance/saturation_store.py'
22
+ - 'sengol/governance/report_base.py'
23
+ - 'sengol/cli/main.py'
24
+ - 'sengol/logging.py'
25
+ - 'alembic/**'
26
+ - 'tests/integration/**'
27
+
28
+ jobs:
29
+ integration:
30
+ runs-on: ubuntu-latest
31
+
32
+ services:
33
+ postgres:
34
+ image: postgres:16
35
+ env:
36
+ POSTGRES_USER: sengol
37
+ POSTGRES_PASSWORD: sengol
38
+ POSTGRES_DB: sengol_test
39
+ ports:
40
+ - 5432:5432
41
+ options: >-
42
+ --health-cmd pg_isready
43
+ --health-interval 10s
44
+ --health-timeout 5s
45
+ --health-retries 5
46
+
47
+ env:
48
+ SENGOL_AUDIT_URI: postgresql+asyncpg://sengol:sengol@localhost:5432/sengol_test
49
+ SENGOL_SIGNING_KEY: test-signing-key-32-bytes-minimum
50
+ SENGOL_ENVIRONMENT: development
51
+
52
+ steps:
53
+ - uses: actions/checkout@v4
54
+
55
+ - name: Install uv
56
+ uses: astral-sh/setup-uv@v3
57
+ with:
58
+ enable-cache: true
59
+
60
+ - name: Set up Python
61
+ run: uv python install 3.11
62
+
63
+ - name: Install dependencies
64
+ run: uv sync --all-extras
65
+
66
+ - name: Run Alembic migrations
67
+ run: uv run alembic upgrade head
68
+
69
+ - name: Run integration tests
70
+ run: uv run pytest tests/integration/ -v --tb=short -m integration
@@ -0,0 +1,41 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+ workflow_dispatch:
7
+
8
+ permissions:
9
+ id-token: write # required for PyPI OIDC trusted publisher
10
+ contents: read
11
+
12
+ jobs:
13
+ publish:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - name: Install uv
19
+ uses: astral-sh/setup-uv@v3
20
+ with:
21
+ enable-cache: true
22
+
23
+ - name: Set up Python
24
+ run: uv python install 3.11
25
+
26
+ - name: Install dependencies
27
+ run: uv sync --all-extras
28
+
29
+ - name: Build
30
+ run: uv build
31
+
32
+ - name: Publish to PyPI
33
+ run: uv publish
34
+ # uv publish defaults to PyPI and auto-uses the OIDC token from Actions.
35
+ # No UV_PUBLISH_URL or UV_PUBLISH_TOKEN needed.
36
+ #
37
+ # One-time setup required on pypi.org (per account):
38
+ # Account -> Publishing -> Add pending publisher
39
+ # GitHub owner: sengol-io
40
+ # repo: sengol
41
+ # workflow: publish.yml
@@ -0,0 +1,48 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ /build/
8
+ /dist/
9
+ *.egg-info/
10
+ .eggs/
11
+
12
+ # Virtual environments
13
+ .venv/
14
+ venv/
15
+ env/
16
+
17
+ # Testing & coverage
18
+ .pytest_cache/
19
+ .coverage
20
+ .coverage.*
21
+ htmlcov/
22
+ coverage.xml
23
+ .hypothesis/
24
+
25
+ # Editors / OS
26
+ .DS_Store
27
+ .idea/
28
+ .vscode/
29
+ *.swp
30
+
31
+ # Secrets / env
32
+ .env
33
+ .env.local
34
+ *.pem
35
+
36
+ # Demo + run artifacts (regenerated by examples/demo_end_to_end.py)
37
+ /reports/
38
+ /datasets/
39
+ /eval-results.xml
40
+
41
+ # Claude (local settings stay ignored; versioned skills are tracked)
42
+ .claude/*
43
+ !.claude/skills/
44
+
45
+ # Console frontend (built assets ship in wheel, not committed)
46
+ console/node_modules/
47
+ sengol/console_static/
48
+ console/*.tsbuildinfo
sengol-0.8.0/.mcp.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "mcpServers": {
3
+ "filesystem": {
4
+ "command": "npx",
5
+ "args": ["-y", "@modelcontextprotocol/server-filesystem", "."],
6
+ "description": "Read sengol.yaml, catalog.yaml, source files"
7
+ },
8
+ "github": {
9
+ "command": "npx",
10
+ "args": ["-y", "@modelcontextprotocol/server-github"],
11
+ "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}" },
12
+ "description": "Create PRs, manage issues, read commits"
13
+ },
14
+ "postgres": {
15
+ "command": "npx",
16
+ "args": ["-y", "@modelcontextprotocol/server-postgres", "${SENGOL_AUDIT_URI}"],
17
+ "description": "Query AuditStore, verify HMAC records"
18
+ },
19
+ "memory": {
20
+ "command": "npx",
21
+ "args": ["-y", "@modelcontextprotocol/server-memory"],
22
+ "description": "Persist phase state across Claude Code sessions"
23
+ },
24
+ "sequential-thinking": {
25
+ "command": "npx",
26
+ "args": ["-y", "@modelcontextprotocol/server-sequential-thinking"],
27
+ "description": "Multi-step phase builds — plan before implementing"
28
+ }
29
+ }
30
+ }