sqlguard-ninja 0.1.0__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.0 → sqlguard_ninja-0.2.0}/CHANGELOG.md +44 -0
  2. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/PKG-INFO +46 -41
  3. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/README.md +45 -40
  4. {sqlguard_ninja-0.1.0/benchmarks/results/v1.0.0 → sqlguard_ninja-0.2.0/benchmarks/baselines}/native.json +4844 -1315
  5. sqlguard_ninja-0.2.0/benchmarks/datasets/external/README.md +28 -0
  6. sqlguard_ninja-0.2.0/benchmarks/datasets/v1/LABEL_CHANGES.yaml +22 -0
  7. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/04_privacy.yaml +5 -4
  8. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/05_tenant_isolation.yaml +5 -2
  9. sqlguard_ninja-0.2.0/benchmarks/datasets/v1/cases/08_lineage.yaml +150 -0
  10. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/manifest.yaml +1 -1
  11. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/agent-sql-guard.csv +1045 -0
  12. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/agent-sql-guard.json +20184 -0
  13. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/agent-sql-guard.md +110 -0
  14. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/krish2105-sqlguard.csv +1045 -0
  15. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/krish2105-sqlguard.json +20121 -0
  16. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/krish2105-sqlguard.md +110 -0
  17. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/native.csv +1045 -0
  18. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/native.json +20484 -0
  19. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/native.md +78 -0
  20. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/sql-guardrail.csv +1045 -0
  21. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/sql-guardrail.json +20779 -0
  22. sqlguard_ninja-0.2.0/benchmarks/results/v1.1.0/sql-guardrail.md +103 -0
  23. sqlguard_ninja-0.2.0/docs/benchmarks/RESULTS_v1.1.md +48 -0
  24. sqlguard_ninja-0.2.0/docs/development/ARCHITECTURE_MAP.md +47 -0
  25. sqlguard_ninja-0.2.0/docs/development/DECISION_LOG.md +9 -0
  26. sqlguard_ninja-0.2.0/docs/development/IMPLEMENTATION_PROGRESS.md +7 -0
  27. sqlguard_ninja-0.2.0/docs/development/NEXT_ACTIONS.md +5 -0
  28. sqlguard_ninja-0.2.0/docs/development/TEST_EVIDENCE.md +7 -0
  29. sqlguard_ninja-0.2.0/docs/development/UPGRADE_MASTER_PLAN.md +25 -0
  30. sqlguard_ninja-0.2.0/docs/development/progress.json +106 -0
  31. sqlguard_ninja-0.2.0/docs/guides/BENCHMARK_BIAS_REVIEW.md +74 -0
  32. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/docs/guides/BENCHMARK_METHODOLOGY.md +9 -4
  33. sqlguard_ninja-0.2.0/docs/releases/v0.1.1.md +29 -0
  34. sqlguard_ninja-0.2.0/docs/releases/v0.2.0.md +27 -0
  35. sqlguard_ninja-0.2.0/docs/security/STATIC_ANALYSIS_LIMITS.md +49 -0
  36. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/docs/security/THREAT_MODEL.md +4 -0
  37. sqlguard_ninja-0.2.0/src/sqlguard_ninja/_version.py +1 -0
  38. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/compare.py +8 -1
  39. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/dataset.py +38 -2
  40. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/metrics.py +66 -2
  41. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/runner.py +35 -0
  42. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/cli/config.py +2 -0
  43. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/cli/main.py +34 -5
  44. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/analysis.py +9 -1
  45. sqlguard_ninja-0.2.0/src/sqlguard_ninja/core/lineage.py +199 -0
  46. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/tenant.py +56 -25
  47. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/privacy/rules.py +53 -14
  48. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/reporting/markdown.py +36 -5
  49. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/unit/test_benchmark_engine.py +77 -0
  50. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/unit/test_cli.py +47 -0
  51. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/unit/test_docs.py +13 -0
  52. sqlguard_ninja-0.2.0/tests/unit/test_lineage.py +84 -0
  53. sqlguard_ninja-0.1.0/src/sqlguard_ninja/_version.py +0 -1
  54. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/.gitignore +0 -0
  55. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/LICENSE +0 -0
  56. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/THIRD_PARTY_NOTICES.md +0 -0
  57. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/01_destructive.yaml +0 -0
  58. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/02_multi_statement_and_formatting.yaml +0 -0
  59. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/03_table_and_column_access.yaml +0 -0
  60. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/06_cte_nested_unicode.yaml +0 -0
  61. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/cases/07_legitimate_lookalike_cost_dialect.yaml +0 -0
  62. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/generated/grant_matrix.yaml +0 -0
  63. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/generated/label_matrix.yaml +0 -0
  64. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/generated/tenant_matrix.yaml +0 -0
  65. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/benchmarks/datasets/v1/generated/transforms.yaml +0 -0
  66. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/benchmarks/policies/retail_saas.yaml +0 -0
  67. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/agent-sql-guard.json +0 -0
  68. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/agent-sql-guard.md +0 -0
  69. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/krish2105-sqlguard.json +0 -0
  70. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/krish2105-sqlguard.md +0 -0
  71. {sqlguard_ninja-0.1.0/benchmarks/baselines → sqlguard_ninja-0.2.0/benchmarks/results/v1.0.0}/native.json +0 -0
  72. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/native.md +0 -0
  73. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/sql-guardrail.json +0 -0
  74. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/benchmarks/results/v1.0.0/sql-guardrail.md +0 -0
  75. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/docs/architecture/ARCHITECTURE_DECISIONS.md +0 -0
  76. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/docs/benchmarks/RESULTS_v1.md +0 -0
  77. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/docs/guides/AGENT_INTEGRATION.md +0 -0
  78. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/docs/guides/CI_INTEGRATION.md +0 -0
  79. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/docs/guides/POLICY_REFERENCE.md +0 -0
  80. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/docs/guides/QUERY_COST.md +0 -0
  81. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/docs/release/FINAL_TECHNICAL_AUDIT.md +0 -0
  82. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/docs/releases/v0.1.0.md +0 -0
  83. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/docs/research/COMPETITIVE_ANALYSIS.md +0 -0
  84. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/examples/_shared.py +0 -0
  85. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/examples/fastapi/app.py +0 -0
  86. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/examples/github-actions/sql-security.yml +0 -0
  87. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/examples/langchain/guarded_tool_demo.py +0 -0
  88. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/examples/langgraph/real_llm_agent.py +0 -0
  89. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/examples/langgraph/sql_agent_demo.py +0 -0
  90. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/examples/postgresql/plan_inspection_demo.py +0 -0
  91. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/examples/sdk/quickstart.py +0 -0
  92. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/examples/sqlite/text_to_sql_demo.py +0 -0
  93. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/pyproject.toml +0 -0
  94. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/__init__.py +0 -0
  95. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/__init__.py +0 -0
  96. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/adapters.py +0 -0
  97. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/builtin.py +0 -0
  98. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/fixtures.py +0 -0
  99. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/translate.py +0 -0
  100. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/workers/_protocol.py +0 -0
  101. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/workers/agent_sql_guard_worker.py +0 -0
  102. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/workers/krish_sqlguard_worker.py +0 -0
  103. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/benchmarking/workers/sql_guardrail_worker.py +0 -0
  104. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/cli/__init__.py +0 -0
  105. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/cli/templates.py +0 -0
  106. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/__init__.py +0 -0
  107. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/findings.py +0 -0
  108. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/guard.py +0 -0
  109. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/__init__.py +0 -0
  110. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/access.py +0 -0
  111. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/base.py +0 -0
  112. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/catalog.py +0 -0
  113. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/functions.py +0 -0
  114. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/statements.py +0 -0
  115. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/core/rules/structure.py +0 -0
  116. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/__init__.py +0 -0
  117. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/audit.py +0 -0
  118. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/checkpoint.py +0 -0
  119. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/executors.py +0 -0
  120. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/fastapi.py +0 -0
  121. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/langchain.py +0 -0
  122. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/integrations/langgraph.py +0 -0
  123. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/policy/__init__.py +0 -0
  124. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/policy/model.py +0 -0
  125. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/privacy/__init__.py +0 -0
  126. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/privacy/suggest.py +0 -0
  127. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/py.typed +0 -0
  128. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/query_cost/__init__.py +0 -0
  129. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/query_cost/postgres.py +0 -0
  130. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/query_cost/static.py +0 -0
  131. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/src/sqlguard_ninja/reporting/__init__.py +0 -0
  132. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/__init__.py +0 -0
  133. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/conftest.py +0 -0
  134. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/integration/__init__.py +0 -0
  135. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/integration/test_corpus_sqlite_validation.py +0 -0
  136. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/integration/test_external_adapters.py +0 -0
  137. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/integration/test_frameworks.py +0 -0
  138. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/integration/test_postgres.py +0 -0
  139. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/pg_support.py +0 -0
  140. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/property/__init__.py +0 -0
  141. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/property/test_guard_properties.py +0 -0
  142. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/security/__init__.py +0 -0
  143. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/security/test_agent_boundaries.py +0 -0
  144. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/security/test_corpus_native.py +0 -0
  145. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/unit/__init__.py +0 -0
  146. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/unit/helpers.py +0 -0
  147. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/unit/test_dataset.py +0 -0
  148. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/unit/test_function_policy_mechanics.py +0 -0
  149. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/unit/test_policy.py +0 -0
  150. {sqlguard_ninja-0.1.0 → sqlguard_ninja-0.2.0}/tests/unit/test_rules.py +0 -0
@@ -3,6 +3,50 @@
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
+
30
+ ## [0.1.1] — 2026-10-24
31
+
32
+ Documentation and governance patch. No changes to policy decisions.
33
+
34
+ ### Fixed
35
+ * README links were relative and broke on the PyPI project page. They are now absolute
36
+ GitHub URLs, and a test keeps relative links out of the README.
37
+
38
+ ### Added
39
+ * `docs/security/STATIC_ANALYSIS_LIMITS.md`: limits of static analysis, compensating
40
+ controls, and a dialect support matrix (supported / experimental / untested).
41
+ * `docs/guides/BENCHMARK_BIAS_REVIEW.md`: quantified review of corpus v1 bias
42
+ (co-development, generated labels, input distribution, outcome imbalance).
43
+ * `benchmarks/datasets/external/`: intake rules for independently sourced, held-out
44
+ evaluation sets (no cases yet).
45
+ * `.github/CODEOWNERS`, and branch protection on `main` (pull requests and CI required).
46
+
47
+ ### Unchanged known limitations
48
+ * No restricted-function or system-catalog benchmark cases; no external dataset yet.
49
+
6
50
  ## [0.1.0] — 2026-10-24
7
51
 
8
52
  First release.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: sqlguard-ninja
3
- Version: 0.1.0
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,29 +70,29 @@ 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
 
77
77
  > **One layer, not the only one.** Static SQL inspection cannot guarantee database security.
78
78
  > Use a read-only least-privilege role, row-level security and statement timeouts as well.
79
- > See the [threat model](docs/security/THREAT_MODEL.md).
79
+ > See the [threat model](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/security/THREAT_MODEL.md).
80
80
 
81
81
  ## What it does
82
82
 
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
 
92
92
  Not yet included: governed writes (all writes are denied in v0.1); benchmark cases for
93
93
  restricted functions and system catalogs (the rules exist, but the corpus does not cover
94
94
  them); dialects beyond PostgreSQL and SQLite (they parse, but are untested). Full list:
95
- [KNOWN_LIMITATIONS.md](KNOWN_LIMITATIONS.md).
95
+ [KNOWN_LIMITATIONS.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/KNOWN_LIMITATIONS.md).
96
96
 
97
97
  ## Architecture
98
98
 
@@ -121,7 +121,7 @@ flowchart LR
121
121
  ```
122
122
 
123
123
  Design decisions and their trade-offs are recorded in
124
- [ARCHITECTURE_DECISIONS.md](docs/architecture/ARCHITECTURE_DECISIONS.md).
124
+ [ARCHITECTURE_DECISIONS.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/architecture/ARCHITECTURE_DECISIONS.md).
125
125
 
126
126
  ## Five-minute quick start
127
127
 
@@ -203,7 +203,7 @@ ctx = RequestContext(principal=user.id, role=user.role, tenant_id=user.tenant_id
203
203
  app.invoke(state, config={"configurable": {CONTEXT_KEY: ctx}}) # nodes cannot alter config
204
204
  ```
205
205
 
206
- More in [AGENT_INTEGRATION.md](docs/guides/AGENT_INTEGRATION.md): the LangChain tool (its
206
+ More in [AGENT_INTEGRATION.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/AGENT_INTEGRATION.md): the LangChain tool (its
207
207
  schema accepts only `query`), the FastAPI router, review-mode approvals and audit sinks.
208
208
 
209
209
  ## Privacy policies
@@ -244,7 +244,7 @@ REVIEW:
244
244
  Labels also apply to paths inside JSON columns (`profile->'health'->>'allergies'`).
245
245
  `sqlninja policy suggest` proposes labels from column names for a human to review; those
246
246
  suggestions are never enforced. This is a technical control, not a certification of GDPR
247
- compliance. Full semantics: [POLICY_REFERENCE.md](docs/guides/POLICY_REFERENCE.md).
247
+ compliance. Full semantics: [POLICY_REFERENCE.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/POLICY_REFERENCE.md).
248
248
 
249
249
  ## Query cost analysis
250
250
 
@@ -268,7 +268,7 @@ report = PostgresPlanInspector(guard, lambda: psycopg.connect(READER_DSN)).inspe
268
268
  report.total_cost, report.plan_rows, report.static.score, report.findings
269
269
  ```
270
270
 
271
- See [QUERY_COST.md](docs/guides/QUERY_COST.md) and `examples/postgresql/plan_inspection_demo.py`.
271
+ See [QUERY_COST.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/QUERY_COST.md) and `examples/postgresql/plan_inspection_demo.py`.
272
272
 
273
273
  ## Benchmark
274
274
 
@@ -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](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](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
 
@@ -304,7 +306,7 @@ thorough read-only validator with a tautology catch-all, which this project does
304
306
  duplicate. [agent-sql-guard](https://github.com/sakura-sky/sql-guard) has a careful
305
307
  schema-less PII denylist. What SQLGuard Ninja adds: role- and label-based policies, the agent
306
308
  checkpoint contract, a shared benchmark with isolated adapters, planner inspection, and the
307
- CI gate. Full comparison: [COMPETITIVE_ANALYSIS.md](docs/research/COMPETITIVE_ANALYSIS.md).
309
+ CI gate. Full comparison: [COMPETITIVE_ANALYSIS.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/research/COMPETITIVE_ANALYSIS.md).
308
310
 
309
311
  ## Security limitations
310
312
 
@@ -318,13 +320,14 @@ CI gate. Full comparison: [COMPETITIVE_ANALYSIS.md](docs/research/COMPETITIVE_AN
318
320
  but those two categories are not measured.
319
321
 
320
322
  Use database grants, row-level security and timeouts as the authoritative controls. See the
321
- [threat model](docs/security/THREAT_MODEL.md) and [KNOWN_LIMITATIONS.md](KNOWN_LIMITATIONS.md).
323
+ [threat model](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/security/THREAT_MODEL.md), [limits of static analysis](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/security/STATIC_ANALYSIS_LIMITS.md),
324
+ the [benchmark bias review](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/BENCHMARK_BIAS_REVIEW.md) and [KNOWN_LIMITATIONS.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/KNOWN_LIMITATIONS.md).
322
325
 
323
326
  ## Roadmap
324
327
 
325
328
  Next: restricted-function and system-catalog benchmark cases, an independent held-out
326
329
  corpus, lineage-aware aggregate checks, and tenant predicate push-down. Later: governed
327
- writes, more tested dialects, and SARIF output. Details in [ROADMAP.md](ROADMAP.md).
330
+ writes, more tested dialects, and SARIF output. Details in [ROADMAP.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/ROADMAP.md).
328
331
 
329
332
  ## Links
330
333
 
@@ -332,18 +335,20 @@ writes, more tested dialects, and SARIF output. Details in [ROADMAP.md](ROADMAP.
332
335
  * Releases: https://github.com/Pratik653/SQLGuard_Ninjapy/releases
333
336
  * PyPI: https://pypi.org/project/sqlguard-ninja/
334
337
  * Issues: https://github.com/Pratik653/SQLGuard_Ninjapy/issues
335
- * Security policy: [SECURITY.md](SECURITY.md) · Contributing: [CONTRIBUTING.md](CONTRIBUTING.md)
338
+ * Security policy: [SECURITY.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/SECURITY.md) · Contributing: [CONTRIBUTING.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/CONTRIBUTING.md)
336
339
 
337
340
  ## Documentation
338
341
 
339
- * [Policy reference](docs/guides/POLICY_REFERENCE.md)
340
- * [Agent integration](docs/guides/AGENT_INTEGRATION.md)
341
- * [Query cost](docs/guides/QUERY_COST.md)
342
- * [CI integration](docs/guides/CI_INTEGRATION.md)
343
- * [Benchmark methodology](docs/guides/BENCHMARK_METHODOLOGY.md)
344
- * [Threat model](docs/security/THREAT_MODEL.md)
345
- * [Architecture decisions](docs/architecture/ARCHITECTURE_DECISIONS.md)
346
- * [Known limitations](KNOWN_LIMITATIONS.md) · [Roadmap](ROADMAP.md) · [Changelog](CHANGELOG.md)
342
+ * [Policy reference](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/POLICY_REFERENCE.md)
343
+ * [Agent integration](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/AGENT_INTEGRATION.md)
344
+ * [Query cost](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/QUERY_COST.md)
345
+ * [CI integration](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/CI_INTEGRATION.md)
346
+ * [Benchmark methodology](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/BENCHMARK_METHODOLOGY.md)
347
+ * [Threat model](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/security/THREAT_MODEL.md)
348
+ * [Limits of static SQL analysis and dialect support](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/security/STATIC_ANALYSIS_LIMITS.md)
349
+ * [Benchmark bias review](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/BENCHMARK_BIAS_REVIEW.md)
350
+ * [Architecture decisions](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/architecture/ARCHITECTURE_DECISIONS.md)
351
+ * [Known limitations](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/KNOWN_LIMITATIONS.md) · [Roadmap](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/ROADMAP.md) · [Changelog](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/CHANGELOG.md)
347
352
 
348
353
  ## Supported versions
349
354
 
@@ -361,10 +366,10 @@ pytest # PostgreSQL tests run if SQLNINJA_PG_DSN is set
361
366
  python scripts/generate_corpus.py --check
362
367
  ```
363
368
 
364
- See [CONTRIBUTING.md](CONTRIBUTING.md). Report vulnerabilities privately per
365
- [SECURITY.md](SECURITY.md).
369
+ See [CONTRIBUTING.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/CONTRIBUTING.md). Report vulnerabilities privately per
370
+ [SECURITY.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/SECURITY.md).
366
371
 
367
372
  ## Licence
368
373
 
369
374
  Apache-2.0. No third-party code is vendored; dependencies and their licences are listed in
370
- [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md). All benchmark data is synthetic.
375
+ [THIRD_PARTY_NOTICES.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/THIRD_PARTY_NOTICES.md). All benchmark data is synthetic.
@@ -14,29 +14,29 @@ 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
 
21
21
  > **One layer, not the only one.** Static SQL inspection cannot guarantee database security.
22
22
  > Use a read-only least-privilege role, row-level security and statement timeouts as well.
23
- > See the [threat model](docs/security/THREAT_MODEL.md).
23
+ > See the [threat model](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/security/THREAT_MODEL.md).
24
24
 
25
25
  ## What it does
26
26
 
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
 
36
36
  Not yet included: governed writes (all writes are denied in v0.1); benchmark cases for
37
37
  restricted functions and system catalogs (the rules exist, but the corpus does not cover
38
38
  them); dialects beyond PostgreSQL and SQLite (they parse, but are untested). Full list:
39
- [KNOWN_LIMITATIONS.md](KNOWN_LIMITATIONS.md).
39
+ [KNOWN_LIMITATIONS.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/KNOWN_LIMITATIONS.md).
40
40
 
41
41
  ## Architecture
42
42
 
@@ -65,7 +65,7 @@ flowchart LR
65
65
  ```
66
66
 
67
67
  Design decisions and their trade-offs are recorded in
68
- [ARCHITECTURE_DECISIONS.md](docs/architecture/ARCHITECTURE_DECISIONS.md).
68
+ [ARCHITECTURE_DECISIONS.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/architecture/ARCHITECTURE_DECISIONS.md).
69
69
 
70
70
  ## Five-minute quick start
71
71
 
@@ -147,7 +147,7 @@ ctx = RequestContext(principal=user.id, role=user.role, tenant_id=user.tenant_id
147
147
  app.invoke(state, config={"configurable": {CONTEXT_KEY: ctx}}) # nodes cannot alter config
148
148
  ```
149
149
 
150
- More in [AGENT_INTEGRATION.md](docs/guides/AGENT_INTEGRATION.md): the LangChain tool (its
150
+ More in [AGENT_INTEGRATION.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/AGENT_INTEGRATION.md): the LangChain tool (its
151
151
  schema accepts only `query`), the FastAPI router, review-mode approvals and audit sinks.
152
152
 
153
153
  ## Privacy policies
@@ -188,7 +188,7 @@ REVIEW:
188
188
  Labels also apply to paths inside JSON columns (`profile->'health'->>'allergies'`).
189
189
  `sqlninja policy suggest` proposes labels from column names for a human to review; those
190
190
  suggestions are never enforced. This is a technical control, not a certification of GDPR
191
- compliance. Full semantics: [POLICY_REFERENCE.md](docs/guides/POLICY_REFERENCE.md).
191
+ compliance. Full semantics: [POLICY_REFERENCE.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/POLICY_REFERENCE.md).
192
192
 
193
193
  ## Query cost analysis
194
194
 
@@ -212,7 +212,7 @@ report = PostgresPlanInspector(guard, lambda: psycopg.connect(READER_DSN)).inspe
212
212
  report.total_cost, report.plan_rows, report.static.score, report.findings
213
213
  ```
214
214
 
215
- See [QUERY_COST.md](docs/guides/QUERY_COST.md) and `examples/postgresql/plan_inspection_demo.py`.
215
+ See [QUERY_COST.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/QUERY_COST.md) and `examples/postgresql/plan_inspection_demo.py`.
216
216
 
217
217
  ## Benchmark
218
218
 
@@ -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](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](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
 
@@ -248,7 +250,7 @@ thorough read-only validator with a tautology catch-all, which this project does
248
250
  duplicate. [agent-sql-guard](https://github.com/sakura-sky/sql-guard) has a careful
249
251
  schema-less PII denylist. What SQLGuard Ninja adds: role- and label-based policies, the agent
250
252
  checkpoint contract, a shared benchmark with isolated adapters, planner inspection, and the
251
- CI gate. Full comparison: [COMPETITIVE_ANALYSIS.md](docs/research/COMPETITIVE_ANALYSIS.md).
253
+ CI gate. Full comparison: [COMPETITIVE_ANALYSIS.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/research/COMPETITIVE_ANALYSIS.md).
252
254
 
253
255
  ## Security limitations
254
256
 
@@ -262,13 +264,14 @@ CI gate. Full comparison: [COMPETITIVE_ANALYSIS.md](docs/research/COMPETITIVE_AN
262
264
  but those two categories are not measured.
263
265
 
264
266
  Use database grants, row-level security and timeouts as the authoritative controls. See the
265
- [threat model](docs/security/THREAT_MODEL.md) and [KNOWN_LIMITATIONS.md](KNOWN_LIMITATIONS.md).
267
+ [threat model](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/security/THREAT_MODEL.md), [limits of static analysis](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/security/STATIC_ANALYSIS_LIMITS.md),
268
+ the [benchmark bias review](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/BENCHMARK_BIAS_REVIEW.md) and [KNOWN_LIMITATIONS.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/KNOWN_LIMITATIONS.md).
266
269
 
267
270
  ## Roadmap
268
271
 
269
272
  Next: restricted-function and system-catalog benchmark cases, an independent held-out
270
273
  corpus, lineage-aware aggregate checks, and tenant predicate push-down. Later: governed
271
- writes, more tested dialects, and SARIF output. Details in [ROADMAP.md](ROADMAP.md).
274
+ writes, more tested dialects, and SARIF output. Details in [ROADMAP.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/ROADMAP.md).
272
275
 
273
276
  ## Links
274
277
 
@@ -276,18 +279,20 @@ writes, more tested dialects, and SARIF output. Details in [ROADMAP.md](ROADMAP.
276
279
  * Releases: https://github.com/Pratik653/SQLGuard_Ninjapy/releases
277
280
  * PyPI: https://pypi.org/project/sqlguard-ninja/
278
281
  * Issues: https://github.com/Pratik653/SQLGuard_Ninjapy/issues
279
- * Security policy: [SECURITY.md](SECURITY.md) · Contributing: [CONTRIBUTING.md](CONTRIBUTING.md)
282
+ * Security policy: [SECURITY.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/SECURITY.md) · Contributing: [CONTRIBUTING.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/CONTRIBUTING.md)
280
283
 
281
284
  ## Documentation
282
285
 
283
- * [Policy reference](docs/guides/POLICY_REFERENCE.md)
284
- * [Agent integration](docs/guides/AGENT_INTEGRATION.md)
285
- * [Query cost](docs/guides/QUERY_COST.md)
286
- * [CI integration](docs/guides/CI_INTEGRATION.md)
287
- * [Benchmark methodology](docs/guides/BENCHMARK_METHODOLOGY.md)
288
- * [Threat model](docs/security/THREAT_MODEL.md)
289
- * [Architecture decisions](docs/architecture/ARCHITECTURE_DECISIONS.md)
290
- * [Known limitations](KNOWN_LIMITATIONS.md) · [Roadmap](ROADMAP.md) · [Changelog](CHANGELOG.md)
286
+ * [Policy reference](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/POLICY_REFERENCE.md)
287
+ * [Agent integration](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/AGENT_INTEGRATION.md)
288
+ * [Query cost](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/QUERY_COST.md)
289
+ * [CI integration](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/CI_INTEGRATION.md)
290
+ * [Benchmark methodology](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/BENCHMARK_METHODOLOGY.md)
291
+ * [Threat model](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/security/THREAT_MODEL.md)
292
+ * [Limits of static SQL analysis and dialect support](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/security/STATIC_ANALYSIS_LIMITS.md)
293
+ * [Benchmark bias review](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/guides/BENCHMARK_BIAS_REVIEW.md)
294
+ * [Architecture decisions](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/docs/architecture/ARCHITECTURE_DECISIONS.md)
295
+ * [Known limitations](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/KNOWN_LIMITATIONS.md) · [Roadmap](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/ROADMAP.md) · [Changelog](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/CHANGELOG.md)
291
296
 
292
297
  ## Supported versions
293
298
 
@@ -305,10 +310,10 @@ pytest # PostgreSQL tests run if SQLNINJA_PG_DSN is set
305
310
  python scripts/generate_corpus.py --check
306
311
  ```
307
312
 
308
- See [CONTRIBUTING.md](CONTRIBUTING.md). Report vulnerabilities privately per
309
- [SECURITY.md](SECURITY.md).
313
+ See [CONTRIBUTING.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/CONTRIBUTING.md). Report vulnerabilities privately per
314
+ [SECURITY.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/SECURITY.md).
310
315
 
311
316
  ## Licence
312
317
 
313
318
  Apache-2.0. No third-party code is vendored; dependencies and their licences are listed in
314
- [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md). All benchmark data is synthetic.
319
+ [THIRD_PARTY_NOTICES.md](https://github.com/Pratik653/SQLGuard_Ninjapy/blob/main/THIRD_PARTY_NOTICES.md). All benchmark data is synthetic.