sqllocks-shape 0.9.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 (367) hide show
  1. sqllocks_shape-0.9.0/.devcontainer/devcontainer.json +6 -0
  2. sqllocks_shape-0.9.0/.env.example +1 -0
  3. sqllocks_shape-0.9.0/.github/ISSUE_TEMPLATE/bug.md +10 -0
  4. sqllocks_shape-0.9.0/.github/pull_request_template.md +6 -0
  5. sqllocks_shape-0.9.0/.github/workflows/ci.yml +109 -0
  6. sqllocks_shape-0.9.0/.github/workflows/nightly.yml +42 -0
  7. sqllocks_shape-0.9.0/.github/workflows/publish.yml +80 -0
  8. sqllocks_shape-0.9.0/.github/workflows/release.yml +24 -0
  9. sqllocks_shape-0.9.0/.github/workflows/security.yml +17 -0
  10. sqllocks_shape-0.9.0/.gitignore +25 -0
  11. sqllocks_shape-0.9.0/CHANGELOG.md +11 -0
  12. sqllocks_shape-0.9.0/CLAUDE.md +41 -0
  13. sqllocks_shape-0.9.0/CODEOWNERS +4 -0
  14. sqllocks_shape-0.9.0/CONTRIBUTING.md +3 -0
  15. sqllocks_shape-0.9.0/GOVERNANCE.md +3 -0
  16. sqllocks_shape-0.9.0/LICENSE +21 -0
  17. sqllocks_shape-0.9.0/Makefile +17 -0
  18. sqllocks_shape-0.9.0/PKG-INFO +105 -0
  19. sqllocks_shape-0.9.0/README.md +55 -0
  20. sqllocks_shape-0.9.0/SECURITY.md +11 -0
  21. sqllocks_shape-0.9.0/THIRD_PARTY_NOTICES.md +20 -0
  22. sqllocks_shape-0.9.0/benchmarks/baselines/2026-09-29/profile_bench.json +620 -0
  23. sqllocks_shape-0.9.0/benchmarks/baselines/2026-09-29/profile_verify.txt +718 -0
  24. sqllocks_shape-0.9.0/benchmarks/baselines/2026-09-29/retail_bench.json +1933 -0
  25. sqllocks_shape-0.9.0/benchmarks/baselines/2026-09-29/retail_large_seed_study.json +1 -0
  26. sqllocks_shape-0.9.0/benchmarks/baselines/2026-09-29/retail_verify_large.json +4684 -0
  27. sqllocks_shape-0.9.0/benchmarks/baselines/2026-09-29/retail_verify_large.txt +144 -0
  28. sqllocks_shape-0.9.0/benchmarks/baselines/2026-09-29/retail_verify_medium.json +4679 -0
  29. sqllocks_shape-0.9.0/benchmarks/baselines/2026-09-29/retail_verify_medium.txt +144 -0
  30. sqllocks_shape-0.9.0/benchmarks/baselines/2026-09-29/retail_verify_medium_sameseed.json +4453 -0
  31. sqllocks_shape-0.9.0/benchmarks/baselines/2026-09-29/retail_verify_medium_sameseed.txt +144 -0
  32. sqllocks_shape-0.9.0/benchmarks/baselines/2026-09-29/retail_verify_small.json +4718 -0
  33. sqllocks_shape-0.9.0/benchmarks/baselines/2026-09-29/retail_verify_small.txt +144 -0
  34. sqllocks_shape-0.9.0/benchmarks/vs_spindle/README.md +40 -0
  35. sqllocks_shape-0.9.0/benchmarks/vs_spindle/check_coverage.py +89 -0
  36. sqllocks_shape-0.9.0/benchmarks/vs_spindle/common.py +58 -0
  37. sqllocks_shape-0.9.0/benchmarks/vs_spindle/domain_1to1/README.md +437 -0
  38. sqllocks_shape-0.9.0/benchmarks/vs_spindle/domain_1to1/bench.py +199 -0
  39. sqllocks_shape-0.9.0/benchmarks/vs_spindle/domain_1to1/generate.py +209 -0
  40. sqllocks_shape-0.9.0/benchmarks/vs_spindle/domain_1to1/port.py +1432 -0
  41. sqllocks_shape-0.9.0/benchmarks/vs_spindle/domain_1to1/verify.py +880 -0
  42. sqllocks_shape-0.9.0/benchmarks/vs_spindle/dump_schema.py +64 -0
  43. sqllocks_shape-0.9.0/benchmarks/vs_spindle/paths.py +24 -0
  44. sqllocks_shape-0.9.0/benchmarks/vs_spindle/profile_1to1/README.md +208 -0
  45. sqllocks_shape-0.9.0/benchmarks/vs_spindle/profile_1to1/bench.py +268 -0
  46. sqllocks_shape-0.9.0/benchmarks/vs_spindle/profile_1to1/datasets.py +436 -0
  47. sqllocks_shape-0.9.0/benchmarks/vs_spindle/profile_1to1/port.py +1917 -0
  48. sqllocks_shape-0.9.0/benchmarks/vs_spindle/profile_1to1/spindle_cli_profile.py +40 -0
  49. sqllocks_shape-0.9.0/benchmarks/vs_spindle/profile_1to1/spindle_dump.py +138 -0
  50. sqllocks_shape-0.9.0/benchmarks/vs_spindle/profile_1to1/verify.py +289 -0
  51. sqllocks_shape-0.9.0/benchmarks/vs_spindle/results.json +241 -0
  52. sqllocks_shape-0.9.0/benchmarks/vs_spindle/results.schema.json +61 -0
  53. sqllocks_shape-0.9.0/benchmarks/vs_spindle/run.py +521 -0
  54. sqllocks_shape-0.9.0/benchmarks/vs_spindle/setup_spindle.sh +32 -0
  55. sqllocks_shape-0.9.0/docs/API_STABILITY.md +7 -0
  56. sqllocks_shape-0.9.0/docs/BRANDING.md +17 -0
  57. sqllocks_shape-0.9.0/docs/CONTRIBUTING.md +13 -0
  58. sqllocks_shape-0.9.0/docs/DETERMINISM.md +7 -0
  59. sqllocks_shape-0.9.0/docs/EXTERNAL_REFERENCE_ASSETS.md +8 -0
  60. sqllocks_shape-0.9.0/docs/INSTALL.md +21 -0
  61. sqllocks_shape-0.9.0/docs/LOCATION_AS_CODE.md +8 -0
  62. sqllocks_shape-0.9.0/docs/PRIVACY_MODEL.md +2 -0
  63. sqllocks_shape-0.9.0/docs/PRODUCT_ARCHITECTURE.md +202 -0
  64. sqllocks_shape-0.9.0/docs/QUICKSTART.md +23 -0
  65. sqllocks_shape-0.9.0/docs/RELEASE_POLICY.md +2 -0
  66. sqllocks_shape-0.9.0/docs/SECURITY_SPECIFICATION.md +322 -0
  67. sqllocks_shape-0.9.0/docs/SHAPE_MANIFESTO.md +27 -0
  68. sqllocks_shape-0.9.0/docs/THREAT_MODEL.md +11 -0
  69. sqllocks_shape-0.9.0/docs/TUTORIAL.md +12 -0
  70. sqllocks_shape-0.9.0/docs/plans/COMPLETION_PLAN.md +2456 -0
  71. sqllocks_shape-0.9.0/docs/plans/demo_status/DM-00.md +29 -0
  72. sqllocks_shape-0.9.0/docs/plans/demo_status/DM-01.md +62 -0
  73. sqllocks_shape-0.9.0/docs/plans/demo_status/DM-01_verify_output.txt +67 -0
  74. sqllocks_shape-0.9.0/docs/plans/demo_status/DM-02.md +62 -0
  75. sqllocks_shape-0.9.0/docs/plans/demo_status/DM-03.md +54 -0
  76. sqllocks_shape-0.9.0/docs/plans/demo_status/DM-03b.md +60 -0
  77. sqllocks_shape-0.9.0/docs/plans/demo_status/DM-04.md +24 -0
  78. sqllocks_shape-0.9.0/docs/plans/demo_status/DM-05.md +22 -0
  79. sqllocks_shape-0.9.0/docs/plans/demo_status/DM-05b.md +20 -0
  80. sqllocks_shape-0.9.0/docs/plans/demo_status/DM-06.md +25 -0
  81. sqllocks_shape-0.9.0/docs/plans/demo_status/DM-07.md +26 -0
  82. sqllocks_shape-0.9.0/docs/plans/demo_status/DM-08-talk.md +25 -0
  83. sqllocks_shape-0.9.0/docs/plans/demo_status/DM-08.md +16 -0
  84. sqllocks_shape-0.9.0/docs/plans/demo_status/GATE-G0.md +70 -0
  85. sqllocks_shape-0.9.0/docs/plans/demo_status/MORNING_SUMMARY.md +44 -0
  86. sqllocks_shape-0.9.0/docs/plans/spindle_coverage.tsv +149 -0
  87. sqllocks_shape-0.9.0/docs/specs/LOCATION_SPEC.md +3 -0
  88. sqllocks_shape-0.9.0/docs/specs/ONE_ZERO_CONTRACT.md +14 -0
  89. sqllocks_shape-0.9.0/docs/specs/PACK_SPEC.md +3 -0
  90. sqllocks_shape-0.9.0/docs/specs/PLUGIN_PROTOCOL.md +5 -0
  91. sqllocks_shape-0.9.0/docs/specs/SHAPE_1_0.md +17 -0
  92. sqllocks_shape-0.9.0/docs/specs/SHAPE_1_0_GA.md +49 -0
  93. sqllocks_shape-0.9.0/docs/specs/SHAPE_ARTIFACT_SPEC.md +13 -0
  94. sqllocks_shape-0.9.0/docs/specs/STREAMING_SEMANTICS.md +3 -0
  95. sqllocks_shape-0.9.0/docs/specs/requirements.yaml +719 -0
  96. sqllocks_shape-0.9.0/docs/specs/shape-v1-ga.schema.json +83 -0
  97. sqllocks_shape-0.9.0/docs/specs/shape-v1.schema.json +82 -0
  98. sqllocks_shape-0.9.0/examples/classified_release.py +5 -0
  99. sqllocks_shape-0.9.0/examples/customer.shape.json +36 -0
  100. sqllocks_shape-0.9.0/examples/shape_as_code.py +8 -0
  101. sqllocks_shape-0.9.0/pyproject.toml +159 -0
  102. sqllocks_shape-0.9.0/scripts/build_pure_wheel.py +285 -0
  103. sqllocks_shape-0.9.0/scripts/check_requirements.py +15 -0
  104. sqllocks_shape-0.9.0/scripts/check_secrets.py +15 -0
  105. sqllocks_shape-0.9.0/scripts/env.sh +8 -0
  106. sqllocks_shape-0.9.0/security/CLASSIFICATION_PROPAGATION.md +11 -0
  107. sqllocks_shape-0.9.0/security/THREAT_MODEL.md +8 -0
  108. sqllocks_shape-0.9.0/src/shape/__init__.py +84 -0
  109. sqllocks_shape-0.9.0/src/shape/api.py +65 -0
  110. sqllocks_shape-0.9.0/src/shape/artifact/__init__.py +36 -0
  111. sqllocks_shape-0.9.0/src/shape/artifact/canonical.py +30 -0
  112. sqllocks_shape-0.9.0/src/shape/artifact/io.py +120 -0
  113. sqllocks_shape-0.9.0/src/shape/artifact/migrate.py +53 -0
  114. sqllocks_shape-0.9.0/src/shape/artifact/secure.py +58 -0
  115. sqllocks_shape-0.9.0/src/shape/artifact/shape_file.py +63 -0
  116. sqllocks_shape-0.9.0/src/shape/capture/__init__.py +5 -0
  117. sqllocks_shape-0.9.0/src/shape/capture/core.py +75 -0
  118. sqllocks_shape-0.9.0/src/shape/capture/vectorized.py +82 -0
  119. sqllocks_shape-0.9.0/src/shape/cli/__init__.py +1 -0
  120. sqllocks_shape-0.9.0/src/shape/cli/main.py +320 -0
  121. sqllocks_shape-0.9.0/src/shape/connectors/__init__.py +31 -0
  122. sqllocks_shape-0.9.0/src/shape/connectors/dbapi.py +55 -0
  123. sqllocks_shape-0.9.0/src/shape/connectors/eventhubs.py +34 -0
  124. sqllocks_shape-0.9.0/src/shape/connectors/files.py +69 -0
  125. sqllocks_shape-0.9.0/src/shape/connectors/kafka.py +36 -0
  126. sqllocks_shape-0.9.0/src/shape/connectors/qualification.py +70 -0
  127. sqllocks_shape-0.9.0/src/shape/connectors/registry.py +22 -0
  128. sqllocks_shape-0.9.0/src/shape/contracts/__init__.py +18 -0
  129. sqllocks_shape-0.9.0/src/shape/contracts/core.py +147 -0
  130. sqllocks_shape-0.9.0/src/shape/contracts/v1.py +350 -0
  131. sqllocks_shape-0.9.0/src/shape/diff/__init__.py +4 -0
  132. sqllocks_shape-0.9.0/src/shape/diff/core.py +29 -0
  133. sqllocks_shape-0.9.0/src/shape/drift/__init__.py +6 -0
  134. sqllocks_shape-0.9.0/src/shape/drift/core.py +62 -0
  135. sqllocks_shape-0.9.0/src/shape/drift/policy.py +22 -0
  136. sqllocks_shape-0.9.0/src/shape/errors.py +21 -0
  137. sqllocks_shape-0.9.0/src/shape/generation/__init__.py +195 -0
  138. sqllocks_shape-0.9.0/src/shape/generation/address_vectorized.py +77 -0
  139. sqllocks_shape-0.9.0/src/shape/generation/advanced.py +60 -0
  140. sqllocks_shape-0.9.0/src/shape/generation/certificate.py +109 -0
  141. sqllocks_shape-0.9.0/src/shape/generation/compiler.py +154 -0
  142. sqllocks_shape-0.9.0/src/shape/generation/core.py +43 -0
  143. sqllocks_shape-0.9.0/src/shape/generation/distribution_fidelity.py +30 -0
  144. sqllocks_shape-0.9.0/src/shape/generation/evolution.py +33 -0
  145. sqllocks_shape-0.9.0/src/shape/generation/fidelity.py +127 -0
  146. sqllocks_shape-0.9.0/src/shape/generation/future.py +14 -0
  147. sqllocks_shape-0.9.0/src/shape/generation/geo_fidelity.py +21 -0
  148. sqllocks_shape-0.9.0/src/shape/generation/joint.py +49 -0
  149. sqllocks_shape-0.9.0/src/shape/generation/levels.py +51 -0
  150. sqllocks_shape-0.9.0/src/shape/generation/relational.py +83 -0
  151. sqllocks_shape-0.9.0/src/shape/generation/relational_fidelity.py +33 -0
  152. sqllocks_shape-0.9.0/src/shape/generation/release.py +18 -0
  153. sqllocks_shape-0.9.0/src/shape/generation/strategies.py +144 -0
  154. sqllocks_shape-0.9.0/src/shape/generation/timeline.py +63 -0
  155. sqllocks_shape-0.9.0/src/shape/generation/vectorized.py +31 -0
  156. sqllocks_shape-0.9.0/src/shape/geospatial/__init__.py +5 -0
  157. sqllocks_shape-0.9.0/src/shape/geospatial/core.py +40 -0
  158. sqllocks_shape-0.9.0/src/shape/kernel/__init__.py +4 -0
  159. sqllocks_shape-0.9.0/src/shape/kernel/batches.py +25 -0
  160. sqllocks_shape-0.9.0/src/shape/location/__init__.py +51 -0
  161. sqllocks_shape-0.9.0/src/shape/location/core.py +167 -0
  162. sqllocks_shape-0.9.0/src/shape/location/reference.py +106 -0
  163. sqllocks_shape-0.9.0/src/shape/model/__init__.py +14 -0
  164. sqllocks_shape-0.9.0/src/shape/model/core.py +69 -0
  165. sqllocks_shape-0.9.0/src/shape/packs/__init__.py +86 -0
  166. sqllocks_shape-0.9.0/src/shape/packs/address.py +228 -0
  167. sqllocks_shape-0.9.0/src/shape/packs/base.py +35 -0
  168. sqllocks_shape-0.9.0/src/shape/packs/domains.py +241 -0
  169. sqllocks_shape-0.9.0/src/shape/packs/person.py +20 -0
  170. sqllocks_shape-0.9.0/src/shape/packs/sdk.py +26 -0
  171. sqllocks_shape-0.9.0/src/shape/packs/verify.py +17 -0
  172. sqllocks_shape-0.9.0/src/shape/plugins/__init__.py +13 -0
  173. sqllocks_shape-0.9.0/src/shape/plugins/core.py +52 -0
  174. sqllocks_shape-0.9.0/src/shape/plugins/runtime.py +53 -0
  175. sqllocks_shape-0.9.0/src/shape/privacy/__init__.py +77 -0
  176. sqllocks_shape-0.9.0/src/shape/privacy/advanced.py +8 -0
  177. sqllocks_shape-0.9.0/src/shape/privacy/classification.py +17 -0
  178. sqllocks_shape-0.9.0/src/shape/privacy/core.py +35 -0
  179. sqllocks_shape-0.9.0/src/shape/privacy/detect.py +59 -0
  180. sqllocks_shape-0.9.0/src/shape/privacy/measure.py +58 -0
  181. sqllocks_shape-0.9.0/src/shape/privacy/policy.py +100 -0
  182. sqllocks_shape-0.9.0/src/shape/privacy/propagate.py +14 -0
  183. sqllocks_shape-0.9.0/src/shape/privacy/release.py +54 -0
  184. sqllocks_shape-0.9.0/src/shape/profile/__init__.py +57 -0
  185. sqllocks_shape-0.9.0/src/shape/profile/advanced.py +81 -0
  186. sqllocks_shape-0.9.0/src/shape/profile/bounded_dependencies.py +67 -0
  187. sqllocks_shape-0.9.0/src/shape/profile/datetime.py +28 -0
  188. sqllocks_shape-0.9.0/src/shape/profile/dependence.py +52 -0
  189. sqllocks_shape-0.9.0/src/shape/profile/dependencies.py +61 -0
  190. sqllocks_shape-0.9.0/src/shape/profile/error.py +22 -0
  191. sqllocks_shape-0.9.0/src/shape/profile/numeric.py +104 -0
  192. sqllocks_shape-0.9.0/src/shape/profile/reference/__init__.py +13 -0
  193. sqllocks_shape-0.9.0/src/shape/profile/reference/column.py +626 -0
  194. sqllocks_shape-0.9.0/src/shape/profile/reference/model.py +70 -0
  195. sqllocks_shape-0.9.0/src/shape/profile/reference/numerics.py +805 -0
  196. sqllocks_shape-0.9.0/src/shape/profile/reference/profile.py +300 -0
  197. sqllocks_shape-0.9.0/src/shape/profile/reference/readers.py +152 -0
  198. sqllocks_shape-0.9.0/src/shape/profile/reference/sources.py +125 -0
  199. sqllocks_shape-0.9.0/src/shape/profile/reference/table.py +328 -0
  200. sqllocks_shape-0.9.0/src/shape/profile/semantic_future.py +16 -0
  201. sqllocks_shape-0.9.0/src/shape/profile/sketches.py +173 -0
  202. sqllocks_shape-0.9.0/src/shape/profile/temporal.py +12 -0
  203. sqllocks_shape-0.9.0/src/shape/profile/text.py +37 -0
  204. sqllocks_shape-0.9.0/src/shape/profile/text_vectorized.py +49 -0
  205. sqllocks_shape-0.9.0/src/shape/py.typed +0 -0
  206. sqllocks_shape-0.9.0/src/shape/quality/__init__.py +18 -0
  207. sqllocks_shape-0.9.0/src/shape/quality/core.py +39 -0
  208. sqllocks_shape-0.9.0/src/shape/quality/infer.py +21 -0
  209. sqllocks_shape-0.9.0/src/shape/quality/policy.py +71 -0
  210. sqllocks_shape-0.9.0/src/shape/query/__init__.py +3 -0
  211. sqllocks_shape-0.9.0/src/shape/query/core.py +75 -0
  212. sqllocks_shape-0.9.0/src/shape/registry/__init__.py +2 -0
  213. sqllocks_shape-0.9.0/src/shape/registry/local.py +104 -0
  214. sqllocks_shape-0.9.0/src/shape/relations/__init__.py +3 -0
  215. sqllocks_shape-0.9.0/src/shape/relations/core.py +62 -0
  216. sqllocks_shape-0.9.0/src/shape/report/__init__.py +7 -0
  217. sqllocks_shape-0.9.0/src/shape/report/html.py +232 -0
  218. sqllocks_shape-0.9.0/src/shape/security/__init__.py +87 -0
  219. sqllocks_shape-0.9.0/src/shape/security/crypto.py +57 -0
  220. sqllocks_shape-0.9.0/src/shape/security/hardening.py +100 -0
  221. sqllocks_shape-0.9.0/src/shape/security/labels.py +31 -0
  222. sqllocks_shape-0.9.0/src/shape/spec/__init__.py +11 -0
  223. sqllocks_shape-0.9.0/src/shape/spec/capabilities.py +18 -0
  224. sqllocks_shape-0.9.0/src/shape/spec/io.py +35 -0
  225. sqllocks_shape-0.9.0/src/shape/spec/migrate.py +13 -0
  226. sqllocks_shape-0.9.0/src/shape/spec/model.py +58 -0
  227. sqllocks_shape-0.9.0/src/shape/streaming/__init__.py +107 -0
  228. sqllocks_shape-0.9.0/src/shape/streaming/aggregate_windows.py +85 -0
  229. sqllocks_shape-0.9.0/src/shape/streaming/checkpoint.py +38 -0
  230. sqllocks_shape-0.9.0/src/shape/streaming/core.py +47 -0
  231. sqllocks_shape-0.9.0/src/shape/streaming/evidence.py +110 -0
  232. sqllocks_shape-0.9.0/src/shape/streaming/failure.py +20 -0
  233. sqllocks_shape-0.9.0/src/shape/streaming/full_engine.py +72 -0
  234. sqllocks_shape-0.9.0/src/shape/streaming/keyed.py +103 -0
  235. sqllocks_shape-0.9.0/src/shape/streaming/monitor.py +27 -0
  236. sqllocks_shape-0.9.0/src/shape/streaming/online.py +26 -0
  237. sqllocks_shape-0.9.0/src/shape/streaming/platinum.py +343 -0
  238. sqllocks_shape-0.9.0/src/shape/streaming/vectorized.py +51 -0
  239. sqllocks_shape-0.9.0/src/shape/streaming/windows.py +72 -0
  240. sqllocks_shape-0.9.0/src/shape/types.py +110 -0
  241. sqllocks_shape-0.9.0/src/shape/validation/__init__.py +23 -0
  242. sqllocks_shape-0.9.0/src/shape/validation/adversarial.py +35 -0
  243. sqllocks_shape-0.9.0/src/shape/validation/conformance.py +24 -0
  244. sqllocks_shape-0.9.0/src/shape/validation/fuzz.py +26 -0
  245. sqllocks_shape-0.9.0/src/shape/validation/invariants.py +46 -0
  246. sqllocks_shape-0.9.0/src/shape/validation/statistics.py +51 -0
  247. sqllocks_shape-0.9.0/src/shape/validation/suite.py +36 -0
  248. sqllocks_shape-0.9.0/tests/artifact/test_artifact.py +8 -0
  249. sqllocks_shape-0.9.0/tests/artifact/test_hardening.py +23 -0
  250. sqllocks_shape-0.9.0/tests/artifact/test_migration.py +9 -0
  251. sqllocks_shape-0.9.0/tests/artifact/test_rc_shape_file.py +26 -0
  252. sqllocks_shape-0.9.0/tests/artifact/test_secure.py +29 -0
  253. sqllocks_shape-0.9.0/tests/benchmarks/test_vs_spindle_harness.py +146 -0
  254. sqllocks_shape-0.9.0/tests/capture/test_capture.py +6 -0
  255. sqllocks_shape-0.9.0/tests/capture/test_late_columns.py +6 -0
  256. sqllocks_shape-0.9.0/tests/capture/test_vectorized.py +14 -0
  257. sqllocks_shape-0.9.0/tests/cli/test_cli.py +16 -0
  258. sqllocks_shape-0.9.0/tests/cli/test_cli_e2e.py +17 -0
  259. sqllocks_shape-0.9.0/tests/cli/test_five_cli.py +33 -0
  260. sqllocks_shape-0.9.0/tests/cli/test_product_cli.py +13 -0
  261. sqllocks_shape-0.9.0/tests/conformance/test_repository_constitution.py +17 -0
  262. sqllocks_shape-0.9.0/tests/conftest.py +13 -0
  263. sqllocks_shape-0.9.0/tests/connectors/test_adapters.py +12 -0
  264. sqllocks_shape-0.9.0/tests/connectors/test_dbapi.py +14 -0
  265. sqllocks_shape-0.9.0/tests/connectors/test_files.py +12 -0
  266. sqllocks_shape-0.9.0/tests/connectors/test_qualification.py +63 -0
  267. sqllocks_shape-0.9.0/tests/connectors/test_registry.py +7 -0
  268. sqllocks_shape-0.9.0/tests/contracts/test_contracts.py +32 -0
  269. sqllocks_shape-0.9.0/tests/demo/content/test_demo_data.py +201 -0
  270. sqllocks_shape-0.9.0/tests/demo/content/test_talk_kit.py +111 -0
  271. sqllocks_shape-0.9.0/tests/demo/core/conftest.py +45 -0
  272. sqllocks_shape-0.9.0/tests/demo/core/test_artifact.py +114 -0
  273. sqllocks_shape-0.9.0/tests/demo/core/test_cli.py +145 -0
  274. sqllocks_shape-0.9.0/tests/demo/core/test_contract.py +199 -0
  275. sqllocks_shape-0.9.0/tests/demo/core/test_diff.py +148 -0
  276. sqllocks_shape-0.9.0/tests/demo/core/test_profile.py +251 -0
  277. sqllocks_shape-0.9.0/tests/demo/core/test_publish_workflow.py +77 -0
  278. sqllocks_shape-0.9.0/tests/demo/core/test_report.py +46 -0
  279. sqllocks_shape-0.9.0/tests/demo/core/test_wheel.py +100 -0
  280. sqllocks_shape-0.9.0/tests/demo/core/test_wheel_license.py +33 -0
  281. sqllocks_shape-0.9.0/tests/demo/fabric/conftest.py +47 -0
  282. sqllocks_shape-0.9.0/tests/demo/fabric/fabric_helpers.py +165 -0
  283. sqllocks_shape-0.9.0/tests/demo/fabric/requirements.txt +13 -0
  284. sqllocks_shape-0.9.0/tests/demo/fabric/test_notebooks.py +278 -0
  285. sqllocks_shape-0.9.0/tests/demo/fabric/test_pipelines.py +307 -0
  286. sqllocks_shape-0.9.0/tests/demo/fabric/test_udf.py +414 -0
  287. sqllocks_shape-0.9.0/tests/diff/test_diff.py +6 -0
  288. sqllocks_shape-0.9.0/tests/drift/test_drift.py +8 -0
  289. sqllocks_shape-0.9.0/tests/drift/test_drift_gate_new.py +8 -0
  290. sqllocks_shape-0.9.0/tests/generation/test_address_partition_weights.py +37 -0
  291. sqllocks_shape-0.9.0/tests/generation/test_certificate.py +22 -0
  292. sqllocks_shape-0.9.0/tests/generation/test_distribution_fidelity.py +10 -0
  293. sqllocks_shape-0.9.0/tests/generation/test_fidelity_categorical.py +11 -0
  294. sqllocks_shape-0.9.0/tests/generation/test_fidelity_complete.py +36 -0
  295. sqllocks_shape-0.9.0/tests/generation/test_generation.py +15 -0
  296. sqllocks_shape-0.9.0/tests/generation/test_levels_evolution.py +24 -0
  297. sqllocks_shape-0.9.0/tests/generation/test_random_access.py +25 -0
  298. sqllocks_shape-0.9.0/tests/generation/test_relational.py +19 -0
  299. sqllocks_shape-0.9.0/tests/generation/test_shape_compiler.py +54 -0
  300. sqllocks_shape-0.9.0/tests/generation/test_strategies.py +36 -0
  301. sqllocks_shape-0.9.0/tests/generation/test_timeline.py +30 -0
  302. sqllocks_shape-0.9.0/tests/generation/test_vectorized_generation.py +55 -0
  303. sqllocks_shape-0.9.0/tests/geospatial/test_geo.py +7 -0
  304. sqllocks_shape-0.9.0/tests/kernel/test_batches.py +28 -0
  305. sqllocks_shape-0.9.0/tests/location/test_location.py +55 -0
  306. sqllocks_shape-0.9.0/tests/location/test_reference.py +8 -0
  307. sqllocks_shape-0.9.0/tests/model/test_model.py +34 -0
  308. sqllocks_shape-0.9.0/tests/packs/test_address.py +34 -0
  309. sqllocks_shape-0.9.0/tests/packs/test_domain_sdk.py +30 -0
  310. sqllocks_shape-0.9.0/tests/packs/test_domains.py +29 -0
  311. sqllocks_shape-0.9.0/tests/packs/test_person.py +11 -0
  312. sqllocks_shape-0.9.0/tests/packs/test_sdk.py +6 -0
  313. sqllocks_shape-0.9.0/tests/packs/test_verify.py +13 -0
  314. sqllocks_shape-0.9.0/tests/platform12/test_features_05_08.py +12 -0
  315. sqllocks_shape-0.9.0/tests/platform12/test_hardening.py +9 -0
  316. sqllocks_shape-0.9.0/tests/plugins/test_plugins.py +11 -0
  317. sqllocks_shape-0.9.0/tests/plugins/test_runtime.py +27 -0
  318. sqllocks_shape-0.9.0/tests/privacy/test_advanced.py +17 -0
  319. sqllocks_shape-0.9.0/tests/privacy/test_classification.py +8 -0
  320. sqllocks_shape-0.9.0/tests/privacy/test_detect.py +12 -0
  321. sqllocks_shape-0.9.0/tests/privacy/test_measure.py +13 -0
  322. sqllocks_shape-0.9.0/tests/privacy/test_propagate.py +7 -0
  323. sqllocks_shape-0.9.0/tests/privacy/test_release_controls.py +8 -0
  324. sqllocks_shape-0.9.0/tests/privacy/test_release_policy_new.py +74 -0
  325. sqllocks_shape-0.9.0/tests/profile/test_advanced.py +13 -0
  326. sqllocks_shape-0.9.0/tests/profile/test_bounded_dependencies.py +12 -0
  327. sqllocks_shape-0.9.0/tests/profile/test_dependence_temporal.py +10 -0
  328. sqllocks_shape-0.9.0/tests/profile/test_dependencies.py +13 -0
  329. sqllocks_shape-0.9.0/tests/profile/test_error_models.py +5 -0
  330. sqllocks_shape-0.9.0/tests/profile/test_merge_invariants.py +22 -0
  331. sqllocks_shape-0.9.0/tests/profile/test_merge_properties.py +24 -0
  332. sqllocks_shape-0.9.0/tests/profile/test_numeric.py +36 -0
  333. sqllocks_shape-0.9.0/tests/quality/test_infer.py +8 -0
  334. sqllocks_shape-0.9.0/tests/quality/test_policy.py +7 -0
  335. sqllocks_shape-0.9.0/tests/query/test_query.py +21 -0
  336. sqllocks_shape-0.9.0/tests/registry/test_local_registry.py +56 -0
  337. sqllocks_shape-0.9.0/tests/relations/test_covariance.py +8 -0
  338. sqllocks_shape-0.9.0/tests/release/test_rc1_hardening.py +49 -0
  339. sqllocks_shape-0.9.0/tests/security/test_crypto.py +27 -0
  340. sqllocks_shape-0.9.0/tests/security/test_fuzz_boundaries.py +47 -0
  341. sqllocks_shape-0.9.0/tests/security/test_ga_security.py +112 -0
  342. sqllocks_shape-0.9.0/tests/security/test_ga_security_extended.py +128 -0
  343. sqllocks_shape-0.9.0/tests/security/test_rc1_leakage.py +15 -0
  344. sqllocks_shape-0.9.0/tests/security/test_sensitivity.py +13 -0
  345. sqllocks_shape-0.9.0/tests/security/test_zero_network.py +16 -0
  346. sqllocks_shape-0.9.0/tests/spec/test_capabilities.py +8 -0
  347. sqllocks_shape-0.9.0/tests/spec/test_ga_freeze.py +42 -0
  348. sqllocks_shape-0.9.0/tests/spec/test_io.py +11 -0
  349. sqllocks_shape-0.9.0/tests/spec/test_shape_contract.py +8 -0
  350. sqllocks_shape-0.9.0/tests/streaming/test_checkpoint_store.py +10 -0
  351. sqllocks_shape-0.9.0/tests/streaming/test_failure_replay.py +13 -0
  352. sqllocks_shape-0.9.0/tests/streaming/test_monitor.py +8 -0
  353. sqllocks_shape-0.9.0/tests/streaming/test_online.py +9 -0
  354. sqllocks_shape-0.9.0/tests/streaming/test_rc1_evidence.py +72 -0
  355. sqllocks_shape-0.9.0/tests/streaming/test_rq6.py +32 -0
  356. sqllocks_shape-0.9.0/tests/streaming/test_rq7.py +21 -0
  357. sqllocks_shape-0.9.0/tests/streaming/test_rq8.py +20 -0
  358. sqllocks_shape-0.9.0/tests/streaming/test_windows.py +13 -0
  359. sqllocks_shape-0.9.0/tests/test_adversarial_invariants.py +28 -0
  360. sqllocks_shape-0.9.0/tests/test_removed_modules.py +45 -0
  361. sqllocks_shape-0.9.0/tests/test_streaming_async.py +14 -0
  362. sqllocks_shape-0.9.0/tests/torture/test_all_modules.py +30 -0
  363. sqllocks_shape-0.9.0/tests/torture/test_cross_feature_torture.py +105 -0
  364. sqllocks_shape-0.9.0/tests/types/test_types.py +31 -0
  365. sqllocks_shape-0.9.0/tests/validation/test_adversarial.py +5 -0
  366. sqllocks_shape-0.9.0/tests/validation/test_fuzz_artifact.py +14 -0
  367. sqllocks_shape-0.9.0/tests/validation/test_suite.py +6 -0
@@ -0,0 +1,6 @@
1
+ {
2
+ "name": "Shape Dev",
3
+ "image": "mcr.microsoft.com/devcontainers/python:1-3.12-bookworm",
4
+ "postCreateCommand": "python -m pip install -e '.[dev]'",
5
+ "remoteUser": "vscode"
6
+ }
@@ -0,0 +1 @@
1
+ # Shape core requires no credentials or network service.
@@ -0,0 +1,10 @@
1
+ ---
2
+ name: Bug
3
+ about: Report reproducible incorrect behavior
4
+ ---
5
+ ## Reproduction
6
+ ## Expected
7
+ ## Actual
8
+ ## Shape version/environment
9
+ ## Security/privacy impact
10
+ Do not attach secrets, PII, classified data, or proprietary datasets.
@@ -0,0 +1,6 @@
1
+ ## What changed
2
+ ## Requirement/spec impact
3
+ ## Tests/evidence
4
+ ## Determinism/bounded-memory impact
5
+ ## Privacy/security impact
6
+ ## Compatibility/migration impact
@@ -0,0 +1,109 @@
1
+ name: CI
2
+ on: [push, pull_request]
3
+ permissions: {contents: read}
4
+ jobs:
5
+ test:
6
+ # T-06: the full Python 3.11-3.14 matrix on Linux; 3.11 and 3.14 on macOS and Windows.
7
+ strategy:
8
+ fail-fast: false
9
+ matrix:
10
+ os: [ubuntu-latest]
11
+ python: ['3.11', '3.12', '3.13', '3.14']
12
+ include:
13
+ - {os: macos-latest, python: '3.11'}
14
+ - {os: macos-latest, python: '3.14'}
15
+ - {os: windows-latest, python: '3.11'}
16
+ - {os: windows-latest, python: '3.14'}
17
+ runs-on: ${{ matrix.os }}
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+ - uses: actions/setup-python@v5
21
+ with: {python-version: '${{ matrix.python }}', allow-prereleases: true}
22
+ - run: python -m pip install -U pip
23
+ - run: pip install -e '.[dev,streaming]'
24
+ # T-27 scope: src tests plugins benchmarks/vs_spindle rust (only the paths that exist yet).
25
+ - run: ruff check src tests benchmarks/vs_spindle
26
+ - run: ruff format --check src tests benchmarks/vs_spindle
27
+ # [tool.mypy] targets python_version 3.11. On 3.12+ legs pip installs a numpy whose
28
+ # stubs use 3.12-only syntax (`type` statements), which mypy rejects under a 3.11
29
+ # target, so the type check runs on the 3.11 legs (every OS).
30
+ - if: matrix.python == '3.11'
31
+ run: mypy
32
+ - run: python -m compileall -q src/shape
33
+ # The Fabric demo tests need Java, PySpark and unixODBC, and the demo content tests need
34
+ # the pinned Spindle checkout; both run in the fabric-demo job below.
35
+ # --cov-fail-under is the measured coverage (86.55% on P0-06), rounded down.
36
+ - run: >-
37
+ python -m pytest -q -m "not emulator and not live"
38
+ --ignore=tests/demo/fabric --ignore=tests/demo/content
39
+ --cov=shape --cov-fail-under=86
40
+ audit:
41
+ runs-on: ubuntu-latest
42
+ steps:
43
+ - uses: actions/checkout@v4
44
+ - uses: actions/setup-python@v5
45
+ with: {python-version: '3.13'}
46
+ - run: python -m pip install -U pip
47
+ - run: pip install -e '.[dev,streaming]'
48
+ - run: pip-audit --skip-editable
49
+ fabric-demo:
50
+ runs-on: ubuntu-latest
51
+ steps:
52
+ - uses: actions/checkout@v4
53
+ - uses: actions/setup-python@v5
54
+ with: {python-version: '3.11'}
55
+ - uses: actions/setup-java@v4
56
+ with: {distribution: temurin, java-version: '17'}
57
+ - run: sudo apt-get update -q && sudo apt-get install -y -q unixodbc
58
+ - run: python -m pip install -U pip
59
+ - run: pip install -e '.[dev]' -r tests/demo/fabric/requirements.txt
60
+ # demo/make_data.py reads Spindle's schema and reference data (plan section 1.2); read only.
61
+ - name: Pinned Spindle checkout
62
+ run: |
63
+ git init -q "$RUNNER_TEMP/spindle"
64
+ git -C "$RUNNER_TEMP/spindle" fetch -q --depth 1 https://github.com/sqllocks/spindle 422e78df2267e73bb2fa976267e48cb437861e2f
65
+ git -C "$RUNNER_TEMP/spindle" checkout -q FETCH_HEAD
66
+ echo "SPINDLE_ROOT=$RUNNER_TEMP/spindle" >> "$GITHUB_ENV"
67
+ - run: python -m pytest -q tests/demo/fabric tests/demo/content
68
+ bench-quick:
69
+ # Verifiers, then the quick benchmark (D1, D2, retail small+medium; 3 runs) against the
70
+ # pinned Spindle. On a private repository the standard runner has 2 vCPUs, so ratios are
71
+ # informational until the repository is public (O-05).
72
+ runs-on: ubuntu-latest
73
+ timeout-minutes: 90
74
+ env: {BENCH_OUT_DIR: "${{ github.workspace }}/bench-out"}
75
+ steps:
76
+ - uses: actions/checkout@v4
77
+ - uses: actions/setup-python@v5
78
+ with: {python-version: '3.11'}
79
+ - name: Pinned Spindle baseline and venv (plan section 1.2)
80
+ run: source scripts/env.sh && bash benchmarks/vs_spindle/setup_spindle.sh
81
+ - name: Shape venv (pyarrow pinned like the Spindle venv)
82
+ run: |
83
+ source scripts/env.sh
84
+ python -m venv "$SHAPE_VENV"
85
+ "$SHAPE_VENV/bin/pip" install -U pip
86
+ "$SHAPE_VENV/bin/pip" install -e '.[dev]' 'pyarrow==25.0.1'
87
+ - run: source scripts/env.sh && python benchmarks/vs_spindle/check_coverage.py
88
+ - run: source scripts/env.sh && python benchmarks/vs_spindle/run.py --quick --out "$BENCH_OUT_DIR/results.json"
89
+ - uses: actions/upload-artifact@v4
90
+ if: always()
91
+ with:
92
+ name: benchmark-results-quick
93
+ path: |
94
+ ${{ github.workspace }}/bench-out/results.json
95
+ ${{ github.workspace }}/bench-out/verify/
96
+ build:
97
+ runs-on: ubuntu-latest
98
+ steps:
99
+ - uses: actions/checkout@v4
100
+ - uses: actions/setup-python@v5
101
+ with: {python-version: '3.13'}
102
+ - run: pip install build twine pip-audit
103
+ - run: python -m pip install --upgrade pip
104
+ - run: pip install .
105
+ - run: python -m build
106
+ - run: python -m twine check dist/*
107
+ - run: pip-audit
108
+ - uses: actions/upload-artifact@v4
109
+ with: {name: distributions, path: dist/*}
@@ -0,0 +1,42 @@
1
+ name: Nightly
2
+ on:
3
+ schedule: [{cron: '17 3 * * *'}]
4
+ workflow_dispatch: {}
5
+ permissions: {contents: read}
6
+ jobs:
7
+ benchmarks-full:
8
+ # Every workload of plan section 3.4 (5 runs each): verifiers first, then timings.
9
+ # Timings are ratios measured in this one job (T-19). A public repository gets 4-vCPU
10
+ # standard runners; on a private repository use a 4-vCPU larger runner (O-05).
11
+ runs-on: ubuntu-latest
12
+ timeout-minutes: 360
13
+ env: {BENCH_OUT_DIR: "${{ github.workspace }}/bench-out"}
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+ - uses: actions/setup-python@v5
17
+ with: {python-version: '3.11'}
18
+ - name: Pinned Spindle baseline and venv (plan section 1.2)
19
+ run: source scripts/env.sh && bash benchmarks/vs_spindle/setup_spindle.sh
20
+ - name: Shape venv (pyarrow pinned like the Spindle venv, so timings share one pyarrow)
21
+ run: |
22
+ source scripts/env.sh
23
+ python -m venv "$SHAPE_VENV"
24
+ "$SHAPE_VENV/bin/pip" install -U pip
25
+ "$SHAPE_VENV/bin/pip" install -e '.[dev]' 'pyarrow==25.0.1'
26
+ - run: source scripts/env.sh && python benchmarks/vs_spindle/check_coverage.py
27
+ - run: source scripts/env.sh && python benchmarks/vs_spindle/run.py --full
28
+ - uses: actions/upload-artifact@v4
29
+ if: always()
30
+ with:
31
+ name: benchmark-results-full
32
+ path: |
33
+ benchmarks/vs_spindle/results.json
34
+ ${{ github.workspace }}/bench-out/verify/
35
+ ${{ github.workspace }}/bench-out/spindle_freeze.txt
36
+ emulator-compose:
37
+ # The emulator-backed test jobs (Kafka, Event Hubs + Azurite, SQL Server) arrive with the
38
+ # work packages that own those connectors; until then, keep the compose file valid.
39
+ runs-on: ubuntu-latest
40
+ steps:
41
+ - uses: actions/checkout@v4
42
+ - run: docker compose -f ci/emulators/docker-compose.yml config --quiet
@@ -0,0 +1,80 @@
1
+ # Early-access publish of the pure-Python wheel and an sdist (plan DM-03b).
2
+ #
3
+ # Trusted publishing only: no API tokens and no passwords. The PyPI (and TestPyPI) project
4
+ # "sqllocks-shape" must have a trusted publisher registered for this repository, workflow file
5
+ # "publish.yml" and environment "pypi" (TestPyPI: environment "testpypi").
6
+ #
7
+ # Owner triggers it: Actions > "Publish" > Run workflow, repository = testpypi first, then pypi.
8
+ # Pushing a tag "v<version>" publishes to PyPI (the tag must equal the package version).
9
+ name: Publish
10
+
11
+ on:
12
+ workflow_dispatch:
13
+ inputs:
14
+ repository:
15
+ description: "Where to publish"
16
+ required: true
17
+ default: testpypi
18
+ type: choice
19
+ options:
20
+ - testpypi
21
+ - pypi
22
+ push:
23
+ tags:
24
+ - "v*"
25
+
26
+ permissions:
27
+ contents: read
28
+
29
+ jobs:
30
+ build:
31
+ name: Build and test the wheel and sdist
32
+ runs-on: ubuntu-latest
33
+ steps:
34
+ - uses: actions/checkout@v4
35
+ - uses: actions/setup-python@v5
36
+ with:
37
+ python-version: "3.11"
38
+ - run: python -m pip install --upgrade pip build twine
39
+ - name: Tag must match the package version
40
+ if: startsWith(github.ref, 'refs/tags/v')
41
+ run: |
42
+ version="$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")"
43
+ test "v${version}" = "${GITHUB_REF_NAME}" || {
44
+ echo "tag ${GITHUB_REF_NAME} does not match version ${version}"; exit 1; }
45
+ - name: README must say this is early access
46
+ run: grep -qi "early access" README.md
47
+ - name: Build the pure wheel, install it in a clean venv and run tests/demo/core
48
+ run: python scripts/build_pure_wheel.py --verify --python python3.11
49
+ - name: Build the sdist
50
+ run: python -m build --sdist
51
+ - name: twine check
52
+ run: python -m twine check dist/*
53
+ - run: ls -l dist
54
+ - uses: actions/upload-artifact@v4
55
+ with:
56
+ name: dist
57
+ path: dist/*
58
+ if-no-files-found: error
59
+
60
+ publish:
61
+ name: Publish to ${{ (github.event_name == 'workflow_dispatch' && inputs.repository == 'testpypi') && 'TestPyPI' || 'PyPI' }}
62
+ needs: build
63
+ runs-on: ubuntu-latest
64
+ environment: ${{ (github.event_name == 'workflow_dispatch' && inputs.repository == 'testpypi') && 'testpypi' || 'pypi' }}
65
+ permissions:
66
+ id-token: write
67
+ contents: read
68
+ steps:
69
+ - uses: actions/download-artifact@v4
70
+ with:
71
+ name: dist
72
+ path: dist
73
+ - name: Publish to TestPyPI
74
+ if: github.event_name == 'workflow_dispatch' && inputs.repository == 'testpypi'
75
+ uses: pypa/gh-action-pypi-publish@release/v1
76
+ with:
77
+ repository-url: https://test.pypi.org/legacy/
78
+ - name: Publish to PyPI
79
+ if: github.event_name != 'workflow_dispatch' || inputs.repository == 'pypi'
80
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,24 @@
1
+ name: Release candidate
2
+ on: {workflow_dispatch: {}}
3
+ permissions: {contents: read, id-token: write}
4
+ jobs:
5
+ release:
6
+ runs-on: ubuntu-latest
7
+ steps:
8
+ - uses: actions/checkout@v4
9
+ - uses: actions/setup-python@v5
10
+ with: {python-version: '3.13'}
11
+ - run: python -m pip install --upgrade pip
12
+ - run: pip install build twine pip-audit cyclonedx-bom
13
+ - run: pip install '.[dev]'
14
+ - run: make check
15
+ - run: python -m build
16
+ - run: python -m twine check dist/*
17
+ - run: pip-audit
18
+ - run: cyclonedx-py environment -o sbom.json
19
+ - uses: actions/upload-artifact@v4
20
+ with:
21
+ name: release-candidate
22
+ path: |
23
+ dist/*
24
+ sbom.json
@@ -0,0 +1,17 @@
1
+ name: Security
2
+ on: [push, pull_request]
3
+ permissions: {contents: read}
4
+ jobs:
5
+ security:
6
+ runs-on: ubuntu-latest
7
+ steps:
8
+ - uses: actions/checkout@v4
9
+ - uses: actions/setup-python@v5
10
+ with: {python-version: "3.12"}
11
+ - run: python -m pip install --upgrade pip
12
+ - run: python -m pip install -e ".[dev,streaming]"
13
+ - run: pip-audit --skip-editable
14
+ - run: bandit -q -r src -ll
15
+ - run: python scripts/check_secrets.py
16
+ # The Fabric demo tests need extra packages and run in ci.yml's fabric-demo job.
17
+ - run: pytest -m security --ignore=tests/demo/fabric
@@ -0,0 +1,25 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ .venv/
4
+ .pytest_cache/
5
+ .mypy_cache/
6
+ .ruff_cache/
7
+ dist/
8
+ build/
9
+ *.egg-info/
10
+ .env
11
+ .env.*
12
+ !.env.example
13
+ *.pem
14
+ *.key
15
+ *.p12
16
+ *.pfx
17
+ .hypothesis/
18
+ .coverage
19
+ htmlcov/
20
+ .DS_Store
21
+ Thumbs.db
22
+ *.swp
23
+
24
+ # benchmark scratch output in CI
25
+ /bench-out/
@@ -0,0 +1,11 @@
1
+ # Changelog
2
+
3
+ Shape is in **early access**. Profiling is available now; data generation and
4
+ pipeline integration are in progress. See `docs/plans/COMPLETION_PLAN.md`.
5
+
6
+ ## Unreleased
7
+
8
+ - Relicensed under the MIT license.
9
+ - Repository cleaned up for public release: removed internal milestone and
10
+ qualification records.
11
+ - README and changelog rewritten to describe the current state.
@@ -0,0 +1,41 @@
1
+ # CLAUDE.md
2
+
3
+ This repository is being rebuilt against a fixed, fully decided plan:
4
+ **`docs/plans/COMPLETION_PLAN.md`**.
5
+
6
+ Before doing anything in this repo:
7
+
8
+ 1. Read §0 (Builder guide), §1 (Environment setup) and §6 (Execution rules) of the
9
+ plan, in full.
10
+ 2. Find the next work package in §11 (Status tracker). It is the first `todo` whose
11
+ `Depends` are all `done`.
12
+ 3. Build exactly that work package to its acceptance criteria in §7. Then update the
13
+ tracker, commit with the work-package ID as the message prefix, and push.
14
+
15
+ **48-hour Fabric demo lanes:** if your session prompt names a demo lane (L1, L2 or
16
+ L3), follow §12 of the plan instead of step 2. Edit only the paths that §12.5 gives
17
+ your lane, and record completion in `docs/plans/demo_status/<WP>.md`, never in the
18
+ plan's tables.
19
+
20
+ Rules that override everything else:
21
+
22
+ - Every decision in §2 (D-xx and T-xx), every gate and every tolerance is fixed. Do
23
+ not change one; escalate instead (§0.4).
24
+ - Never lower a gate, loosen a tolerance, skip or xfail a test, or fabricate
25
+ benchmark results.
26
+ - Equivalence verification comes before any timing (§6.4).
27
+ - Never modify the pinned Spindle checkout (`$SPINDLE_ROOT`).
28
+ - Never report something as done without running its checks in this session.
29
+ - Shell state does not persist between tool calls. Start every command that uses the
30
+ plan's environment variables with `source scripts/env.sh &&`, run from the repo
31
+ root. P0-00 creates that file; until then, use the §1 block from the plan.
32
+ - Performance numbers count only after the equivalence verifier for that workload
33
+ exits 0.
34
+
35
+ Useful commands (once P0-06 and P0-07 are done):
36
+
37
+ ```bash
38
+ make check # lint, format, types, tests (T-27 scope)
39
+ pytest -m "not emulator and not live" # local test run
40
+ source scripts/env.sh && python benchmarks/vs_spindle/run.py --quick # verifiers + benchmarks vs pinned Spindle
41
+ ```
@@ -0,0 +1,4 @@
1
+ # Replace placeholder after GitHub repository creation.
2
+ /docs/PRODUCT_ARCHITECTURE.md @OWNER
3
+ /docs/SECURITY_SPECIFICATION.md @OWNER
4
+ /security/ @OWNER
@@ -0,0 +1,3 @@
1
+ # Contributing
2
+
3
+ Changes should preserve deterministic behavior, bounded-memory semantics where promised, sensitivity/provenance propagation and fail-closed handling of ambiguous or unsafe input. Add tests and requirement traceability for new normative behavior. Avoid mandatory network dependencies in core.
@@ -0,0 +1,3 @@
1
+ # Governance
2
+
3
+ Shape uses specification-first governance. Public behavior is defined by versioned specifications and conformance tests, not incidental Python implementation details. Breaking changes require a major specification version and migration path. Security fixes may tighten previously permissive behavior.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025-2026 SQLLocks (Jonathan Stewart)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,17 @@
1
+ PYTHON ?= python
2
+ .PHONY: bootstrap check test security
3
+ bootstrap:
4
+ $(PYTHON) -m pip install -e ".[dev]"
5
+ # Same commands as the `test` job in .github/workflows/ci.yml (T-27 scope: only paths that exist).
6
+ check:
7
+ ruff check src tests benchmarks/vs_spindle
8
+ ruff format --check src tests benchmarks/vs_spindle
9
+ mypy
10
+ $(PYTHON) -m compileall -q src/shape
11
+ $(PYTHON) scripts/check_requirements.py
12
+ $(PYTHON) scripts/check_secrets.py
13
+ pytest -q -m "not emulator and not live" --ignore=tests/demo/fabric --ignore=tests/demo/content --cov=shape --cov-fail-under=86
14
+ test:
15
+ pytest -m "not emulator and not live"
16
+ security:
17
+ pytest -m security
@@ -0,0 +1,105 @@
1
+ Metadata-Version: 2.5
2
+ Name: sqllocks-shape
3
+ Version: 0.9.0
4
+ Summary: Shape by SQLLocks — Shape as Code: profile, check and compare how your data behaves. Early access.
5
+ Project-URL: Homepage, https://github.com/sqllocks/shape
6
+ Project-URL: Repository, https://github.com/sqllocks/shape
7
+ Project-URL: Issues, https://github.com/sqllocks/shape/issues
8
+ License-Expression: MIT
9
+ License-File: LICENSE
10
+ License-File: THIRD_PARTY_NOTICES.md
11
+ Requires-Python: >=3.11
12
+ Requires-Dist: numpy<3,>=2.0
13
+ Requires-Dist: pyarrow>=14.0.1
14
+ Provides-Extra: delta
15
+ Requires-Dist: deltalake>=0.17; extra == 'delta'
16
+ Provides-Extra: dev
17
+ Requires-Dist: bandit>=1.8; extra == 'dev'
18
+ Requires-Dist: build>=1.2; extra == 'dev'
19
+ Requires-Dist: cryptography<51,>=50; extra == 'dev'
20
+ Requires-Dist: deltalake>=0.17; extra == 'dev'
21
+ Requires-Dist: hypothesis>=6.115; extra == 'dev'
22
+ Requires-Dist: import-linter>=2; extra == 'dev'
23
+ Requires-Dist: maturin<2,>=1.15; extra == 'dev'
24
+ Requires-Dist: mypy>=1.13; extra == 'dev'
25
+ Requires-Dist: pandas>=2; extra == 'dev'
26
+ Requires-Dist: pip-audit>=2.7; extra == 'dev'
27
+ Requires-Dist: py-spy>=0.4; extra == 'dev'
28
+ Requires-Dist: pytest-cov>=6; extra == 'dev'
29
+ Requires-Dist: pytest>=8.3; extra == 'dev'
30
+ Requires-Dist: pyyaml>=6; extra == 'dev'
31
+ Requires-Dist: ruff>=0.8; extra == 'dev'
32
+ Requires-Dist: sqlglot>=25; extra == 'dev'
33
+ Requires-Dist: twine>=5; extra == 'dev'
34
+ Requires-Dist: vulture>=2.11; extra == 'dev'
35
+ Requires-Dist: xxhash>=3.5; extra == 'dev'
36
+ Provides-Extra: eventhubs
37
+ Requires-Dist: azure-eventhub<6,>=5.12; extra == 'eventhubs'
38
+ Provides-Extra: kafka
39
+ Requires-Dist: confluent-kafka<4,>=2.5; extra == 'kafka'
40
+ Provides-Extra: pandas
41
+ Requires-Dist: pandas>=2; extra == 'pandas'
42
+ Provides-Extra: sign
43
+ Requires-Dist: cryptography<51,>=50; extra == 'sign'
44
+ Provides-Extra: streaming
45
+ Requires-Dist: azure-eventhub<6,>=5.12; extra == 'streaming'
46
+ Requires-Dist: confluent-kafka<4,>=2.5; extra == 'streaming'
47
+ Provides-Extra: yaml
48
+ Requires-Dist: pyyaml>=6; extra == 'yaml'
49
+ Description-Content-Type: text/markdown
50
+
51
+ # Shape
52
+
53
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
54
+
55
+ **Shape by SQLLocks** — Shape as Code: a portable, executable description of how
56
+ data behaves, not merely its schema.
57
+
58
+ > **Early access.** Profiling is available now; data generation and pipeline
59
+ > integration are in progress. See `docs/plans/COMPLETION_PLAN.md`.
60
+
61
+ Install with `pip install sqllocks-shape`. Python imports use `import shape`, the
62
+ command is `shape`, and artifacts use the `.shape` extension.
63
+
64
+ ## Quick start
65
+
66
+ ```python
67
+ import shape
68
+
69
+ p = shape.profile("customers.csv") # also: Parquet, JSONL, Delta tables, pandas, pyarrow
70
+ shape.save(p, "customers.shape")
71
+ print(p.summary()) # small JSON-safe summary per column
72
+
73
+ result = shape.check(p, {"columns": {"customer_id": {"unique": True, "nullable": False}}})
74
+ print(result.passed, result.violations)
75
+
76
+ drift = shape.diff(shape.load("customers.shape"), shape.profile("customers_next.csv"))
77
+ print(drift.drifted, drift.changes)
78
+ ```
79
+
80
+ ```bash
81
+ shape profile customers.csv -o customers.shape --html report.html --json summary.json
82
+ shape check customers.shape contract.json # exit code 1 if the contract fails
83
+ shape diff customers.shape customers_next.shape --fail-on-drift
84
+ ```
85
+
86
+ ## What a `.shape` file contains
87
+
88
+ A profile keeps real values from your data, as Spindle's profiler does: up to the 500
89
+ most frequent values per column with their counts, and each column's minimum and maximum.
90
+ Treat a `.shape` file, its HTML report and its JSON summary as you would the source data,
91
+ and don't share one from a sensitive table. A privacy-safe profile, with rare values
92
+ suppressed, is planned.
93
+
94
+ ## Design principles
95
+
96
+ - evidence carries provenance and algorithm parameters
97
+ - deterministic generation and replay
98
+ - offline by default: no network access or cloud service is required
99
+ - `.shape` readers fail closed on unsafe or corrupt containers
100
+
101
+ See `docs/PRODUCT_ARCHITECTURE.md` and `docs/specs/`.
102
+
103
+ ## License
104
+
105
+ MIT. See `LICENSE` and `THIRD_PARTY_NOTICES.md`.
@@ -0,0 +1,55 @@
1
+ # Shape
2
+
3
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
4
+
5
+ **Shape by SQLLocks** — Shape as Code: a portable, executable description of how
6
+ data behaves, not merely its schema.
7
+
8
+ > **Early access.** Profiling is available now; data generation and pipeline
9
+ > integration are in progress. See `docs/plans/COMPLETION_PLAN.md`.
10
+
11
+ Install with `pip install sqllocks-shape`. Python imports use `import shape`, the
12
+ command is `shape`, and artifacts use the `.shape` extension.
13
+
14
+ ## Quick start
15
+
16
+ ```python
17
+ import shape
18
+
19
+ p = shape.profile("customers.csv") # also: Parquet, JSONL, Delta tables, pandas, pyarrow
20
+ shape.save(p, "customers.shape")
21
+ print(p.summary()) # small JSON-safe summary per column
22
+
23
+ result = shape.check(p, {"columns": {"customer_id": {"unique": True, "nullable": False}}})
24
+ print(result.passed, result.violations)
25
+
26
+ drift = shape.diff(shape.load("customers.shape"), shape.profile("customers_next.csv"))
27
+ print(drift.drifted, drift.changes)
28
+ ```
29
+
30
+ ```bash
31
+ shape profile customers.csv -o customers.shape --html report.html --json summary.json
32
+ shape check customers.shape contract.json # exit code 1 if the contract fails
33
+ shape diff customers.shape customers_next.shape --fail-on-drift
34
+ ```
35
+
36
+ ## What a `.shape` file contains
37
+
38
+ A profile keeps real values from your data, as Spindle's profiler does: up to the 500
39
+ most frequent values per column with their counts, and each column's minimum and maximum.
40
+ Treat a `.shape` file, its HTML report and its JSON summary as you would the source data,
41
+ and don't share one from a sensitive table. A privacy-safe profile, with rare values
42
+ suppressed, is planned.
43
+
44
+ ## Design principles
45
+
46
+ - evidence carries provenance and algorithm parameters
47
+ - deterministic generation and replay
48
+ - offline by default: no network access or cloud service is required
49
+ - `.shape` readers fail closed on unsafe or corrupt containers
50
+
51
+ See `docs/PRODUCT_ARCHITECTURE.md` and `docs/specs/`.
52
+
53
+ ## License
54
+
55
+ MIT. See `LICENSE` and `THIRD_PARTY_NOTICES.md`.
@@ -0,0 +1,11 @@
1
+ # Security Policy
2
+
3
+ Report suspected vulnerabilities privately to the maintainer at
4
+ **sqllocks@sqlbites.com**, or through GitHub's private vulnerability reporting on
5
+ this repository, rather than opening a public issue. Do not include real secrets,
6
+ PII or customer datasets in reports.
7
+
8
+ Shape is in early access; only the latest release receives fixes.
9
+
10
+ Shape treats artifacts, packs, plugins, connector responses and reference assets as
11
+ untrusted inputs. See `docs/THREAT_MODEL.md`.
@@ -0,0 +1,20 @@
1
+ # Third-Party Notices
2
+
3
+ Shape is released under the MIT license (see `LICENSE`).
4
+
5
+ ## Spindle
6
+
7
+ Parts of Shape's reference data and behaviour are derived from Spindle.
8
+
9
+ Spindle: MIT, Copyright (c) 2025-2026 SQLLocks (Jonathan Stewart). Where code or
10
+ data copied or substantially derived from Spindle is included, its MIT notice is
11
+ retained.
12
+
13
+ ## GeoNames
14
+
15
+ Postal-code and place reference data is derived from GeoNames (https://www.geonames.org/).
16
+
17
+ GeoNames data is licensed under the Creative Commons Attribution 4.0 International
18
+ license (CC-BY-4.0), https://creativecommons.org/licenses/by/4.0/. Attribution:
19
+ "This work includes data from GeoNames (https://www.geonames.org/), licensed under
20
+ CC-BY-4.0." Any distribution that includes this data must retain this attribution.