sqlguard-ninja 0.1.1__tar.gz → 0.2.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 (150) hide show
  1. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/CHANGELOG.md +24 -0
  2. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/PKG-INFO +22 -20
  3. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/README.md +21 -19
  4. {sqlguard_ninja-0.1.1/benchmarks/results/v1.0.0 → sqlguard_ninja-0.2.0/benchmarks/baselines}/native.json +4844 -1315
  5. sqlguard_ninja-0.2.0/benchmarks/datasets/v1/LABEL_CHANGES.yaml +22 -0
  6. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/04_privacy.yaml +5 -4
  7. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/05_tenant_isolation.yaml +5 -2
  8. sqlguard_ninja-0.2.0/benchmarks/datasets/v1/cases/08_lineage.yaml +150 -0
  9. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/manifest.yaml +1 -1
  10. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/agent-sql-guard.csv +1045 -0
  11. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/agent-sql-guard.json +20184 -0
  12. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/agent-sql-guard.md +110 -0
  13. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/krish2105-sqlguard.csv +1045 -0
  14. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/krish2105-sqlguard.json +20121 -0
  15. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/krish2105-sqlguard.md +110 -0
  16. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/native.csv +1045 -0
  17. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/native.json +20484 -0
  18. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/native.md +78 -0
  19. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/sql-guardrail.csv +1045 -0
  20. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/sql-guardrail.json +20779 -0
  21. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/sql-guardrail.md +103 -0
  22. sqlguard_ninja-0.2.0/docs/benchmarks/RESULTS_v1.1.md +48 -0
  23. sqlguard_ninja-0.2.0/docs/development/ARCHITECTURE_MAP.md +47 -0
  24. sqlguard_ninja-0.2.0/docs/development/DECISION_LOG.md +9 -0
  25. sqlguard_ninja-0.2.0/docs/development/IMPLEMENTATION_PROGRESS.md +7 -0
  26. sqlguard_ninja-0.2.0/docs/development/NEXT_ACTIONS.md +5 -0
  27. sqlguard_ninja-0.2.0/docs/development/TEST_EVIDENCE.md +7 -0
  28. sqlguard_ninja-0.2.0/docs/development/UPGRADE_MASTER_PLAN.md +25 -0
  29. sqlguard_ninja-0.2.0/docs/development/progress.json +106 -0
  30. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/guides/BENCHMARK_BIAS_REVIEW.md +1 -1
  31. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/guides/BENCHMARK_METHODOLOGY.md +7 -4
  32. sqlguard_ninja-0.2.0/docs/releases/v0.2.0.md +27 -0
  33. sqlguard_ninja-0.2.0/src/sqlguard_ninja/_version.py +1 -0
  34. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/compare.py +8 -1
  35. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/dataset.py +38 -2
  36. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/metrics.py +66 -2
  37. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/runner.py +35 -0
  38. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/cli/config.py +2 -0
  39. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/cli/main.py +34 -5
  40. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/analysis.py +9 -1
  41. sqlguard_ninja-0.2.0/src/sqlguard_ninja/core/lineage.py +199 -0
  42. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/tenant.py +56 -25
  43. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/privacy/rules.py +53 -14
  44. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/reporting/markdown.py +36 -5
  45. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/unit/test_benchmark_engine.py +77 -0
  46. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/unit/test_cli.py +47 -0
  47. sqlguard_ninja-0.2.0/tests/unit/test_lineage.py +84 -0
  48. sqlguard_ninja-0.1.1/src/sqlguard_ninja/_version.py +0 -1
  49. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/.gitignore +0 -0
  50. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/LICENSE +0 -0
  51. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/THIRD_PARTY_NOTICES.md +0 -0
  52. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/external/README.md +0 -0
  53. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/01_destructive.yaml +0 -0
  54. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/02_multi_statement_and_formatting.yaml +0 -0
  55. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/03_table_and_column_access.yaml +0 -0
  56. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/06_cte_nested_unicode.yaml +0 -0
  57. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/07_legitimate_lookalike_cost_dialect.yaml +0 -0
  58. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/generated/grant_matrix.yaml +0 -0
  59. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/generated/label_matrix.yaml +0 -0
  60. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/generated/tenant_matrix.yaml +0 -0
  61. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/generated/transforms.yaml +0 -0
  62. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/policies/retail_saas.yaml +0 -0
  63. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/agent-sql-guard.json +0 -0
  64. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/agent-sql-guard.md +0 -0
  65. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/krish2105-sqlguard.json +0 -0
  66. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/krish2105-sqlguard.md +0 -0
  67. {sqlguard_ninja-0.1.1/benchmarks/baselines → sqlguard_ninja-0.2.0/benchmarks/results/v1.0.0}/native.json +0 -0
  68. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/native.md +0 -0
  69. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/sql-guardrail.json +0 -0
  70. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/sql-guardrail.md +0 -0
  71. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/architecture/ARCHITECTURE_DECISIONS.md +0 -0
  72. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/benchmarks/RESULTS_v1.md +0 -0
  73. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/guides/AGENT_INTEGRATION.md +0 -0
  74. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/guides/CI_INTEGRATION.md +0 -0
  75. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/guides/POLICY_REFERENCE.md +0 -0
  76. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/guides/QUERY_COST.md +0 -0
  77. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/release/FINAL_TECHNICAL_AUDIT.md +0 -0
  78. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/releases/v0.1.0.md +0 -0
  79. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/releases/v0.1.1.md +0 -0
  80. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/research/COMPETITIVE_ANALYSIS.md +0 -0
  81. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/security/STATIC_ANALYSIS_LIMITS.md +0 -0
  82. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/docs/security/THREAT_MODEL.md +0 -0
  83. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/examples/_shared.py +0 -0
  84. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/examples/fastapi/app.py +0 -0
  85. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/examples/github-actions/sql-security.yml +0 -0
  86. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/examples/langchain/guarded_tool_demo.py +0 -0
  87. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/examples/langgraph/real_llm_agent.py +0 -0
  88. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/examples/langgraph/sql_agent_demo.py +0 -0
  89. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/examples/postgresql/plan_inspection_demo.py +0 -0
  90. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/examples/sdk/quickstart.py +0 -0
  91. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/examples/sqlite/text_to_sql_demo.py +0 -0
  92. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/pyproject.toml +0 -0
  93. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/__init__.py +0 -0
  94. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/__init__.py +0 -0
  95. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/adapters.py +0 -0
  96. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/builtin.py +0 -0
  97. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/fixtures.py +0 -0
  98. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/translate.py +0 -0
  99. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/workers/_protocol.py +0 -0
  100. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/workers/agent_sql_guard_worker.py +0 -0
  101. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/workers/krish_sqlguard_worker.py +0 -0
  102. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/workers/sql_guardrail_worker.py +0 -0
  103. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/cli/__init__.py +0 -0
  104. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/cli/templates.py +0 -0
  105. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/__init__.py +0 -0
  106. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/findings.py +0 -0
  107. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/guard.py +0 -0
  108. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/__init__.py +0 -0
  109. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/access.py +0 -0
  110. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/base.py +0 -0
  111. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/catalog.py +0 -0
  112. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/functions.py +0 -0
  113. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/statements.py +0 -0
  114. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/structure.py +0 -0
  115. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/__init__.py +0 -0
  116. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/audit.py +0 -0
  117. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/checkpoint.py +0 -0
  118. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/executors.py +0 -0
  119. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/fastapi.py +0 -0
  120. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/langchain.py +0 -0
  121. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/langgraph.py +0 -0
  122. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/policy/__init__.py +0 -0
  123. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/policy/model.py +0 -0
  124. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/privacy/__init__.py +0 -0
  125. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/privacy/suggest.py +0 -0
  126. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/py.typed +0 -0
  127. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/query_cost/__init__.py +0 -0
  128. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/query_cost/postgres.py +0 -0
  129. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/query_cost/static.py +0 -0
  130. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/reporting/__init__.py +0 -0
  131. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/__init__.py +0 -0
  132. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/conftest.py +0 -0
  133. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/integration/__init__.py +0 -0
  134. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/integration/test_corpus_sqlite_validation.py +0 -0
  135. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/integration/test_external_adapters.py +0 -0
  136. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/integration/test_frameworks.py +0 -0
  137. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/integration/test_postgres.py +0 -0
  138. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/pg_support.py +0 -0
  139. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/property/__init__.py +0 -0
  140. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/property/test_guard_properties.py +0 -0
  141. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/security/__init__.py +0 -0
  142. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/security/test_agent_boundaries.py +0 -0
  143. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/security/test_corpus_native.py +0 -0
  144. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/unit/__init__.py +0 -0
  145. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/unit/helpers.py +0 -0
  146. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/unit/test_dataset.py +0 -0
  147. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/unit/test_docs.py +0 -0
  148. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/unit/test_function_policy_mechanics.py +0 -0
  149. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/unit/test_policy.py +0 -0
  150. {sqlguard_ninja-0.1.1 → sqlguard_ninja-0.2.0}/tests/unit/test_rules.py +0 -0
@@ -3,6 +3,30 @@
3
3
  All notable changes are documented here. The project follows
4
4
  [Semantic Versioning](https://semver.org/); before 1.0, minor versions may change the API.
5
5
 
6
+ ## [0.2.0] — 2026-10-24
7
+
8
+ ### Added
9
+ * **Lineage-aware privacy** (`core/lineage.py`). An `aggregate_only` column projected raw in a
10
+ CTE or derived table is accepted only when every downstream consumer aggregates it
11
+ statistically. Whole-row use, filters, ordering, windows, MIN/MAX and a raw use by any
12
+ consumer stay denied (issue #8).
13
+ * **Tenant push-down.** An outer tenant pin on an unmodified projection of the tenant column
14
+ satisfies the inner read when the inner scope has no aggregation, window, LIMIT, OFFSET or
15
+ FETCH and every consumer pins it, recursively (issue #9).
16
+ * The small-cohort check follows identifiers through CTEs and derived tables, so the lineage
17
+ relaxation cannot bypass it (found by new boundary case LIN-012).
18
+ * Privacy findings carry structured lineage metadata (base column, JSON path, scope, labels).
19
+ * Benchmark: `internal` / `independent` dataset tiers, flag basis (policy vs unsupported SQL),
20
+ F1, 95% Wilson intervals, throughput, CSV output (`--csv`), per-file SHA-256 dataset hashes
21
+ in results and `sqlninja dataset stats`.
22
+ * Approved-relabel workflow: `LABEL_CHANGES.yaml` (CODEOWNERS-protected) lists reviewed label
23
+ changes; `benchmark compare --approved-label-changes` / `ci.approved_label_changes`.
24
+ * Corpus 1.1.0: 21 lineage boundary cases; 2 approved relabels (PRV-026, TEN-021).
25
+
26
+ ### Changed
27
+ * Decisions changed for exactly two corpus cases (PRV-026, TEN-021: deny → allow); all other
28
+ 1,042 evaluations are unchanged.
29
+
6
30
  ## [0.1.1] — 2026-10-24
7
31
 
8
32
  Documentation and governance patch. No changes to policy decisions.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: sqlguard-ninja
3
- Version: 0.1.1
3
+ Version: 0.2.0
4
4
  Summary: Security testing, policy enforcement, agent integration, privacy analysis and CI benchmarking for LLM-generated SQL.
5
5
  Project-URL: Homepage, https://github.com/Pratik653/SQLGuard_Ninjapy
6
6
  Project-URL: Documentation, https://github.com/Pratik653/SQLGuard_Ninjapy/tree/main/docs
@@ -70,7 +70,7 @@ the *authenticated* caller: which tables and columns a role may use, which data
70
70
  appear only in aggregates or only after human approval, and which tenant the caller belongs
71
71
  to. It records an audit trail and gives the agent an explanation it can act on.
72
72
 
73
- It ships with a labelled benchmark corpus (530 cases, 1,002 dialect evaluations) and a
73
+ It ships with a labelled benchmark corpus (551 cases, 1,044 dialect evaluations) and a
74
74
  regression gate for CI. The same benchmark harness can evaluate other open-source guards
75
75
  side by side.
76
76
 
@@ -83,9 +83,9 @@ side by side.
83
83
  | Workstream | What you get | Status |
84
84
  |---|---|---|
85
85
  | **Policy engine** | Read-only enforcement, table/column grants, tenant isolation, function and catalog rules, structural limits. Built on [sqlglot](https://github.com/tobymao/sqlglot). Fails closed when analysis is incomplete. | PostgreSQL + SQLite tested |
86
- | **Privacy pack** | Explicit classification labels, `deny` / `aggregate_only` / `review` per role, JSON-path labels, small-cohort review, minimisation hints and alternatives | implemented |
86
+ | **Privacy pack** | Explicit classification labels, `deny` / `aggregate_only` / `review` per role, JSON-path labels, lineage through CTEs and derived tables, small-cohort review, minimisation hints and alternatives | implemented |
87
87
  | **Agent integrations** | `SQLCheckpoint` with block / review / audit modes, hash-bound single-use approvals, retry lock-out, redacted audit events. LangChain tool, LangGraph nodes, FastAPI router | implemented |
88
- | **Benchmark engine** | Versioned corpus, metrics (recall, precision, FPR, FNR, exact match, per category/dialect, latency percentiles), adapters for native, callable and isolated external validators, JSON and Markdown reports | implemented |
88
+ | **Benchmark engine** | Versioned corpus with per-file SHA-256 hashes, internal and independent tiers, metrics (recall, precision, F1, FPR, FNR with 95% Wilson intervals, exact match, throughput, latency percentiles, per category/dialect/tier), adapters for native, callable and isolated external validators, JSON, CSV and Markdown reports | implemented |
89
89
  | **Query cost** | Explainable static score; optional PostgreSQL `EXPLAIN (FORMAT JSON)` inspection, gated and read-only | implemented |
90
90
  | **CI** | Composite GitHub Action and CLI gate: security, usability, label-change and error regressions against an approved baseline | implemented |
91
91
 
@@ -279,22 +279,24 @@ sqlninja benchmark run --dataset builtin:v1 --adapter external:sql-guardrail
279
279
  sqlninja benchmark compare --baseline benchmarks/baselines/native.json --candidate results/latest.json
280
280
  ```
281
281
 
282
- Results for corpus v1.0.0 (Windows 11, Python 3.11, 1,002 evaluations). Details and raw files:
283
- [RESULTS_v1.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/benchmarks/RESULTS_v1.md).
284
-
285
- | Validator | Recall | Precision | FPR | Recall / FPR within declared capability | p95 ms |
286
- |---|---:|---:|---:|---:|---:|
287
- | SQLGuard Ninja 0.1.0 | 100.0% | 100.0% | 0.0% | 100.0% / 0.0% | 2.15 |
288
- | sql-guardrail 0.5.2 | 98.6% | 86.6% | 21.2% | 98.3% / 19.3% | 1.72 |
289
- | agent-sql-guard 0.2.0 | 67.9% | 86.6% | 14.5% | 89.5% / 17.2% | 1.26 |
290
- | krish2105/sqlguard 0.1.0 | 65.8% | 91.4% | 8.6% | 83.5% / 5.2% | 1.22 |
291
-
292
- **Read the native row with care.** The corpus and the engine were developed together, and
293
- every disagreement was triaged by fixing the engine or correcting a label (both are logged).
294
- 100% shows consistency with the documented semantics, not independent detection quality. The
295
- other tools have smaller policy models (no roles, labels, aggregate-only access or review), so
296
- the "within capability" column is the fairer comparison. Methodology and threats to validity:
297
- [BENCHMARK_METHODOLOGY.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/BENCHMARK_METHODOLOGY.md).
282
+ Results for corpus v1.1.0 (551 cases, 1,044 evaluations; SQLGuard Ninja 0.2.0; Windows 11,
283
+ Python 3.11). Intervals are 95% Wilson intervals. Details, CSV and raw files:
284
+ [RESULTS_v1.1.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/benchmarks/RESULTS_v1.1.md).
285
+
286
+ | Validator | Recall (95% CI) | Precision | F1 | FPR (95% CI) | Recall / FPR within declared capability | p95 ms |
287
+ |---|---:|---:|---:|---:|---:|---:|
288
+ | SQLGuard Ninja 0.2.0 | 100.0% (99.4–100.0) | 100.0% | 1.000 | 0.0% (0.0–0.9) | 100.0% / 0.0% | 3.33 |
289
+ | sql-guardrail 0.5.2 | 98.7% (97.4–99.3) | 85.1% | 0.914 | 24.1% (20.3–28.3) | 98.3% / 19.7% | 2.63 |
290
+ | agent-sql-guard 0.2.0 | 67.3% (63.4–70.9) | 85.2% | 0.752 | 16.3% (13.1–20.0) | 89.4% / 17.7% | 1.87 |
291
+ | krish2105/sqlguard 0.1.0 | 65.3% (61.4–69.0) | 89.6% | 0.755 | 10.5% (8.0–13.8) | 83.5% / 5.2% | 1.95 |
292
+
293
+ **All of these are internal results.** The corpus was written by this project, alongside the
294
+ engine. The native 100% shows consistency with the documented semantics, not independent
295
+ detection quality. No independently sourced dataset exists yet ([intake rules](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/benchmarks/datasets/external/README.md),
296
+ issue #6). Reports keep `internal` and `independent` tiers separate, and they also separate
297
+ policy denials from unsupported-SQL denials. Methodology and bias review:
298
+ [BENCHMARK_METHODOLOGY.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/BENCHMARK_METHODOLOGY.md),
299
+ [BENCHMARK_BIAS_REVIEW.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/BENCHMARK_BIAS_REVIEW.md).
298
300
 
299
301
  ## How it relates to existing tools
300
302
 
@@ -14,7 +14,7 @@ the *authenticated* caller: which tables and columns a role may use, which data
14
14
  appear only in aggregates or only after human approval, and which tenant the caller belongs
15
15
  to. It records an audit trail and gives the agent an explanation it can act on.
16
16
 
17
- It ships with a labelled benchmark corpus (530 cases, 1,002 dialect evaluations) and a
17
+ It ships with a labelled benchmark corpus (551 cases, 1,044 dialect evaluations) and a
18
18
  regression gate for CI. The same benchmark harness can evaluate other open-source guards
19
19
  side by side.
20
20
 
@@ -27,9 +27,9 @@ side by side.
27
27
  | Workstream | What you get | Status |
28
28
  |---|---|---|
29
29
  | **Policy engine** | Read-only enforcement, table/column grants, tenant isolation, function and catalog rules, structural limits. Built on [sqlglot](https://github.com/tobymao/sqlglot). Fails closed when analysis is incomplete. | PostgreSQL + SQLite tested |
30
- | **Privacy pack** | Explicit classification labels, `deny` / `aggregate_only` / `review` per role, JSON-path labels, small-cohort review, minimisation hints and alternatives | implemented |
30
+ | **Privacy pack** | Explicit classification labels, `deny` / `aggregate_only` / `review` per role, JSON-path labels, lineage through CTEs and derived tables, small-cohort review, minimisation hints and alternatives | implemented |
31
31
  | **Agent integrations** | `SQLCheckpoint` with block / review / audit modes, hash-bound single-use approvals, retry lock-out, redacted audit events. LangChain tool, LangGraph nodes, FastAPI router | implemented |
32
- | **Benchmark engine** | Versioned corpus, metrics (recall, precision, FPR, FNR, exact match, per category/dialect, latency percentiles), adapters for native, callable and isolated external validators, JSON and Markdown reports | implemented |
32
+ | **Benchmark engine** | Versioned corpus with per-file SHA-256 hashes, internal and independent tiers, metrics (recall, precision, F1, FPR, FNR with 95% Wilson intervals, exact match, throughput, latency percentiles, per category/dialect/tier), adapters for native, callable and isolated external validators, JSON, CSV and Markdown reports | implemented |
33
33
  | **Query cost** | Explainable static score; optional PostgreSQL `EXPLAIN (FORMAT JSON)` inspection, gated and read-only | implemented |
34
34
  | **CI** | Composite GitHub Action and CLI gate: security, usability, label-change and error regressions against an approved baseline | implemented |
35
35
 
@@ -223,22 +223,24 @@ sqlninja benchmark run --dataset builtin:v1 --adapter external:sql-guardrail
223
223
  sqlninja benchmark compare --baseline benchmarks/baselines/native.json --candidate results/latest.json
224
224
  ```
225
225
 
226
- Results for corpus v1.0.0 (Windows 11, Python 3.11, 1,002 evaluations). Details and raw files:
227
- [RESULTS_v1.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/benchmarks/RESULTS_v1.md).
228
-
229
- | Validator | Recall | Precision | FPR | Recall / FPR within declared capability | p95 ms |
230
- |---|---:|---:|---:|---:|---:|
231
- | SQLGuard Ninja 0.1.0 | 100.0% | 100.0% | 0.0% | 100.0% / 0.0% | 2.15 |
232
- | sql-guardrail 0.5.2 | 98.6% | 86.6% | 21.2% | 98.3% / 19.3% | 1.72 |
233
- | agent-sql-guard 0.2.0 | 67.9% | 86.6% | 14.5% | 89.5% / 17.2% | 1.26 |
234
- | krish2105/sqlguard 0.1.0 | 65.8% | 91.4% | 8.6% | 83.5% / 5.2% | 1.22 |
235
-
236
- **Read the native row with care.** The corpus and the engine were developed together, and
237
- every disagreement was triaged by fixing the engine or correcting a label (both are logged).
238
- 100% shows consistency with the documented semantics, not independent detection quality. The
239
- other tools have smaller policy models (no roles, labels, aggregate-only access or review), so
240
- the "within capability" column is the fairer comparison. Methodology and threats to validity:
241
- [BENCHMARK_METHODOLOGY.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/BENCHMARK_METHODOLOGY.md).
226
+ Results for corpus v1.1.0 (551 cases, 1,044 evaluations; SQLGuard Ninja 0.2.0; Windows 11,
227
+ Python 3.11). Intervals are 95% Wilson intervals. Details, CSV and raw files:
228
+ [RESULTS_v1.1.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/benchmarks/RESULTS_v1.1.md).
229
+
230
+ | Validator | Recall (95% CI) | Precision | F1 | FPR (95% CI) | Recall / FPR within declared capability | p95 ms |
231
+ |---|---:|---:|---:|---:|---:|---:|
232
+ | SQLGuard Ninja 0.2.0 | 100.0% (99.4–100.0) | 100.0% | 1.000 | 0.0% (0.0–0.9) | 100.0% / 0.0% | 3.33 |
233
+ | sql-guardrail 0.5.2 | 98.7% (97.4–99.3) | 85.1% | 0.914 | 24.1% (20.3–28.3) | 98.3% / 19.7% | 2.63 |
234
+ | agent-sql-guard 0.2.0 | 67.3% (63.4–70.9) | 85.2% | 0.752 | 16.3% (13.1–20.0) | 89.4% / 17.7% | 1.87 |
235
+ | krish2105/sqlguard 0.1.0 | 65.3% (61.4–69.0) | 89.6% | 0.755 | 10.5% (8.0–13.8) | 83.5% / 5.2% | 1.95 |
236
+
237
+ **All of these are internal results.** The corpus was written by this project, alongside the
238
+ engine. The native 100% shows consistency with the documented semantics, not independent
239
+ detection quality. No independently sourced dataset exists yet ([intake rules](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/benchmarks/datasets/external/README.md),
240
+ issue #6). Reports keep `internal` and `independent` tiers separate, and they also separate
241
+ policy denials from unsupported-SQL denials. Methodology and bias review:
242
+ [BENCHMARK_METHODOLOGY.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/BENCHMARK_METHODOLOGY.md),
243
+ [BENCHMARK_BIAS_REVIEW.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/BENCHMARK_BIAS_REVIEW.md).
242
244
 
243
245
  ## How it relates to existing tools
244
246