hecks 2.8.0 → 3.0.0

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 (886) hide show
  1. checksums.yaml +4 -4
  2. data/exe/hecks +50 -7
  3. data/lib/hecks/adapters/driven/claude_code.rb +4 -104
  4. data/lib/hecks/adapters/driven/d1.rb +44 -237
  5. data/lib/hecks/adapters/driven/folder.rb +17 -76
  6. data/lib/hecks/adapters/driven/google_authentication.rb +15 -49
  7. data/lib/hecks/adapters/driven/governance_authorization.rb +23 -70
  8. data/lib/hecks/adapters/driven/heki/journal.rb +8 -41
  9. data/lib/hecks/adapters/driven/heki/saga_store.rb +12 -54
  10. data/lib/hecks/adapters/driven/heki/snapshot.rb +4 -12
  11. data/lib/hecks/adapters/driven/heki.rb +13 -42
  12. data/lib/hecks/adapters/driven/identity_registry.rb +3 -14
  13. data/lib/hecks/adapters/driven/in_memory_ordering.rb +9 -26
  14. data/lib/hecks/adapters/driven/in_process_key_vault.rb +2 -14
  15. data/lib/hecks/adapters/driven/lambda/client.rb +10 -51
  16. data/lib/hecks/adapters/driven/lambda.rb +10 -84
  17. data/lib/hecks/adapters/driven/local_storage.rb +5 -40
  18. data/lib/hecks/adapters/driven/memory.rb +32 -100
  19. data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +5 -21
  20. data/lib/hecks/adapters/driven/postgres/codec.rb +6 -28
  21. data/lib/hecks/adapters/driven/postgres/outbox.rb +3 -12
  22. data/lib/hecks/adapters/driven/postgres/reconnect.rb +10 -32
  23. data/lib/hecks/adapters/driven/postgres/schema_builder.rb +34 -108
  24. data/lib/hecks/adapters/driven/postgres/shared_connection.rb +180 -0
  25. data/lib/hecks/adapters/driven/postgres.rb +149 -136
  26. data/lib/hecks/adapters/driven/postgres_era.adapter +4 -15
  27. data/lib/hecks/adapters/driven/prism.rb +48 -38
  28. data/lib/hecks/adapters/driven/sql_query_builder.rb +21 -121
  29. data/lib/hecks/adapters/driven/sqlite/codec.rb +8 -40
  30. data/lib/hecks/adapters/driven/sqlite/projection.rb +26 -82
  31. data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +40 -84
  32. data/lib/hecks/adapters/driven/sqlite.rb +128 -65
  33. data/lib/hecks/adapters/driven/tenant_provisioner.rb +76 -62
  34. data/lib/hecks/adapters/driven.rb +5 -36
  35. data/lib/hecks/adapters/driving/github_webhook.rb +8 -76
  36. data/lib/hecks/behaviors/dsl.rb +7 -25
  37. data/lib/hecks/behaviors/expectations.rb +32 -142
  38. data/lib/hecks/behaviors/ir.rb +7 -20
  39. data/lib/hecks/behaviors/rspec.rb +6 -17
  40. data/lib/hecks/behaviors/runner.rb +10 -34
  41. data/lib/hecks/behaviors.rb +4 -8
  42. data/lib/hecks/bench/cli.rb +62 -0
  43. data/lib/hecks/bench/environment.rb +71 -0
  44. data/lib/hecks/bench/postgres_probe.rb +30 -0
  45. data/lib/hecks/bench/report.rb +76 -0
  46. data/lib/hecks/bench/ruby_runner.rb +93 -0
  47. data/lib/hecks/bench/run.rb +55 -0
  48. data/lib/hecks/bench/rust_runner.rb +101 -0
  49. data/lib/hecks/bench/stats.rb +46 -0
  50. data/lib/hecks/bench/suite.rb +98 -0
  51. data/lib/hecks/bench/workload.rb +89 -0
  52. data/lib/hecks/bench.rb +17 -0
  53. data/lib/hecks/bluebook/aggregate.rb +9 -75
  54. data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +9 -38
  55. data/lib/hecks/bluebook/assembly/build.rb +4 -15
  56. data/lib/hecks/bluebook/assembly/contract.rb +15 -136
  57. data/lib/hecks/bluebook/assembly/contracts.rb +56 -174
  58. data/lib/hecks/bluebook/assembly/marks.rb +31 -223
  59. data/lib/hecks/bluebook/assembly/specializer.rb +6 -52
  60. data/lib/hecks/bluebook/assembly.rb +6 -45
  61. data/lib/hecks/bluebook/attribute.rb +12 -61
  62. data/lib/hecks/bluebook/behaviour/aggregate.rb +39 -39
  63. data/lib/hecks/bluebook/behaviour/attribute.rb +3 -14
  64. data/lib/hecks/bluebook/behaviour/chapter.rb +14 -42
  65. data/lib/hecks/bluebook/behaviour/command.rb +14 -66
  66. data/lib/hecks/bluebook/behaviour/domain_port.rb +11 -20
  67. data/lib/hecks/bluebook/behaviour/entity.rb +7 -27
  68. data/lib/hecks/bluebook/behaviour/hexagon.rb +23 -41
  69. data/lib/hecks/bluebook/behaviour/lifecycle.rb +15 -40
  70. data/lib/hecks/bluebook/behaviour/policy.rb +23 -52
  71. data/lib/hecks/bluebook/behaviour/process_manager.rb +30 -57
  72. data/lib/hecks/bluebook/behaviour/read_model.rb +25 -31
  73. data/lib/hecks/bluebook/behaviour/traits.rb +27 -64
  74. data/lib/hecks/bluebook/behaviour/value_object.rb +5 -24
  75. data/lib/hecks/bluebook/capabilities.rb +17 -49
  76. data/lib/hecks/bluebook/chapter.rb +16 -50
  77. data/lib/hecks/bluebook/command.rb +23 -81
  78. data/lib/hecks/bluebook/domain_port.rb +49 -67
  79. data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +50 -229
  80. data/lib/hecks/bluebook/dsl/aggregate_builder.rb +50 -377
  81. data/lib/hecks/bluebook/dsl/attribute_collector.rb +33 -204
  82. data/lib/hecks/bluebook/dsl/binding_proxy.rb +16 -69
  83. data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +96 -708
  84. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +63 -169
  85. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +3 -1
  86. data/lib/hecks/bluebook/dsl/command_builder.rb +74 -546
  87. data/lib/hecks/bluebook/dsl/const_shim.rb +8 -41
  88. data/lib/hecks/bluebook/dsl/domain_port_builder.rb +42 -89
  89. data/lib/hecks/bluebook/dsl/entity_builder.rb +44 -330
  90. data/lib/hecks/bluebook/dsl/generic_dispatch.rb +20 -269
  91. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +148 -197
  92. data/lib/hecks/bluebook/dsl/identity_declaration.rb +13 -88
  93. data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +6 -20
  94. data/lib/hecks/bluebook/dsl/policy_builder.rb +16 -88
  95. data/lib/hecks/bluebook/dsl/port_builder.rb +2 -6
  96. data/lib/hecks/bluebook/dsl/port_operation_builder.rb +22 -96
  97. data/lib/hecks/bluebook/dsl/process_manager_builder.rb +31 -184
  98. data/lib/hecks/bluebook/dsl/query_builder.rb +38 -43
  99. data/lib/hecks/bluebook/dsl/read_model_builder.rb +75 -201
  100. data/lib/hecks/bluebook/dsl/rule_reference.rb +22 -163
  101. data/lib/hecks/bluebook/dsl/translation_builder.rb +28 -114
  102. data/lib/hecks/bluebook/dsl/value_object_builder.rb +10 -124
  103. data/lib/hecks/bluebook/dsl/word_gate.rb +16 -162
  104. data/lib/hecks/bluebook/dsl/world_builder.rb +46 -111
  105. data/lib/hecks/bluebook/entity.rb +13 -71
  106. data/lib/hecks/bluebook/expression/ast_json.rb +24 -190
  107. data/lib/hecks/bluebook/expression/ast_reader.rb +12 -54
  108. data/lib/hecks/bluebook/expression/canonical_form.rb +11 -88
  109. data/lib/hecks/bluebook/expression/evaluator.rb +47 -295
  110. data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +30 -147
  111. data/lib/hecks/bluebook/expression/resolver.rb +39 -661
  112. data/lib/hecks/bluebook/hexagon.rb +18 -33
  113. data/lib/hecks/bluebook/lifecycle.rb +5 -16
  114. data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -7
  115. data/lib/hecks/bluebook/meta_validator/judge.rb +111 -361
  116. data/lib/hecks/bluebook/meta_validator/plan.rb +33 -162
  117. data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -7
  118. data/lib/hecks/bluebook/meta_validator/readings.rb +56 -342
  119. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +25 -176
  120. data/lib/hecks/bluebook/meta_validator/shapes.rb +53 -267
  121. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +47 -306
  122. data/lib/hecks/bluebook/meta_validator/translation_judge.rb +7 -43
  123. data/lib/hecks/bluebook/meta_validator/verdict_cache.rb +246 -0
  124. data/lib/hecks/bluebook/meta_validator/world_judge.rb +6 -18
  125. data/lib/hecks/bluebook/meta_validator.rb +87 -352
  126. data/lib/hecks/bluebook/model_check/client_profile.rb +6 -21
  127. data/lib/hecks/bluebook/model_check.rb +122 -596
  128. data/lib/hecks/bluebook/pattern_subset.rb +49 -69
  129. data/lib/hecks/bluebook/process_manager.rb +13 -83
  130. data/lib/hecks/bluebook/project_loader.rb +3 -39
  131. data/lib/hecks/bluebook/project_register.rb +12 -60
  132. data/lib/hecks/bluebook/query.rb +27 -51
  133. data/lib/hecks/bluebook/read_model.rb +57 -81
  134. data/lib/hecks/bluebook/reference.rb +7 -41
  135. data/lib/hecks/bluebook/smoke_test.rb +9 -99
  136. data/lib/hecks/bluebook/synthesizer.rb +13 -62
  137. data/lib/hecks/bluebook/translation.rb +26 -62
  138. data/lib/hecks/bluebook/value_object.rb +11 -36
  139. data/lib/hecks/bluebook.rb +5 -22
  140. data/lib/hecks/cache_dir.rb +4 -23
  141. data/lib/hecks/canonical_json.rb +30 -0
  142. data/lib/hecks/chapters.rb +102 -0
  143. data/lib/hecks/cli/behaviors.rb +61 -0
  144. data/lib/hecks/cli/canonicalise.rb +25 -0
  145. data/lib/hecks/cli/check_engine_agreement.rb +32 -0
  146. data/lib/hecks/cli/check_era.rb +88 -0
  147. data/lib/hecks/cli/console.rb +66 -0
  148. data/lib/hecks/cli/deploy_template_diff.rb +40 -0
  149. data/lib/hecks/cli/doc_coverage.rb +32 -0
  150. data/lib/hecks/cli/document.rb +5 -23
  151. data/lib/hecks/cli/expression_projection.rb +41 -0
  152. data/lib/hecks/cli/follow.rb +88 -0
  153. data/lib/hecks/cli/history.rb +44 -0
  154. data/lib/hecks/cli/ir.rb +4 -6
  155. data/lib/hecks/cli/mcp.rb +5 -6
  156. data/lib/hecks/cli/model_check.rb +24 -88
  157. data/lib/hecks/cli/pattern_cases.rb +47 -0
  158. data/lib/hecks/cli/present.rb +39 -0
  159. data/lib/hecks/cli/project_cli.rb +223 -64
  160. data/lib/hecks/cli/project_diagrams.rb +4 -10
  161. data/lib/hecks/cli/project_glossary.rb +44 -0
  162. data/lib/hecks/cli/reference.rb +46 -0
  163. data/lib/hecks/cli/refresh_projections.rb +44 -0
  164. data/lib/hecks/cli/refresh_rspec_runtime_baseline.rb +150 -0
  165. data/lib/hecks/cli/release.rb +70 -0
  166. data/lib/hecks/cli/release_gem.rb +59 -0
  167. data/lib/hecks/cli/rspec_io_parallel_files.rb +137 -0
  168. data/lib/hecks/cli/rspec_shard_files.rb +66 -0
  169. data/lib/hecks/cli/run.rb +15 -61
  170. data/lib/hecks/cli/seed_semantics_corpus.rb +71 -0
  171. data/lib/hecks/cli/serve_query_ir_mcp.rb +30 -0
  172. data/lib/hecks/cli/shape.rb +70 -0
  173. data/lib/hecks/cli/smoke_http.rb +230 -0
  174. data/lib/hecks/cli/smoke_test.rb +7 -19
  175. data/lib/hecks/cli/spec_example.rb +27 -0
  176. data/lib/hecks/cli/statements.rb +32 -0
  177. data/lib/hecks/cli/stores.rb +4 -6
  178. data/lib/hecks/cli/stress_concurrency_specs.rb +177 -0
  179. data/lib/hecks/cli.rb +216 -73
  180. data/lib/hecks/codemod.rb +324 -0
  181. data/lib/hecks/construct.rb +8 -34
  182. data/lib/hecks/corpus.rb +423 -0
  183. data/lib/hecks/deploy/bluebook/deploy.bluebook +617 -158
  184. data/lib/hecks/deploy/bluebook/deploy.hecksagon +41 -11
  185. data/lib/hecks/deploy/oidc.json +82 -2
  186. data/lib/hecks/doc/reference.rb +351 -0
  187. data/lib/hecks/doors/cli_door.rb +196 -0
  188. data/lib/hecks/doors/cli_runner.rb +297 -0
  189. data/lib/hecks/{facade → doors}/command_request.rb +14 -34
  190. data/lib/hecks/doors/handle.rb +206 -0
  191. data/lib/hecks/doors/json_door.rb +132 -0
  192. data/lib/hecks/doors/launcher_options.rb +129 -0
  193. data/lib/hecks/{cli → doors}/mcp_door.rb +25 -120
  194. data/lib/hecks/doors/mcp_door_scope.rb +97 -0
  195. data/lib/hecks/doors/ruby_door/aggregate_door.rb +162 -0
  196. data/lib/hecks/doors/ruby_door/chapter.rb +72 -0
  197. data/lib/hecks/doors/ruby_door.rb +77 -0
  198. data/lib/hecks/doors.rb +61 -0
  199. data/lib/hecks/embryonaut_bluebook/lock.rb +3 -35
  200. data/lib/hecks/embryonaut_bluebook/shape.rb +1 -17
  201. data/lib/hecks/embryonaut_bluebook/vendor.rb +8 -53
  202. data/lib/hecks/embryonaut_bluebook/vendor_cli.rb +4 -19
  203. data/lib/hecks/embryonaut_bluebook.rb +5 -72
  204. data/lib/hecks/engine_agreement.rb +156 -0
  205. data/lib/hecks/facade.rb +23 -51
  206. data/lib/hecks/forms/app.rb +21 -76
  207. data/lib/hecks/forms/banking_presentation.rb +50 -0
  208. data/lib/hecks/forms/command_form_renderer.rb +10 -29
  209. data/lib/hecks/forms/field_renderer.rb +17 -156
  210. data/lib/hecks/forms/field_shape.rb +31 -222
  211. data/lib/hecks/forms/html.rb +12 -47
  212. data/lib/hecks/forms/index_renderer.rb +1 -4
  213. data/lib/hecks/forms/page.rb +3 -9
  214. data/lib/hecks/forms/params.rb +14 -60
  215. data/lib/hecks/forms/port_argument.rb +2 -19
  216. data/lib/hecks/forms/query_form_renderer.rb +4 -79
  217. data/lib/hecks/forms/record_renderer.rb +8 -75
  218. data/lib/hecks/forms/record_table.rb +7 -50
  219. data/lib/hecks/forms/reference_options.rb +3 -30
  220. data/lib/hecks/forms/value_object_shape.rb +8 -35
  221. data/lib/hecks/forms.rb +5 -33
  222. data/lib/hecks/fqn.rb +5 -12
  223. data/lib/hecks/framework/bluebook/compliance.bluebook +16 -65
  224. data/lib/hecks/framework/bluebook/console_settings.bluebook +47 -134
  225. data/lib/hecks/framework/bluebook/framework.hecksagon +5 -14
  226. data/lib/hecks/framework/bluebook/governance.bluebook +13 -34
  227. data/lib/hecks/framework/bluebook/identity.bluebook +11 -26
  228. data/lib/hecks/framework/bluebook/privacy.bluebook +8 -33
  229. data/lib/hecks/framework.rb +11 -80
  230. data/lib/hecks/freezer.rb +5 -39
  231. data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +393 -0
  232. data/lib/hecks/fuzzing/combination_miner.rb +86 -0
  233. data/lib/hecks/fuzzing/concurrent_dispatch.rb +214 -0
  234. data/lib/hecks/fuzzing/coverage_campaign.rb +143 -0
  235. data/lib/hecks/fuzzing/differential.rb +156 -0
  236. data/lib/hecks/fuzzing/domain_generator.rb +615 -0
  237. data/lib/hecks/fuzzing/era_boundary.rb +71 -0
  238. data/lib/hecks/fuzzing/form_census.rb +136 -0
  239. data/lib/hecks/fuzzing/generated_domain_check.rb +93 -0
  240. data/lib/hecks/fuzzing/invalid_value_generator.rb +64 -0
  241. data/lib/hecks/fuzzing/isolated_boot.rb +301 -0
  242. data/lib/hecks/fuzzing/nondeterministic.rb +51 -0
  243. data/lib/hecks/fuzzing/outside_world.rb +45 -0
  244. data/lib/hecks/fuzzing/persistence_parity.rb +102 -0
  245. data/lib/hecks/fuzzing/properties/corrections.rb +88 -0
  246. data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +314 -0
  247. data/lib/hecks/fuzzing/properties/guards.rb +190 -0
  248. data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +300 -0
  249. data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +93 -0
  250. data/lib/hecks/fuzzing/properties/outbox.rb +89 -0
  251. data/lib/hecks/fuzzing/properties/querying.rb +175 -0
  252. data/lib/hecks/fuzzing/properties.rb +162 -0
  253. data/lib/hecks/fuzzing/qa_settings.rb +123 -0
  254. data/lib/hecks/fuzzing/replay.rb +505 -0
  255. data/lib/hecks/fuzzing/rotation_priority.rb +48 -0
  256. data/lib/hecks/fuzzing/rust_gap_manifest.rb +108 -0
  257. data/lib/hecks/fuzzing/self_consistency.rb +339 -0
  258. data/lib/hecks/fuzzing/sequence_generator/adversary.rb +385 -0
  259. data/lib/hecks/fuzzing/sequence_generator/catalog.rb +132 -0
  260. data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +95 -0
  261. data/lib/hecks/fuzzing/sequence_generator/picker.rb +77 -0
  262. data/lib/hecks/fuzzing/sequence_generator/query_binding.rb +109 -0
  263. data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +237 -0
  264. data/lib/hecks/fuzzing/sequence_generator.rb +189 -0
  265. data/lib/hecks/fuzzing/shrinker.rb +166 -0
  266. data/lib/hecks/fuzzing/structural_skips.rb +33 -0
  267. data/lib/hecks/fuzzing/sweep_depth.rb +43 -0
  268. data/lib/hecks/fuzzing/target_capabilities.rb +163 -0
  269. data/lib/hecks/fuzzing/value_generator.rb +216 -0
  270. data/lib/hecks/fuzzing.rb +23 -0
  271. data/lib/hecks/grammar/evolve.rb +336 -0
  272. data/lib/hecks/grammar/expression.bluebook +15 -40
  273. data/lib/hecks/grammar/translation.bluebook +3 -6
  274. data/lib/hecks/grammar.rb +16 -41
  275. data/lib/hecks/hecks/adapters/codebase/codemods.rb +45 -0
  276. data/lib/hecks/hecks/adapters/codebase/conformance.rb +71 -0
  277. data/lib/hecks/hecks/adapters/codebase/corpus_tasks.rb +202 -0
  278. data/lib/hecks/hecks/adapters/codebase/gem_registry.rb +80 -0
  279. data/lib/hecks/hecks/adapters/codebase/kernel_tables.rb +54 -0
  280. data/lib/hecks/hecks/adapters/codebase/language.rb +240 -0
  281. data/lib/hecks/hecks/adapters/codebase/npm_registry.rb +102 -0
  282. data/lib/hecks/hecks/adapters/codebase/publishing.rb +142 -0
  283. data/lib/hecks/hecks/adapters/codebase/regeneration.rb +67 -0
  284. data/lib/hecks/hecks/adapters/codebase/release_facts.rb +90 -0
  285. data/lib/hecks/hecks/adapters/codebase/ruby_child.rb +83 -0
  286. data/lib/hecks/hecks/adapters/codebase/secret_vault.rb +36 -0
  287. data/lib/hecks/hecks/adapters/codebase/source_tree.adapter +7 -0
  288. data/lib/hecks/hecks/adapters/codebase/source_tree.rb +189 -0
  289. data/lib/hecks/hecks/adapters/codebase/sqlite_fixture.rb +71 -0
  290. data/lib/hecks/hecks/adapters/codebase/style.rb +171 -0
  291. data/lib/hecks/hecks/adapters/codebase/test_runner.rb +55 -0
  292. data/lib/hecks/hecks/adapters/codebase/test_suite.rb +165 -0
  293. data/lib/hecks/hecks/adapters/codebase/tree.rb +111 -0
  294. data/lib/hecks/hecks/adapters/console_capture.rb +79 -0
  295. data/lib/hecks/hecks/adapters/deploy_toolchain.adapter +7 -0
  296. data/lib/hecks/hecks/adapters/deploy_toolchain.rb +108 -0
  297. data/lib/hecks/hecks/adapters/git.adapter +7 -0
  298. data/lib/hecks/hecks/adapters/git.rb +102 -0
  299. data/lib/hecks/hecks/adapters/host_http.adapter +7 -0
  300. data/lib/hecks/hecks/adapters/host_http.rb +65 -0
  301. data/lib/hecks/hecks/adapters/in_process_boot.adapter +7 -0
  302. data/lib/hecks/hecks/adapters/in_process_boot.rb +197 -0
  303. data/lib/hecks/hecks/adapters/in_process_operations.rb +202 -0
  304. data/lib/hecks/hecks/adapters/journal_store/changes.rb +143 -0
  305. data/lib/hecks/hecks/adapters/journal_store/compaction.rb +145 -0
  306. data/lib/hecks/hecks/adapters/journal_store/edge_audit.rb +132 -0
  307. data/lib/hecks/hecks/adapters/journal_store/examination.rb +135 -0
  308. data/lib/hecks/hecks/adapters/journal_store/held_domain.rb +163 -0
  309. data/lib/hecks/hecks/adapters/journal_store/readings.rb +187 -0
  310. data/lib/hecks/hecks/adapters/journal_store.adapter +7 -0
  311. data/lib/hecks/hecks/adapters/journal_store.rb +64 -0
  312. data/lib/hecks/hecks/adapters/local_files.adapter +7 -0
  313. data/lib/hecks/hecks/adapters/local_files.rb +46 -0
  314. data/lib/hecks/hecks/adapters/pg_admin.adapter +7 -0
  315. data/lib/hecks/hecks/adapters/pg_admin.rb +245 -0
  316. data/lib/hecks/hecks/adapters/process_pool.adapter +7 -0
  317. data/lib/hecks/hecks/adapters/process_pool.rb +119 -0
  318. data/lib/hecks/hecks/adapters/rust_toolchain.adapter +7 -0
  319. data/lib/hecks/hecks/adapters/rust_toolchain.rb +179 -0
  320. data/lib/hecks/hecks/adapters/rust_workspace.rb +150 -0
  321. data/lib/hecks/hecks/adapters/shell.adapter +7 -0
  322. data/lib/hecks/hecks/adapters/shell.rb +49 -0
  323. data/lib/hecks/hecks/adapters/terminal.adapter +7 -0
  324. data/lib/hecks/hecks/adapters/terminal.rb +74 -0
  325. data/lib/hecks/hecks/codebase.behaviors +172 -0
  326. data/lib/hecks/hecks/codebase.bluebook +2453 -0
  327. data/lib/hecks/hecks/context_map.hecksagon +13 -0
  328. data/lib/hecks/hecks/custodian.behaviors +179 -0
  329. data/lib/hecks/hecks/custodian.bluebook +1847 -0
  330. data/lib/hecks/hecks/deploy.behaviors +74 -0
  331. data/lib/hecks/hecks/deploy.world +12 -0
  332. data/lib/hecks/hecks/environments/memory.world +10 -0
  333. data/lib/hecks/hecks/governance.world +7 -0
  334. data/lib/hecks/hecks/hecks.behaviors +62 -0
  335. data/lib/hecks/hecks/hecks.bluebook +124 -0
  336. data/lib/hecks/hecks/hecks.hecksagon +390 -0
  337. data/lib/hecks/hecks/hecks.world +42 -0
  338. data/lib/hecks/ir.rb +14 -83
  339. data/lib/hecks/kernel_capabilities.rb +194 -0
  340. data/lib/hecks/language/adapter.bluebook +2 -7
  341. data/lib/hecks/language/bluebook/aggregate.bluebook +56 -221
  342. data/lib/hecks/language/bluebook/attaches/paging.bluebook +6 -15
  343. data/lib/hecks/language/bluebook/bluebook.bluebook +26 -83
  344. data/lib/hecks/language/bluebook/bluebook.hecksagon +3 -15
  345. data/lib/hecks/language/bluebook/command.bluebook +27 -144
  346. data/lib/hecks/language/bluebook/entity.bluebook +24 -97
  347. data/lib/hecks/language/bluebook/policy.bluebook +16 -67
  348. data/lib/hecks/language/bluebook/process_manager.bluebook +28 -151
  349. data/lib/hecks/language/bluebook/projection.bluebook +126 -60
  350. data/lib/hecks/language/bluebook/query.bluebook +19 -43
  351. data/lib/hecks/language/bluebook/shape.bluebook +23 -73
  352. data/lib/hecks/language/bluebook/syntax.bluebook +51 -262
  353. data/lib/hecks/language/bluebook/vocabulary.bluebook +83 -198
  354. data/lib/hecks/language/hecksagon/adapter_binding.bluebook +3 -10
  355. data/lib/hecks/language/hecksagon/domain_port.bluebook +14 -19
  356. data/lib/hecks/language/hecksagon/hecksagon.bluebook +26 -25
  357. data/lib/hecks/language/hecksagon/port_operation.bluebook +3 -14
  358. data/lib/hecks/language/oidc.json +35 -0
  359. data/lib/hecks/language/port.bluebook +4 -17
  360. data/lib/hecks/language/translation/translation.bluebook +3 -9
  361. data/lib/hecks/language/translation/translation_aggregate.bluebook +5 -24
  362. data/lib/hecks/language/world/wiring.bluebook +1 -3
  363. data/lib/hecks/language/world/world.bluebook +5 -7
  364. data/lib/hecks/literal.rb +8 -50
  365. data/lib/hecks/mcp_stdio_guard.rb +4 -41
  366. data/lib/hecks/naming.rb +29 -137
  367. data/lib/hecks/persistence_legacy_fixture/regenerate.rb +161 -0
  368. data/lib/hecks/persistence_legacy_fixture.rb +113 -0
  369. data/lib/hecks/ports/access_control.rb +7 -23
  370. data/lib/hecks/ports/agent/answers.rb +5 -23
  371. data/lib/hecks/ports/agent.rb +47 -172
  372. data/lib/hecks/ports/authentication.rb +12 -39
  373. data/lib/hecks/ports/authorization.rb +16 -43
  374. data/lib/hecks/ports/clock.rb +5 -45
  375. data/lib/hecks/ports/extraction.rb +7 -12
  376. data/lib/hecks/ports/identity_assignment.rb +8 -29
  377. data/lib/hecks/ports/identity_generation.rb +6 -29
  378. data/lib/hecks/ports/identity_resolution.rb +2 -10
  379. data/lib/hecks/ports/key_vault.rb +9 -45
  380. data/lib/hecks/ports/persistence/append_only.rb +61 -64
  381. data/lib/hecks/ports/persistence/binding_policy.rb +4 -14
  382. data/lib/hecks/ports/persistence/codec_boundary.rb +20 -80
  383. data/lib/hecks/ports/persistence/null_saga_store.rb +4 -20
  384. data/lib/hecks/ports/persistence/plugin.rb +13 -42
  385. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +44 -144
  386. data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +15 -115
  387. data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +20 -85
  388. data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +6 -25
  389. data/lib/hecks/ports/persistence/plugins/era/expected_era.rb +18 -24
  390. data/lib/hecks/ports/persistence/plugins/era/lineage.rb +55 -181
  391. data/lib/hecks/ports/persistence/plugins/era/postgres_era/events.rb +77 -0
  392. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +12 -122
  393. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +28 -128
  394. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +73 -474
  395. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +31 -124
  396. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +45 -219
  397. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +13 -108
  398. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +19 -76
  399. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +9 -49
  400. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +6 -123
  401. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +23 -55
  402. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +14 -72
  403. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +7 -16
  404. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +43 -127
  405. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +13 -45
  406. data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +131 -555
  407. data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +13 -63
  408. data/lib/hecks/ports/persistence/plugins/era/translation/approval_file.rb +227 -0
  409. data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +2 -17
  410. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +3 -14
  411. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +13 -58
  412. data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +3 -17
  413. data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +9 -26
  414. data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +50 -47
  415. data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +18 -124
  416. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +34 -123
  417. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/renderer.rb +5 -12
  418. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +3 -9
  419. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -14
  420. data/lib/hecks/ports/persistence/plugins/era/translation.rb +1 -0
  421. data/lib/hecks/ports/persistence/plugins/era.rb +4 -23
  422. data/lib/hecks/ports/persistence/postgres_dump/connection.rb +7 -23
  423. data/lib/hecks/ports/persistence/postgres_dump.rb +4 -35
  424. data/lib/hecks/ports/persistence/remote_runtime.rb +2 -24
  425. data/lib/hecks/ports/persistence/repository_factory.rb +8 -27
  426. data/lib/hecks/ports/persistence/state_codec.rb +47 -108
  427. data/lib/hecks/ports/persistence.rb +7 -14
  428. data/lib/hecks/ports/projection.rb +42 -84
  429. data/lib/hecks/ports/query/in_memory.rb +10 -58
  430. data/lib/hecks/ports/query/ordering.rb +11 -32
  431. data/lib/hecks/ports/query.rb +14 -37
  432. data/lib/hecks/ports.rb +2 -8
  433. data/lib/hecks/projection_files.rb +285 -0
  434. data/lib/hecks/projections/bootstrap_table.rb +12 -44
  435. data/lib/hecks/projections/deploy/fargate/assembly.rb +2 -15
  436. data/lib/hecks/projections/deploy/fargate/cdn.rb +1 -48
  437. data/lib/hecks/projections/deploy/fargate/cdn_default.rb +2 -11
  438. data/lib/hecks/projections/deploy/fargate/check.rb +5 -14
  439. data/lib/hecks/projections/deploy/fargate/containers.rb +3 -78
  440. data/lib/hecks/projections/deploy/fargate/extras.rb +3 -44
  441. data/lib/hecks/projections/deploy/fargate/monitoring.rb +0 -44
  442. data/lib/hecks/projections/deploy/fargate/settings.rb +2 -54
  443. data/lib/hecks/projections/deploy/fargate/yaml.rb +13 -58
  444. data/lib/hecks/projections/deploy/fargate.rb +40 -207
  445. data/lib/hecks/projections/deploy/lambda.rb +191 -708
  446. data/lib/hecks/projections/deploy/preview/access_yaml.rb +1 -33
  447. data/lib/hecks/projections/deploy/preview/containers.rb +6 -111
  448. data/lib/hecks/projections/deploy/preview/preview.sh.erb +1 -1
  449. data/lib/hecks/projections/deploy/preview/routing_yaml.rb +4 -56
  450. data/lib/hecks/projections/deploy/preview/script.rb +2 -14
  451. data/lib/hecks/projections/deploy/preview/settings.rb +3 -33
  452. data/lib/hecks/projections/deploy/preview/task_yaml.rb +2 -38
  453. data/lib/hecks/projections/deploy/preview/template.rb +3 -59
  454. data/lib/hecks/projections/deploy/preview.rb +2 -67
  455. data/lib/hecks/projections/deploy/scripts/deploy-service.sh.tmpl +1 -1
  456. data/lib/hecks/projections/deploy/scripts/expected-era.header +1 -1
  457. data/lib/hecks/projections/deploy/scripts/hosting.mk.tmpl +3 -3
  458. data/lib/hecks/projections/deploy/scripts/settings.rb +3 -25
  459. data/lib/hecks/projections/deploy/scripts/smoke-after-deploy.sh.tmpl +1 -1
  460. data/lib/hecks/projections/deploy/scripts.rb +4 -57
  461. data/lib/hecks/projections/deploy/shared.rb +48 -147
  462. data/lib/hecks/projections/deploy/smoke.rb +4 -61
  463. data/lib/hecks/projections/deploy/template_diff/comparer.rb +3 -25
  464. data/lib/hecks/projections/deploy/template_diff/loader.rb +2 -11
  465. data/lib/hecks/projections/deploy/template_diff.rb +5 -57
  466. data/lib/hecks/projections/diagrams.rb +22 -584
  467. data/lib/hecks/projections/glossary/html.rb +14 -130
  468. data/lib/hecks/projections/glossary/markdown.rb +8 -69
  469. data/lib/hecks/projections/glossary/mermaid.rb +9 -66
  470. data/lib/hecks/projections/glossary/sensitivity.rb +5 -34
  471. data/lib/hecks/projections/glossary/sentences.rb +14 -159
  472. data/lib/hecks/projections/glossary.rb +30 -222
  473. data/lib/hecks/projections/ir.rb +3 -10
  474. data/lib/hecks/projections/model/deviations.rb +16 -43
  475. data/lib/hecks/projections/model.rb +12 -51
  476. data/lib/hecks/projections/oidc.rb +12 -56
  477. data/lib/hecks/projections/parser_table.rb +13 -32
  478. data/lib/hecks/projections/reference.rb +4 -18
  479. data/lib/hecks/projections/rust_vocabulary.rb +13 -251
  480. data/lib/hecks/projections/shape.rb +3 -29
  481. data/lib/hecks/projections/statements.rb +7 -86
  482. data/lib/hecks/projections/vocabulary.rb +6 -22
  483. data/lib/hecks/projections.rb +2 -16
  484. data/lib/hecks/projector/cli_projector.rb +154 -400
  485. data/lib/hecks/projector/docs_projector.rb +10 -201
  486. data/lib/hecks/projector/exporter.rb +42 -134
  487. data/lib/hecks/projector/ir_projector.rb +2 -9
  488. data/lib/hecks/projector/narrate_projector.rb +15 -189
  489. data/lib/hecks/projector/target.rb +13 -76
  490. data/lib/hecks/projector.rb +30 -121
  491. data/lib/hecks/quality_control/adapters/agent.adapter +7 -0
  492. data/lib/hecks/quality_control/adapters/agent.rb +58 -0
  493. data/lib/hecks/quality_control/adapters/angle_tools.adapter +7 -0
  494. data/lib/hecks/quality_control/adapters/angle_tools.rb +15 -0
  495. data/lib/hecks/quality_control/adapters/clearance_recorder.rb +36 -0
  496. data/lib/hecks/quality_control/adapters/clearance_tools.adapter +7 -0
  497. data/lib/hecks/quality_control/adapters/clearance_tools.rb +17 -0
  498. data/lib/hecks/quality_control/adapters/git_pr.adapter +7 -0
  499. data/lib/hecks/quality_control/adapters/git_pr.rb +226 -0
  500. data/lib/hecks/quality_control/adapters/github_checks.adapter +9 -0
  501. data/lib/hecks/quality_control/adapters/github_checks.rb +83 -0
  502. data/lib/hecks/quality_control/adapters/github_ci_webhook.rb +56 -0
  503. data/lib/hecks/quality_control/adapters/github_issues.adapter +7 -0
  504. data/lib/hecks/quality_control/adapters/github_issues.rb +49 -0
  505. data/lib/hecks/quality_control/adapters/qa_tool.rb +59 -0
  506. data/lib/hecks/quality_control/adapters/sweep_tools.adapter +7 -0
  507. data/lib/hecks/quality_control/adapters/sweep_tools.rb +51 -0
  508. data/lib/hecks/quality_control/adapters/target_tools.adapter +7 -0
  509. data/lib/hecks/quality_control/adapters/target_tools.rb +43 -0
  510. data/lib/hecks/quality_control/cli/child.rb +45 -0
  511. data/lib/hecks/quality_control/cli/qa_concurrency_racer.rb +45 -0
  512. data/lib/hecks/quality_control/cli/qa_discover_external_domains.rb +248 -0
  513. data/lib/hecks/quality_control/cli/qa_domain_novelty.rb +163 -0
  514. data/lib/hecks/quality_control/cli/qa_generated_domains.rb +450 -0
  515. data/lib/hecks/quality_control/cli/qa_log_bug.rb +195 -0
  516. data/lib/hecks/quality_control/cli/qa_mine_combinations.rb +220 -0
  517. data/lib/hecks/quality_control/cli/qa_open_pr.rb +305 -0
  518. data/lib/hecks/quality_control/cli/qa_postgres_migrate.rb +154 -0
  519. data/lib/hecks/quality_control/cli/qa_postgres_role.rb +159 -0
  520. data/lib/hecks/quality_control/cli/qa_pr_check.rb +232 -0
  521. data/lib/hecks/quality_control/cli/qa_seed_angles.rb +142 -0
  522. data/lib/hecks/quality_control/cli/qa_seed_targets.rb +69 -0
  523. data/lib/hecks/quality_control/cli/qa_sweep/all_mode.rb +280 -0
  524. data/lib/hecks/quality_control/cli/qa_sweep/checks.rb +329 -0
  525. data/lib/hecks/quality_control/cli/qa_sweep/dials.rb +92 -0
  526. data/lib/hecks/quality_control/cli/qa_sweep/finding_report.rb +117 -0
  527. data/lib/hecks/quality_control/cli/qa_sweep/parsing.rb +175 -0
  528. data/lib/hecks/quality_control/cli/qa_sweep/release_mode.rb +60 -0
  529. data/lib/hecks/quality_control/cli/qa_sweep.rb +611 -0
  530. data/lib/hecks/quality_control/cli/qa_tick.rb +274 -0
  531. data/lib/hecks/quality_control/quality_control.bluebook +2224 -0
  532. data/lib/hecks/quality_control/quality_control.hecksagon +13 -0
  533. data/lib/hecks/quality_control/quality_control.ports.hecksagon +54 -0
  534. data/lib/hecks/query_ir.rb +346 -0
  535. data/lib/hecks/query_ir_mcp.rb +198 -0
  536. data/lib/hecks/query_specification/common/comparators.rb +5 -26
  537. data/lib/hecks/query_specification/common/comparison.rb +35 -143
  538. data/lib/hecks/query_specification/common/dsl.rb +8 -24
  539. data/lib/hecks/query_specification/common/null_policy.rb +20 -70
  540. data/lib/hecks/query_specification/common/options.rb +2 -6
  541. data/lib/hecks/query_specification/common/where_clause.rb +2 -10
  542. data/lib/hecks/query_specification/field_path.rb +37 -77
  543. data/lib/hecks/query_specification/hop_path.rb +12 -76
  544. data/lib/hecks/release/gem_pin.rb +2 -26
  545. data/lib/hecks/release/runner/ci_publisher.rb +5 -8
  546. data/lib/hecks/release/runner/clean_tree.rb +42 -0
  547. data/lib/hecks/release/runner/commands.rb +2 -4
  548. data/lib/hecks/release/runner/console.rb +6 -0
  549. data/lib/hecks/release/runner/gem_publisher.rb +15 -9
  550. data/lib/hecks/release/runner/npm_publisher.rb +9 -53
  551. data/lib/hecks/release/runner/preflight.rb +29 -20
  552. data/lib/hecks/release/runner/published.rb +8 -26
  553. data/lib/hecks/release/runner/tagger.rb +31 -23
  554. data/lib/hecks/release/runner.rb +60 -38
  555. data/lib/hecks/rendering.rb +4 -26
  556. data/lib/hecks/router/namespace_installer.rb +15 -39
  557. data/lib/hecks/router.rb +4 -8
  558. data/lib/hecks/runtime/adapter_lookup.rb +124 -0
  559. data/lib/hecks/runtime/aggregate_lock.rb +8 -33
  560. data/lib/hecks/runtime/boot_gates.rb +3 -18
  561. data/lib/hecks/runtime/caller.rb +19 -59
  562. data/lib/hecks/runtime/capability_graph.rb +5 -21
  563. data/lib/hecks/runtime/command_interpreter/argument_gate.rb +16 -78
  564. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +27 -160
  565. data/lib/hecks/runtime/command_interpreter.rb +124 -306
  566. data/lib/hecks/runtime/command_rules/admissibility.rb +95 -366
  567. data/lib/hecks/runtime/command_rules/arithmetic.rb +66 -196
  568. data/lib/hecks/runtime/command_rules/authorization.rb +13 -45
  569. data/lib/hecks/runtime/command_rules/emission.rb +8 -21
  570. data/lib/hecks/runtime/command_rules/references.rb +23 -202
  571. data/lib/hecks/runtime/dependency_planning.rb +50 -104
  572. data/lib/hecks/runtime/dispatcher.rb +134 -243
  573. data/lib/hecks/runtime/entity_element.rb +40 -462
  574. data/lib/hecks/runtime/entity_interpreter.rb +64 -219
  575. data/lib/hecks/runtime/errors.rb +32 -115
  576. data/lib/hecks/runtime/event.rb +3 -25
  577. data/lib/hecks/runtime/identity.rb +18 -154
  578. data/lib/hecks/runtime/instance.rb +18 -150
  579. data/lib/hecks/runtime/interpreting.rb +14 -70
  580. data/lib/hecks/runtime/invocation.rb +28 -164
  581. data/lib/hecks/runtime/loader.rb +109 -194
  582. data/lib/hecks/runtime/outbox.rb +39 -262
  583. data/lib/hecks/runtime/policy_interpreter.rb +43 -202
  584. data/lib/hecks/runtime/port_operation_interpreter.rb +28 -97
  585. data/lib/hecks/runtime/query_interpreter.rb +122 -187
  586. data/lib/hecks/runtime/reaction_invocation.rb +36 -138
  587. data/lib/hecks/runtime/reaction_outcome.rb +89 -0
  588. data/lib/hecks/runtime/read_model_interpreter.rb +117 -208
  589. data/lib/hecks/runtime/rebuild_sweep.rb +8 -54
  590. data/lib/hecks/runtime/reference_hop.rb +8 -81
  591. data/lib/hecks/runtime/refusal_wording.rb +28 -87
  592. data/lib/hecks/runtime/registry/saga_persistence.rb +10 -102
  593. data/lib/hecks/runtime/registry/verification.rb +213 -227
  594. data/lib/hecks/runtime/registry/world_defaults.rb +4 -53
  595. data/lib/hecks/runtime/registry.rb +156 -247
  596. data/lib/hecks/runtime/remote_dispatcher.rb +68 -154
  597. data/lib/hecks/runtime/routing.rb +4 -15
  598. data/lib/hecks/runtime/saga_interpreter/correlation.rb +14 -61
  599. data/lib/hecks/runtime/saga_interpreter.rb +79 -263
  600. data/lib/hecks/runtime/saga_pending_dispatch.rb +2 -43
  601. data/lib/hecks/runtime/tenant_check.rb +6 -68
  602. data/lib/hecks/runtime/tenant_scope.rb +3 -28
  603. data/lib/hecks/runtime/value/admission.rb +16 -67
  604. data/lib/hecks/runtime/value/coercion.rb +162 -760
  605. data/lib/hecks/runtime/value/entity_list_coercion.rb +26 -219
  606. data/lib/hecks/runtime/value/field_checks.rb +172 -0
  607. data/lib/hecks/runtime/value.rb +15 -84
  608. data/lib/hecks/runtime.rb +35 -69
  609. data/lib/hecks/rust_build/conformance.rb +158 -0
  610. data/lib/hecks/rust_build/conformance_fuzz.rb +71 -0
  611. data/lib/hecks/rust_build/coverage.rb +218 -0
  612. data/lib/hecks/rust_build/native_build.rb +124 -0
  613. data/lib/hecks/rust_build/project_rust/root_mod.rb +120 -0
  614. data/lib/hecks/rust_build/project_rust.rb +332 -0
  615. data/lib/hecks/rust_build/wasm.rb +105 -0
  616. data/lib/hecks/rust_build/wasm_browser.rb +113 -0
  617. data/lib/hecks/rust_build.rb +144 -0
  618. data/lib/hecks/storehouse.rb +155 -582
  619. data/lib/hecks/tenancy/bluebook/tenancy.bluebook +10 -34
  620. data/lib/hecks/tenancy/bluebook/tenancy.hecksagon +6 -23
  621. data/lib/hecks/three_zero/forms.yml +127 -0
  622. data/lib/hecks/three_zero.rb +12 -0
  623. data/lib/hecks/tools/argument_gate_matrix.rb +316 -0
  624. data/lib/hecks/tools/comment_style.rb +1070 -0
  625. data/lib/hecks/tools/corpus_report.rb +87 -0
  626. data/lib/hecks/tools/deploy_recipe.rb +255 -0
  627. data/lib/hecks/tools/deploy_recipe_lint.rb +282 -0
  628. data/lib/hecks/tools/drop_implicit_append_fields.rb +95 -0
  629. data/lib/hecks/tools/era_projection_backfill.rb +94 -0
  630. data/lib/hecks/tools/era_reattest.rb +146 -0
  631. data/lib/hecks/tools/evolve_run.rb +189 -0
  632. data/lib/hecks/tools/fuzz_sweep.rb +373 -0
  633. data/lib/hecks/tools/heki_compaction.rb +100 -0
  634. data/lib/hecks/tools/hoist_local_givens.rb +246 -0
  635. data/lib/hecks/tools/journal_compaction.rb +89 -0
  636. data/lib/hecks/tools/oidc_manifests.rb +70 -0
  637. data/lib/hecks/tools/query_ir_run.rb +81 -0
  638. data/lib/hecks/tools/regeneration_run.rb +166 -0
  639. data/lib/hecks/tools/rust_comment_style.rb +642 -0
  640. data/lib/hecks/tools/sequence_script.rb +62 -0
  641. data/lib/hecks/tools/tail_merge.rb +117 -0
  642. data/lib/hecks/tools/tenant_provisioning.rb +142 -0
  643. data/lib/hecks/tools/translation_audit.rb +208 -0
  644. data/lib/hecks/tools/translation_scaffold.rb +131 -0
  645. data/lib/hecks/tools.rb +86 -0
  646. data/lib/hecks/vendoring/git_environment.rb +2 -8
  647. data/lib/hecks/vendoring/git_source.rb +4 -10
  648. data/lib/hecks/vendoring.rb +7 -46
  649. data/lib/hecks/version.rb +3 -14
  650. data/lib/hecks.rb +52 -90
  651. data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +8 -46
  652. data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +11 -80
  653. data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +10 -99
  654. data/qa/settings.yml +66 -0
  655. data/rust/.cargo/config.toml +6 -0
  656. data/rust/.gitignore +2 -0
  657. data/rust/Cargo.lock +54 -0
  658. data/rust/Cargo.toml +61 -0
  659. data/rust/build/.cargo/config.toml +3 -0
  660. data/rust/build/.gitignore +1 -0
  661. data/rust/build/Cargo.lock +7 -0
  662. data/rust/build/Cargo.toml +19 -0
  663. data/rust/build/src/build_artifact.rs +47 -0
  664. data/rust/build/src/cargo_sync.rs +248 -0
  665. data/rust/build/src/json.rs +421 -0
  666. data/rust/build/src/lineage_pass.rs +285 -0
  667. data/rust/build/src/main.rs +51 -0
  668. data/rust/build/src/optional_pass.rs +150 -0
  669. data/rust/build/src/pipeline.rs +264 -0
  670. data/rust/build/src/reserved_names.rs +76 -0
  671. data/rust/build/src/resolve.rs +124 -0
  672. data/rust/build/src/root.rs +25 -0
  673. data/rust/build/src/sidecars.rs +73 -0
  674. data/rust/build/src/subprocess.rs +51 -0
  675. data/rust/build/src/tmp.rs +31 -0
  676. data/rust/codegen/.cargo/config.toml +3 -0
  677. data/rust/codegen/.gitignore +1 -0
  678. data/rust/codegen/Cargo.lock +7 -0
  679. data/rust/codegen/Cargo.toml +20 -0
  680. data/rust/codegen/src/attr.rs +32 -0
  681. data/rust/codegen/src/bridging.rs +481 -0
  682. data/rust/codegen/src/commands.rs +1226 -0
  683. data/rust/codegen/src/constraints.rs +109 -0
  684. data/rust/codegen/src/dependency_planning.rs +209 -0
  685. data/rust/codegen/src/domain_generator.rs +1288 -0
  686. data/rust/codegen/src/exemplar.rs +230 -0
  687. data/rust/codegen/src/expr_emitter.rs +87 -0
  688. data/rust/codegen/src/fielded.rs +192 -0
  689. data/rust/codegen/src/hecks_naming.rs +33 -0
  690. data/rust/codegen/src/json.rs +335 -0
  691. data/rust/codegen/src/json_codec.rs +697 -0
  692. data/rust/codegen/src/literal.rs +207 -0
  693. data/rust/codegen/src/main.rs +290 -0
  694. data/rust/codegen/src/manifest.rs +227 -0
  695. data/rust/codegen/src/mutations.rs +784 -0
  696. data/rust/codegen/src/naming.rs +286 -0
  697. data/rust/codegen/src/ports.rs +208 -0
  698. data/rust/codegen/src/prelude.rs +116 -0
  699. data/rust/codegen/src/queries.rs +786 -0
  700. data/rust/codegen/src/reactions.rs +532 -0
  701. data/rust/codegen/src/read_models.rs +697 -0
  702. data/rust/codegen/src/reference_specs.rs +40 -0
  703. data/rust/codegen/src/registry.rs +966 -0
  704. data/rust/codegen/src/reserved_names.rs +76 -0
  705. data/rust/codegen/src/shared.rs +93 -0
  706. data/rust/codegen/src/skip_reason.rs +25 -0
  707. data/rust/codegen/src/types.rs +362 -0
  708. data/rust/host/.cargo/config.toml +3 -0
  709. data/rust/host/.gitignore +1 -0
  710. data/rust/host/Cargo.lock +4297 -0
  711. data/rust/host/Cargo.toml +61 -0
  712. data/rust/host/HECKS_RELEASE +1 -0
  713. data/rust/host/rds-ca-bundle.pem +2736 -0
  714. data/rust/host/src/api.rs +1596 -0
  715. data/rust/host/src/approval.rs +652 -0
  716. data/rust/host/src/auth.rs +1287 -0
  717. data/rust/host/src/bin/expr_harness.rs +46 -0
  718. data/rust/host/src/bin/lineage_harness.rs +119 -0
  719. data/rust/host/src/bin/mint_harness.rs +135 -0
  720. data/rust/host/src/checkout.rs +265 -0
  721. data/rust/host/src/dispatch.rs +1443 -0
  722. data/rust/host/src/expr_json.rs +1117 -0
  723. data/rust/host/src/field_hints.rs +52 -0
  724. data/rust/host/src/ir.rs +733 -0
  725. data/rust/host/src/journal.rs +874 -0
  726. data/rust/host/src/lambda_client.rs +378 -0
  727. data/rust/host/src/log.rs +147 -0
  728. data/rust/host/src/main.rs +474 -0
  729. data/rust/host/src/mint.rs +1865 -0
  730. data/rust/host/src/payments/keystore.rs +330 -0
  731. data/rust/host/src/payments/tests.rs +1400 -0
  732. data/rust/host/src/payments.rs +767 -0
  733. data/rust/host/src/presentation.rs +698 -0
  734. data/rust/host/src/presentation_write.rs +1431 -0
  735. data/rust/host/src/query_step.rs +149 -0
  736. data/rust/host/src/rate_limit.rs +904 -0
  737. data/rust/host/src/reference_transform.rs +241 -0
  738. data/rust/host/src/reference_validate.rs +338 -0
  739. data/rust/host/src/resend.rs +296 -0
  740. data/rust/host/src/secrets.rs +106 -0
  741. data/rust/host/src/server.rs +663 -0
  742. data/rust/host/src/storage_shape.rs +175 -0
  743. data/rust/host/src/test_pg.rs +40 -0
  744. data/rust/host/src/ui_schema.rs +1351 -0
  745. data/rust/host/src/wasm_runner.rs +191 -0
  746. data/rust/host/src/web/newsletter/cooldown.rs +126 -0
  747. data/rust/host/src/web/newsletter/tests.rs +104 -0
  748. data/rust/host/src/web/newsletter.rs +310 -0
  749. data/rust/host/src/web/newsletter_send.rs +357 -0
  750. data/rust/host/src/web/registrations.rs +1505 -0
  751. data/rust/host/src/web.rs +2937 -0
  752. data/rust/lsp/.gitignore +1 -0
  753. data/rust/lsp/Cargo.lock +7 -0
  754. data/rust/lsp/Cargo.toml +16 -0
  755. data/rust/lsp/README.md +133 -0
  756. data/rust/lsp/src/diagnostics.rs +165 -0
  757. data/rust/lsp/src/json.rs +385 -0
  758. data/rust/lsp/src/main.rs +399 -0
  759. data/rust/lsp/src/outline.rs +177 -0
  760. data/rust/lsp/src/rpc.rs +67 -0
  761. data/rust/parser/.cargo/config.toml +5 -0
  762. data/rust/parser/.gitignore +1 -0
  763. data/rust/parser/Cargo.lock +7 -0
  764. data/rust/parser/Cargo.toml +21 -0
  765. data/rust/parser/src/build/closed_sets.rs +27 -0
  766. data/rust/parser/src/build/identity.rs +276 -0
  767. data/rust/parser/src/build/mod.rs +12 -0
  768. data/rust/parser/src/build/naming.rs +141 -0
  769. data/rust/parser/src/build/pattern_subset.rs +161 -0
  770. data/rust/parser/src/build/query_derive.rs +72 -0
  771. data/rust/parser/src/build/query_inference.rs +269 -0
  772. data/rust/parser/src/build/query_options.rs +100 -0
  773. data/rust/parser/src/build/read_model.rs +94 -0
  774. data/rust/parser/src/build/references.rs +32 -0
  775. data/rust/parser/src/canonical.rs +114 -0
  776. data/rust/parser/src/diag.rs +55 -0
  777. data/rust/parser/src/emit.rs +953 -0
  778. data/rust/parser/src/expr/ast_json.rs +147 -0
  779. data/rust/parser/src/expr/evaluator.rs +81 -0
  780. data/rust/parser/src/expr/mod.rs +84 -0
  781. data/rust/parser/src/expr/resolver.rs +497 -0
  782. data/rust/parser/src/ir.rs +387 -0
  783. data/rust/parser/src/keywords.rs +585 -0
  784. data/rust/parser/src/lex.rs +662 -0
  785. data/rust/parser/src/main.rs +252 -0
  786. data/rust/parser/src/parse/aggregate.rs +612 -0
  787. data/rust/parser/src/parse/chapter.rs +517 -0
  788. data/rust/parser/src/parse/command.rs +637 -0
  789. data/rust/parser/src/parse/domain_port.rs +127 -0
  790. data/rust/parser/src/parse/entity.rs +527 -0
  791. data/rust/parser/src/parse/file.rs +67 -0
  792. data/rust/parser/src/parse/hecksagon.rs +231 -0
  793. data/rust/parser/src/parse/lifecycle.rs +162 -0
  794. data/rust/parser/src/parse/mod.rs +1262 -0
  795. data/rust/parser/src/parse/policy.rs +87 -0
  796. data/rust/parser/src/parse/process_manager.rs +305 -0
  797. data/rust/parser/src/parse/query.rs +100 -0
  798. data/rust/parser/src/parse/read_model.rs +214 -0
  799. data/rust/parser/src/parse/value_object.rs +250 -0
  800. data/rust/parser/src/ruby_value.rs +422 -0
  801. data/rust/project/bridging.rb +257 -0
  802. data/rust/project/commands.rb +877 -0
  803. data/rust/project/constraints.rb +86 -0
  804. data/rust/project/dependency_planning.rb +178 -0
  805. data/rust/project/domain_generator.rb +980 -0
  806. data/rust/project/exemplar.rb +148 -0
  807. data/rust/project/expr_emitter.rb +72 -0
  808. data/rust/project/fielded.rb +141 -0
  809. data/rust/project/json_codec.rb +641 -0
  810. data/rust/project/mutations.rb +721 -0
  811. data/rust/project/naming.rb +205 -0
  812. data/rust/project/ports.rb +65 -0
  813. data/rust/project/queries.rb +493 -0
  814. data/rust/project/reactions.rb +317 -0
  815. data/rust/project/read_models.rb +690 -0
  816. data/rust/project/reference_specs.rb +27 -0
  817. data/rust/project/registry.rb +396 -0
  818. data/rust/project/skip_reason.rb +29 -0
  819. data/rust/project/types.rb +225 -0
  820. data/rust/project/write_if_changed.rb +83 -0
  821. data/rust/project.rb +30 -0
  822. data/rust/project_rust_pipeline.rb +383 -0
  823. data/rust/src/exemplar/commands.rs +279 -0
  824. data/rust/src/exemplar/constraints.rs +18 -0
  825. data/rust/src/exemplar/fielded.rs +280 -0
  826. data/rust/src/exemplar/json.rs +277 -0
  827. data/rust/src/exemplar/mod.rs +17 -0
  828. data/rust/src/exemplar/mutations.rs +80 -0
  829. data/rust/src/exemplar/queries.rs +33 -0
  830. data/rust/src/exemplar/reactions.rs +88 -0
  831. data/rust/src/exemplar/read_models.rs +48 -0
  832. data/rust/src/exemplar/registry.rs +166 -0
  833. data/rust/src/exemplar/types.rs +44 -0
  834. data/rust/src/kernel/attribute_shapes/composite.rs +88 -0
  835. data/rust/src/kernel/attribute_shapes/list.rs +18 -0
  836. data/rust/src/kernel/attribute_shapes/mod.rs +44 -0
  837. data/rust/src/kernel/attribute_shapes/optional.rs +9 -0
  838. data/rust/src/kernel/attribute_shapes/scalar.rs +39 -0
  839. data/rust/src/kernel/cli.rs +585 -0
  840. data/rust/src/kernel/dispatch.rs +1090 -0
  841. data/rust/src/kernel/expr.rs +458 -0
  842. data/rust/src/kernel/expression_operators/arithmetic.rs +128 -0
  843. data/rust/src/kernel/expression_operators/comparison.rs +48 -0
  844. data/rust/src/kernel/expression_operators/enumeration.rs +232 -0
  845. data/rust/src/kernel/expression_operators/logical.rs +13 -0
  846. data/rust/src/kernel/expression_operators/membership.rs +18 -0
  847. data/rust/src/kernel/expression_operators/mod.rs +68 -0
  848. data/rust/src/kernel/expression_operators/pattern_match.rs +73 -0
  849. data/rust/src/kernel/expression_operators/positional.rs +126 -0
  850. data/rust/src/kernel/expression_operators/presence.rs +101 -0
  851. data/rust/src/kernel/expression_operators/sign_test.rs +16 -0
  852. data/rust/src/kernel/expression_operators/sized.rs +35 -0
  853. data/rust/src/kernel/expression_operators/text.rs +79 -0
  854. data/rust/src/kernel/expression_operators/to_string.rs +18 -0
  855. data/rust/src/kernel/json.rs +779 -0
  856. data/rust/src/kernel/mod.rs +133 -0
  857. data/rust/src/kernel/named_query.rs +219 -0
  858. data/rust/src/kernel/orchestrate.rs +1810 -0
  859. data/rust/src/kernel/pattern.rs +307 -0
  860. data/rust/src/kernel/query_comparators.rs +206 -0
  861. data/rust/src/kernel/query_ordering.rs +103 -0
  862. data/rust/src/kernel/read_model.rs +914 -0
  863. data/rust/src/kernel/reference_lookup.rs +149 -0
  864. data/rust/src/kernel/repository.rs +468 -0
  865. data/rust/src/kernel/routing.rs +612 -0
  866. data/rust/src/kernel/vocab/aggregate_dispatch_order.rs +118 -0
  867. data/rust/src/kernel/vocab/entity_dispatch_order.rs +114 -0
  868. data/rust/src/kernel/vocab/field_hint.rs +70 -0
  869. data/rust/src/kernel/vocab/mod.rs +20 -0
  870. data/rust/src/kernel/vocab/query_comparator.rs +65 -0
  871. data/rust/src/kernel/vocab/refusal_template.rs +1592 -0
  872. data/rust/src/lib.rs +8 -0
  873. data/rust/src/main.rs +16 -0
  874. data/rust/web/.gitignore +1 -0
  875. data/rust/web/Cargo.lock +119 -0
  876. data/rust/web/Cargo.toml +18 -0
  877. data/rust/web/src/lib.rs +8 -0
  878. metadata +478 -12
  879. data/lib/hecks/facade/cli_door.rb +0 -178
  880. data/lib/hecks/facade/cli_runner.rb +0 -271
  881. data/lib/hecks/facade/handle.rb +0 -293
  882. data/lib/hecks/facade/json_door.rb +0 -247
  883. data/lib/hecks/facade/surface/aggregate_door.rb +0 -222
  884. data/lib/hecks/facade/surface/chapter.rb +0 -116
  885. data/lib/hecks/facade/surface.rb +0 -61
  886. data/lib/hecks/mcp_door_scope.rb +0 -176
@@ -1,44 +1,20 @@
1
1
  module Hecks
2
2
  module QuerySpecification
3
- # One reading of a dotted query-field path, shared by every place that
4
- # would otherwise invent its own. Left to themselves they disagree: a
5
- # reference interpreter doing a bare `record[field]` lookup silently
6
- # matches nothing for a dotted path, an SQL side that splits dots but
7
- # judges numericness from the first nested segment only quietly
8
- # compares a two-level path as text, and a build seal walks the
9
- # declaration graph a third way. Three implementations of "what does
10
- # pizza.price_cents.cents mean" is two more than a language gets to
11
- # have.
3
+ # One reading of a dotted query-field path, shared by every caller that walks one.
12
4
  #
13
- # Two sides, deliberately in one file so they cannot drift:
14
- #
15
- # dig(holder, field) — value side: walk a record's held state,
16
- # segment by segment, through Value
17
- # objects and plain hashes alike.
18
- # leaf_attribute / numeric? — declaration side: walk the declared
19
- # shape to the attribute a path lands on.
20
- # Callers supply value-object lookup as a
21
- # block, because an Aggregate and a
22
- # mid-build AggregateBuilder hold their
23
- # shapes differently but walk the same.
5
+ # `dig` walks a record's held state; `leaf_attribute`/`numeric?` walk the declared shape.
24
6
  module FieldPath
25
7
  module_function
26
8
 
27
9
  NUMERIC_PRIMITIVES = %w[Integer Float].freeze
10
+ INTEGER_PRIMITIVES = %w[Integer].freeze
11
+ BOOLEAN_PRIMITIVES = %w[TrueClass FalseClass].freeze
28
12
  SCALAR_PRIMITIVES = %w[String Integer Float TrueClass FalseClass].freeze
29
13
 
30
14
  # Reads the value a dotted field path names out of a record's held state.
31
15
  #
32
- # The held value a dotted field names, or nil — never a raise. The
33
- # first segment reads off the record (an Instance, a Value, or a
34
- # plain row hash); the rest read through whatever each step holds. A
35
- # stored nested value object is a plain hash by the time it is read
36
- # back, keyed by symbol in memory and by string off a wire decode,
37
- # so both spellings are tried — `key?` first, never `||`, because
38
- # `||` falls through a genuinely-stored `false` to the other
39
- # spelling (usually absent) and returns `nil` instead. The seal
40
- # admits boolean leaves (`SCALAR_PRIMITIVES` below), so a `false`
41
- # here is a real, held answer, not a missing one.
16
+ # Nested value objects come back as hashes keyed by symbol (memory) or string (wire),
17
+ # so both are tried, `key?` first: `||` would turn a stored `false` into `nil`.
42
18
  #
43
19
  # @param holder [Runtime::Instance, Runtime::Value, Hash, nil] the record, value
44
20
  # object or row Hash the first segment is read from
@@ -52,8 +28,7 @@ module Hecks
52
28
  field.to_s.split(".").reduce(holder) { |current, segment| read(current, segment) }
53
29
  end
54
30
 
55
- # Reads one path segment off whatever the previous step held — a single
56
- # step of `dig`.
31
+ # Reads one path segment off whatever the previous step held.
57
32
  #
58
33
  # @param current [Runtime::Instance, Runtime::Value, Hash, Array, nil] the value the
59
34
  # walk has reached; a Hash is tried by Symbol key, then by String key
@@ -68,14 +43,8 @@ module Hecks
68
43
  return current.key?(sym) ? current[sym] : current[segment]
69
44
  end
70
45
 
71
- # M5 — "or nil, never raise" is this method's whole contract, and
72
- # an Array broke it: `Array#[]` demands an Integer index, so
73
- # `current[segment]` (a String) raised `TypeError` straight
74
- # through `dig` instead of answering nil. A dotted path stepping
75
- # into a list_of attribute (`where "tags.name" == "x"` against a
76
- # bare list, rather than each element) has no single member a
77
- # bare index would name anyway — nil is the honest answer, the
78
- # same one a dangling reference or a missing key already gets.
46
+ # A list has no single member a String index could name; `Array#[]` would raise
47
+ # TypeError, breaking dig's "nil, never raise" contract.
79
48
  return nil if current.is_a?(Array)
80
49
 
81
50
  current[segment]
@@ -83,21 +52,16 @@ module Hecks
83
52
 
84
53
  # Walks the declared shape to the attribute a dotted path lands on.
85
54
  #
86
- # The declared attribute a path lands on, or nil. `segments` is the
87
- # dotted tail — for a bare field it is empty and the root attribute
88
- # is its own leaf. The walk stops dead at a reference (an id is a
89
- # scalar; nothing nests under it) and at any member the declared
90
- # value object does not carry.
55
+ # `segments` is the dotted tail, empty for a bare field. The walk stops at a reference
56
+ # and at any member the declared value object does not carry.
91
57
  #
92
- # @param attribute [Bluebook::Attribute, nil] the root attribute the path's first
93
- # segment names; `nil` (no such attribute) answers `nil`
58
+ # @param attribute [Bluebook::Attribute, nil] the root attribute; `nil` answers `nil`
94
59
  # @param segments [Array<String>] the path's remaining segments, `[]` for a bare field
95
60
  # @yield looks a value object up by name in the caller's own declarations
96
- # @yieldparam type [String] the type name of the attribute being stepped into
97
- # @yieldreturn [Class<Bluebook::ValueObject>, nil] the declared shape, or `nil` when
98
- # the type is not a value object the caller knows
99
- # @return [Bluebook::Attribute, nil] the attribute at the end of the path; `nil` when
100
- # a step crosses a reference, an undeclared type or a member that does not exist
61
+ # @yieldparam type [String] the type name being stepped into
62
+ # @yieldreturn [Class<Bluebook::ValueObject>, nil] the declared shape, or `nil`
63
+ # @return [Bluebook::Attribute, nil] the leaf; `nil` when a step crosses a reference or
64
+ # lands on an undeclared type or missing member
101
65
  def leaf_attribute(attribute, segments)
102
66
  current = attribute
103
67
  segments.each do |segment|
@@ -109,43 +73,39 @@ module Hecks
109
73
  current
110
74
  end
111
75
 
112
- # Decides from the declared shape whether a field path holds a number.
76
+ # Whether a field path lands on one of `primitives`: itself, or (bare field only) a
77
+ # value object with a member typed as one.
113
78
  #
114
- # May an ordered comparator (lt/lte/gt/gte) land here, and may an
115
- # `ORDER BY` cast here numerically? A bare field keeps the one-level
116
- # convention every adapter already implements: a numeric primitive,
117
- # or a value object carrying at least one numeric member. A dotted
118
- # path must land on a numeric primitive itself — the convention does
119
- # not reach through a named path, it is the absence of one.
120
- #
121
- # @param attribute [Bluebook::Attribute, nil] the root attribute the path starts at;
122
- # `nil` answers `false`
79
+ # @param attribute [Bluebook::Attribute, nil] the root attribute; `nil` answers `false`
123
80
  # @param segments [Array<String>] the path's remaining segments, `[]` for a bare field
81
+ # @param primitives [Array<String>] the primitive type names that count as a match
124
82
  # @yield looks a value object up by name, as for `leaf_attribute`
125
- # @yieldparam type [String] the type name to look up
126
- # @yieldreturn [Class<Bluebook::ValueObject>, nil] the declared shape, or `nil`
127
- # @return [Boolean] `true` when the leaf is an `Integer` or `Float`, or a bare field
128
- # naming a value object with at least one such member; `false` for a list, a
129
- # reference, or a path that lands nowhere
130
- def numeric?(attribute, segments, &)
83
+ # @return [Boolean] `false` for a list, a reference, or a path that lands nowhere
84
+ def matches_primitive?(attribute, segments, primitives, &)
131
85
  leaf = leaf_attribute(attribute, segments, &)
132
86
  return false if leaf.nil? || leaf.list? || leaf.reference?
133
- return true if NUMERIC_PRIMITIVES.include?(leaf.type.to_s)
87
+ return true if primitives.include?(leaf.type.to_s)
134
88
  return false unless segments.empty?
135
89
 
136
90
  shape = yield(leaf.type.to_s)
137
- !shape.nil? && shape.attributes.any? { |member| NUMERIC_PRIMITIVES.include?(member.type.to_s) }
91
+ !shape.nil? && shape.attributes.any? { |member| primitives.include?(member.type.to_s) }
138
92
  end
139
93
 
140
- # Decides whether a path ends on a scalar primitive that every engine
141
- # compares the same way.
94
+ # @return [Boolean] whether a field path holds a number (`Integer` or `Float`)
95
+ def numeric?(attribute, segments, &) = matches_primitive?(attribute, segments, NUMERIC_PRIMITIVES, &)
96
+
97
+ # @return [Boolean] whether a field path holds specifically an `Integer` (not `Float`)
98
+ def integer?(attribute, segments, &) = matches_primitive?(attribute, segments, INTEGER_PRIMITIVES, &)
99
+
100
+ # @return [Boolean] whether a field path holds a `TrueClass`/`FalseClass`
101
+ def boolean?(attribute, segments, &) = matches_primitive?(attribute, segments, BOOLEAN_PRIMITIVES, &)
102
+
103
+ # Decides whether a path ends on a scalar primitive every engine compares alike.
142
104
  #
143
- # A dotted path must end on a scalar member — landing on a value
144
- # object would hand SQL a JSON object where the reference
145
- # interpreter unwraps a hash, and the two would answer differently.
105
+ # A dotted path landing on a value object would give SQL a JSON object where the
106
+ # reference interpreter unwraps a hash, so the two would disagree.
146
107
  #
147
- # @param attribute [Bluebook::Attribute, nil] the root attribute the path starts at;
148
- # `nil` answers `false`
108
+ # @param attribute [Bluebook::Attribute, nil] the root attribute; `nil` answers `false`
149
109
  # @param segments [Array<String>] the path's remaining segments, `[]` for a bare field
150
110
  # @yield looks a value object up by name, as for `leaf_attribute`
151
111
  # @yieldparam type [String] the type name to look up
@@ -2,61 +2,26 @@ require_relative "../naming"
2
2
 
3
3
  module Hecks
4
4
  module QuerySpecification
5
- # One reading of a dotted query-field path that hops through a
6
- # reference into another aggregate's own shape — FieldPath's
7
- # sibling, not its member. FieldPath walks a shape, which cannot
8
- # loop, and answers nil, never raising, because there is nothing
9
- # left to say beyond "not found." HopPath walks the reference
10
- # graph instead — `BluebookBuilder#validate_no_bidirectional_references!`
11
- # refuses any reference cycle at declaration time (ADR 0025,
12
- # "References" — widened from a direct pair to any ring, DFS over
13
- # the chapter's own reference graph), so what's left to guard here
14
- # is depth, not cycles: MAX_HOPS below, and this module's own
15
- # `refusal` states for a target the chapter doesn't resolve. A walk
16
- # here still needs to say why it stopped, not just that it did.
5
+ # One reading of a dotted query-field path that hops through a reference with `/`.
17
6
  #
18
- # Every method below takes an attribute array, never a "shape"
19
- # object — deliberately, because the two real callers hold their
20
- # attributes differently. `AggregateBuilder` (tier-1 seal, mid-
21
- # build) exposes `attributes` as a plain reader, but its own
22
- # `attribute(name, type = String, ...)` is the DSL's attribute-
23
- # declaring method — calling it as a finder would silently mint a
24
- # new String attribute instead of looking one up. A sealed
25
- # `Aggregate` (tier-2 seal, and every runtime target) has a
26
- # real `attribute(name)` finder, but taking the array either way
27
- # sidesteps the mismatch instead of asking every caller to know
28
- # which kind of object it holds.
7
+ # Takes attribute arrays, not shapes: AggregateBuilder's `attribute(name)` declares rather
8
+ # than finds, so the two real callers cannot share a finder.
29
9
  module HopPath
30
10
  module_function
31
11
 
32
12
  Hop = Struct.new(:attribute, :target_name, :target, keyword_init: true)
33
13
 
34
- # refusal: nil (clean), :unresolvable (a hop's target cannot be
35
- # found — cross-domain, or simply not declared in this chapter),
36
- # :too_deep (see MAX_HOPS below).
14
+ # `refusal` is nil when clean, `:unresolvable` when a hop's target is not found,
15
+ # `:too_deep` when the chain exceeds MAX_HOPS.
37
16
  Plan = Struct.new(:hops, :tail, :refusal, keyword_init: true)
38
17
 
39
- # A hop chain long enough to matter is long enough to be a
40
- # mistake — not a guard against a walk that cannot terminate.
41
- # Nothing here loops forever regardless of how the reference
42
- # graph is shaped: a hop chain is a literal dotted string, fixed
43
- # at declaration time, and every step consumes exactly one of
44
- # its own segments — the walk is bounded by what was typed, not
45
- # by the graph. A self-referential aggregate hopping through
46
- # itself more than once (`"parent.parent.name"`, a grandparent
47
- # query) is real, common, and perfectly safe; this exists only
48
- # to refuse a chain nobody meant to write this long.
18
+ # Bounds hop chains: a longer one is a mistake, not a runaway walk, since each
19
+ # step consumes one segment of the typed path.
49
20
  MAX_HOPS = 8
50
21
 
51
22
  # Names the path segment a reference attribute answers to.
52
23
  #
53
- # The segment name a Reference answers to in a hop path — its own
54
- # declared attribute name, unchanged (ADR 0025, "References":
55
- # `reference_to` mints that bare name, no `_id`, so there is
56
- # no derivation left to apply). `proposal/client` (a query hop)
57
- # and `proposal.client` (the Ruby accessor,
58
- # `Facade::Handle#define_reference_accessors`) name the same
59
- # concept the same way.
24
+ # The attribute's own declared name, unchanged (ADR 0025).
60
25
  #
61
26
  # @param attribute [Bluebook::Attribute] a reference-typed attribute
62
27
  # @return [String] the attribute's declared name
@@ -65,17 +30,8 @@ module Hecks
65
30
  # Decides whether a field path starts by hopping through one of the given
66
31
  # references, without resolving the reference's target.
67
32
  #
68
- # Does this path's head cross into another record via `/`? The
69
- # operator is the answer now, not a name collision to arbitrate —
70
- # `.` walks fields inside this record, `/` crosses into another
71
- # one, so a path with no `/` is never a hop, full stop, and the
72
- # old "a real local attribute wins first" rule (needed only
73
- # because `.` was overloaded for both meanings, and `client_id`
74
- # vs `client` was how the two were told apart) has nothing left
75
- # to arbitrate. Answerable from `attributes` alone — a Reference
76
- # knows its own `target_name` at declaration, before it can
77
- # `resolve` it — which is what lets the aggregate seal recognise
78
- # a hop it cannot yet check.
33
+ # A path with no `/` is never a hop: `.` walks fields inside a record, `/` crosses
34
+ # into another one.
79
35
  #
80
36
  # @param field [String, Symbol] the query field path, such as `:"client/status"`
81
37
  # @param attributes [Array<Bluebook::Attribute>] the attributes of the shape the path
@@ -91,17 +47,6 @@ module Hecks
91
47
 
92
48
  # Resolves the first hop of a field path and hands back what is left to walk.
93
49
  #
94
- # **One step**: does `field`'s head hop through one of `attributes`'
95
- # own references? Answers the resolved `Hop` plus the string
96
- # still left to walk (itself possibly another `/`-hop, against
97
- # the target's own attributes, or a plain `.`-dotted field walk
98
- # once the hops run out) — or nil, when the head names nothing or
99
- # the path has no `/` at all. This is the one primitive
100
- # Runtime::ReferenceHop needs: it recurses hop by hop through its
101
- # own `apply`, one ordinary same-aggregate query at a time, and
102
- # never needs the whole chain resolved up front the way a seal
103
- # does.
104
- #
105
50
  # @param field [String, Symbol] the query field path, such as `"client/region/name"`
106
51
  # @param attributes [Array<Bluebook::Attribute>] the attributes of the shape the path
107
52
  # starts from
@@ -124,11 +69,6 @@ module Hecks
124
69
  # Resolves every hop of a field path in order, stopping with a reason at
125
70
  # the first one it cannot follow.
126
71
  #
127
- # The whole chain, resolved — every hop's target found, in
128
- # order — for the one caller that needs it all at once:
129
- # `BluebookBuilder#validate_query_hops!`, checking a hop chain
130
- # before anything ever dispatches it.
131
- #
132
72
  # @param field [String, Symbol] the query field path, such as `"client/region/name"`
133
73
  # @param attributes [Array<Bluebook::Attribute>] the attributes of the shape the path
134
74
  # starts from
@@ -149,12 +89,8 @@ module Hecks
149
89
  hop, rest = step
150
90
  return Plan.new(hops: hops, tail: nil, refusal: :too_deep) if hops.size >= MAX_HOPS
151
91
 
152
- # Pushed even unresolved — a caller reporting :unresolvable
153
- # needs this hop's own target_name (real, known at
154
- # declaration, regardless of whether resolve succeeded), not
155
- # whatever hop came before it. `.target` is nil on this one
156
- # entry; every caller checking `hops.last.target` already has
157
- # to handle that, the same way `next_hop`'s own caller does.
92
+ # Pushed even unresolved: a caller reporting :unresolvable needs this hop's
93
+ # target_name, and `.target` is nil on this one entry.
158
94
  hops << hop
159
95
  return Plan.new(hops: hops, tail: nil, refusal: :unresolvable) unless hop.target
160
96
 
@@ -2,32 +2,8 @@ require_relative "gem_pin/published_versions"
2
2
 
3
3
  module Hecks
4
4
  module Release
5
- # Finds the hecks version a project runs on, and refuses one that a
6
- # stranger could not install.
7
- #
8
- # ## Why it exists
9
- #
10
- # A project that is copied out of its own workspace (handed to someone who
11
- # will `bundle install` it, or built in an image with no sibling checkout)
12
- # has to name a hecks release RubyGems actually publishes. A `path:` or
13
- # `git:` source only works where the path or remote is reachable, and a
14
- # version that was never published resolves nowhere. This reads the
15
- # project's Gemfiles and lockfiles, without running Bundler, and says which
16
- # version each pins or refuses.
17
- #
18
- # ## Resolution
19
- #
20
- # For each `Gemfile` under the root (a project can hold several, such as a
21
- # domain and a helper app) the pin is, in order: the version its
22
- # `Gemfile.lock` resolved, or the newest stable release its version
23
- # constraint allows. Each pin must be published; the Gemfiles need not
24
- # agree.
25
- #
26
- # ## Injectable network
27
- #
28
- # The published list comes from `published:`, any object answering
29
- # `include?(version)` and `newest_satisfying(requirement)`. The default asks
30
- # RubyGems; a caller without network hands in its own.
5
+ # Reads a project's Gemfiles and lockfiles (no Bundler run) and says which
6
+ # hecks version each pins, refusing any version RubyGems does not publish.
31
7
  class GemPin
32
8
  GEM_LINE = /^\s*gem\s+["']hecks["'](?<rest>.*)$/
33
9
  SOURCE_OPTION = /\b(?:path|git|github|gitlab|bitbucket|branch|ref|tag):/
@@ -3,13 +3,10 @@ require_relative "commands"
3
3
  module Hecks
4
4
  module Release
5
5
  class Runner
6
- # The npm step when CI publishes: the release tag triggers
7
- # `.github/workflows/publish-client.yml`, which publishes `@hecks/client`
8
- # with npm trusted publishing, so nothing is published from this machine.
9
- # This watches npm until the version appears.
6
+ # Watches npm for `@hecks/client` after CI publishes it via
7
+ # `.github/workflows/publish-client.yml` (npm trusted publishing).
10
8
  #
11
- # The clock and the pause are injected, so a spec runs the whole wait
12
- # without sleeping.
9
+ # Its clock and pause are injected, so a spec runs the wait without sleeping.
13
10
  class CiPublisher
14
11
  WORKFLOW = ".github/workflows/publish-client.yml".freeze
15
12
  INTERVAL = 15
@@ -60,8 +57,8 @@ module Hecks
60
57
  def self.timeout_hint(version)
61
58
  "Timed out after #{LIMIT / 60} minutes waiting for CI to publish @hecks/client #{version}. " \
62
59
  "See the run: gh run list --workflow publish-client.yml. Re-run it: " \
63
- "gh workflow run publish-client.yml -f tag=v#{version}. Then finish with: bin/release --npm-only. " \
64
- "To publish from this machine instead: bin/release --npm-only --npm-local."
60
+ "gh workflow run publish-client.yml -f tag=v#{version}. Then finish with: hecks publish --npm-only --confirm. " \
61
+ "To publish from this machine instead: hecks publish --npm-only --npm-local --confirm."
65
62
  end
66
63
 
67
64
  private
@@ -0,0 +1,42 @@
1
+ require_relative "commands"
2
+
3
+ module Hecks
4
+ module Release
5
+ class Runner
6
+ # The check that what a release ships is exactly what is committed: nothing modified,
7
+ # untracked, or ignored under the paths the gem packages.
8
+ #
9
+ # `git status --porcelain` alone hides ignored files, and an ignored file under `lib/` or
10
+ # `rust/` is one a build of the gem could carry. Build output (`target/`) is ignored on
11
+ # purpose and never packaged, so it is not counted.
12
+ class CleanTree
13
+ # The repository paths the gem packages.
14
+ SHIPPED = %w[lib rust exe qa/settings.yml].freeze
15
+
16
+ # Ignored build output, which the gem leaves out.
17
+ BUILD_OUTPUT = %r{(\A|/)target/?\z}
18
+
19
+ # @param git [#read] runs a git command in the checkout and answers its output
20
+ def initialize(git:)
21
+ @git = git
22
+ end
23
+
24
+ # @return [Array<String>] each modified, untracked or ignored path under the packaged paths
25
+ def stray
26
+ lines = @git.read("status", "--porcelain", "--ignored", "--", *SHIPPED).lines.map(&:strip)
27
+ lines.reject(&:empty?).map { |line| line.sub(/\A\S+\s+/, "") }.grep_v(BUILD_OUTPUT)
28
+ end
29
+
30
+ # @return [void]
31
+ # @raise [Refusal] naming the first few stray paths
32
+ def check!
33
+ paths = stray
34
+ return if paths.empty?
35
+
36
+ raise Refusal, "#{paths.size} file(s) under #{SHIPPED.join(', ')} are modified, untracked or " \
37
+ "ignored (#{paths.first(5).join(', ')}); commit or delete them before releasing"
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -9,10 +9,8 @@ module Hecks
9
9
  # Raised when a check refuses the release; the message names the fix.
10
10
  class Refusal < StandardError; end
11
11
 
12
- # Runs the release's external commands: git, gem, npm, curl, op.
13
- #
14
- # The runner takes any object answering `capture` and `run!` the way this
15
- # one does, so a spec hands in a recorder and never starts a real process.
12
+ # Runs the release's external commands (git, gem, npm, curl, op) through
13
+ # any object answering `capture`/`run!`, so a spec injects a recorder.
16
14
  class Commands
17
15
  # What a captured command printed and whether it succeeded.
18
16
  #
@@ -15,6 +15,12 @@ module Hecks
15
15
  @assume_yes = assume_yes
16
16
  end
17
17
 
18
+ # @return [IO] where progress goes
19
+ attr_reader :out
20
+
21
+ # @return [IO] where refusals and failures go
22
+ attr_reader :err
23
+
18
24
  # Prints a progress line.
19
25
  #
20
26
  # @param text [String] the line
@@ -1,12 +1,14 @@
1
- require "fileutils"
2
1
  require_relative "commands"
2
+ require_relative "clean_tree"
3
+ require_relative "git"
4
+ require_relative "../../cli/release_gem"
5
+ require "hecks/hecks/adapters/codebase/gem_registry"
3
6
 
4
7
  module Hecks
5
8
  module Release
6
9
  class Runner
7
- # The gem step: hands the push to `bin/release_gem`, which owns building the
8
- # gem and pushing it with the key 1Password holds. A dry run builds the gem
9
- # to prove it builds and deletes it.
10
+ # The gem step: hands the push to `Hecks::CLI::ReleaseGem`, which builds and pushes
11
+ # it with the key 1Password holds; a dry run only builds it, then deletes it.
10
12
  class GemPublisher
11
13
  # @param root [String] the repository root
12
14
  # @param commands [#run!] runs the build and the push
@@ -15,6 +17,7 @@ module Hecks
15
17
  @root = root
16
18
  @commands = commands
17
19
  @console = console
20
+ @registry = Hecks::Adapters::Codebase::GemRegistry.new(root: root, commands: commands)
18
21
  end
19
22
 
20
23
  # Pushes the gem, or with `dry_run` only builds it.
@@ -23,20 +26,23 @@ module Hecks
23
26
  # @param dry_run [Boolean] build and delete the gem, pushing nothing
24
27
  # @return [void]
25
28
  # @raise [CommandFailed] if the build or the push fails
29
+ # @raise [Refusal] if a packaged path holds a modified, untracked or ignored file
26
30
  def publish!(version, dry_run:)
27
31
  return build_only(version) if dry_run
28
32
 
29
- @console.say("Publishing hecks #{version} to rubygems.org via bin/release_gem...")
30
- @commands.run!(File.join(@root, "bin/release_gem"), chdir: @root)
33
+ CleanTree.new(git: Git.new(root: @root, commands: @commands)).check!
34
+
35
+ @console.say("Publishing hecks #{version} to rubygems.org...")
36
+ status = Hecks::CLI::ReleaseGem.call(root: @root, commands: @commands, out: @console.out,
37
+ err: @console.err, version: version)
38
+ raise CommandFailed, "the gem push was refused" unless status.zero?
31
39
  end
32
40
 
33
41
  private
34
42
 
35
43
  def build_only(version)
36
44
  @console.say("Dry run: building hecks-#{version}.gem (nothing is pushed)...")
37
- @commands.run!("gem", "build", "hecks.gemspec", chdir: @root)
38
- ensure
39
- FileUtils.rm_f(File.join(@root, "hecks-#{version}.gem"))
45
+ @registry.build_only!(version)
40
46
  end
41
47
  end
42
48
  end
@@ -1,87 +1,43 @@
1
- require "tempfile"
2
1
  require_relative "commands"
2
+ require "hecks/hecks/adapters/codebase/npm_registry"
3
3
 
4
4
  module Hecks
5
5
  module Release
6
6
  class Runner
7
7
  # The npm step: publishes `@hecks/client` from `packages/hecks-client`
8
8
  # with the token 1Password holds.
9
- #
10
- # `op run` resolves `release/npm_publish.env` into the environment of the
11
- # one `npm publish` process. npm reads its token from a config file, so a
12
- # throwaway user config holds a placeholder that npm expands from that
13
- # environment; the file never contains the token and is deleted afterwards.
14
- # The package's `prepack` builds `dist/`.
15
- #
16
- # The token is a granular one that bypasses two-factor authentication, because
17
- # the account's second factor is a passkey. As a fallback the publish runs with
18
- # `--auth-type=web` and its output is not captured, so if npm does ask for an
19
- # approval it prints the link straight to the terminal and waits for it.
20
9
  class NpmPublisher
21
- PACKAGE_DIR = "packages/hecks-client".freeze
22
- ENV_FILE = "release/npm_publish.env".freeze
23
10
  APPROVAL_NOTICE = "npm will print an approval link; open it and approve with your security key or passkey. " \
24
11
  "This step waits for you.".freeze
25
- USERCONFIG_LINE = "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}".freeze
26
12
 
27
- # @param root [String] the repository root
28
- # @param commands [#run!] runs npm and op
29
- # @param console [Console] progress output
30
13
  def initialize(root:, commands:, console:)
31
14
  @root = root
32
- @commands = commands
33
15
  @console = console
16
+ @registry = Hecks::Adapters::Codebase::NpmRegistry.new(root: root, commands: commands)
34
17
  end
35
18
 
36
- # Publishes the package, or with `dry_run` only packs it.
37
- #
38
- # @param version [String] the version being released
39
- # @param dry_run [Boolean] run `npm publish --dry-run`, which needs no credentials
40
- # @return [void]
41
- # @raise [CommandFailed] if installing, building or publishing fails
19
+ # Publishes the package, or with `dry_run` only packs it, which needs no
20
+ # credentials.
42
21
  def publish!(version, dry_run:)
43
22
  install_dependencies
44
23
  if dry_run
45
24
  @console.say("Dry run: npm publish --dry-run for @hecks/client #{version} (nothing is published)...")
46
- @commands.run!("npm", "publish", "--dry-run", "--access", "public", chdir: package_dir)
25
+ @registry.dry_publish!
47
26
  else
48
27
  @console.say("Publishing @hecks/client #{version} to npm (1Password will prompt for Touch ID)...")
49
28
  @console.say(APPROVAL_NOTICE)
50
- publish_with_token
29
+ @registry.publish!
51
30
  end
52
31
  end
53
32
 
54
33
  private
55
34
 
56
- def package_dir
57
- File.join(@root, PACKAGE_DIR)
58
- end
59
-
35
+ # npm's `prepack` hook builds `dist/`; there is no separate build step here.
60
36
  def install_dependencies
61
- return if Dir.exist?(File.join(package_dir, "node_modules"))
37
+ return if @registry.installed?
62
38
 
63
39
  @console.say("Installing the client's dependencies (npm ci)...")
64
- @commands.run!("npm", "ci", chdir: package_dir)
65
- end
66
-
67
- def publish_with_token
68
- with_userconfig do |userconfig|
69
- @commands.run!(
70
- "op", "run", "--env-file=#{File.join(@root, ENV_FILE)}", "--",
71
- "npm", "publish", "--access", "public", "--auth-type=web", "--userconfig", userconfig,
72
- chdir: package_dir
73
- )
74
- end
75
- end
76
-
77
- def with_userconfig
78
- file = Tempfile.new(["hecks-npmrc", ".npmrc"])
79
- file.chmod(0o600)
80
- file.write("#{USERCONFIG_LINE}\n")
81
- file.flush
82
- yield file.path
83
- ensure
84
- file&.close!
40
+ @registry.install!
85
41
  end
86
42
  end
87
43
  end