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,25 +1,7 @@
1
1
  module Hecks
2
2
  module Bluebook
3
- # **Which regexes a bluebook may say**.
4
- #
5
- # A `pattern:` is a fact about a value, carried in a bluebook — declared
6
- # data, not Ruby code, so it must not lean on what any one engine happens
7
- # to accept. Regex engines disagree in two different ways :
8
- #
9
- # only a backtracking engine can match it — lookahead, lookbehind,
10
- # backreferences, atomic groups, possessive quantifiers. None of these
11
- # can be matched in linear time, and linear-time engines refuse them
12
- # outright. Refused here for the same reason.
13
- #
14
- # every engine parses it and they mean different things — the dangerous
15
- # half, because nothing errors. `\d` `\w` `\s` are ASCII in some engines
16
- # and Unicode in others ; `[:digit:]` and friends flip the same way in
17
- # the other direction. Both families are refused, and a domain spells
18
- # the range it means.
19
- #
20
- # What remains — explicit ranges, alternation, quantifiers, anchors,
21
- # groups — reads identically everywhere, with `^` and `$` as line anchors
22
- # (Ruby's reading). The evidence is spec/corpus/fixtures/patterns.json.
3
+ # Which regexes a bluebook `pattern:` may say: only what every engine reads the same way.
4
+ # Backtracking-only and ASCII/Unicode-dependent constructs are refused.
23
5
  module PatternSubset
24
6
  Rejection = Struct.new(:construct, :reason)
25
7
 
@@ -55,36 +37,19 @@ module Hecks
55
37
 
56
38
  module_function
57
39
 
58
- # nil when the pattern is admitted, a Rejection when it is not.
40
+ # Returns nil when the pattern is admitted, a Rejection when it is not.
59
41
  #
60
- # A character walk, deliberately plain : the subset is defined by this
61
- # walk, and a cleverer spelling would hide what it admits. An escaped
62
- # construct is a literal, not a violation — `\(\?=` is the three
63
- # characters "(?=" and says nothing about lookahead — which is why this
64
- # steps over each backslash pair rather than matching the pattern as a
65
- # whole.
66
- # One character walk is the subset's definition (see the method
67
- # comment above): each construct-check is a branch in a single
68
- # ordered pass sharing `index`/`in_class`/`class_start`. Splitting
69
- # the branches into separate methods would force those three cursor
70
- # variables to thread as parameters/return values between them,
71
- # turning "the subset is this walk" into "the subset is these
72
- # methods agreeing about a shared cursor" — exactly what the walk's
73
- # own comment says a cleverer spelling would obscure.
42
+ # One ordered character walk defines the subset; an escaped construct is a literal,
43
+ # which is why each backslash pair is stepped over rather than matched as a whole.
74
44
  # rubocop:disable-next Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
75
45
  #
76
46
  # @param pattern [String, Symbol, #to_s] the declared `pattern:` regex source
77
- # @return [Rejection, nil] the reason the pattern is refused, or `nil` if it is
78
- # entirely within the portable subset
47
+ # @return [Rejection, nil] the reason the pattern is refused, or `nil` if admitted
79
48
  def validate(pattern)
80
49
  chars = pattern.to_s.chars
81
50
  index = 0
82
- # A character-class interior is a different alphabet : inside `[...]`,
83
- # `*`, `+`, `?`, `(`, `?` are literal characters, not quantifiers or
84
- # group syntax — `[*+]` means "a literal asterisk or plus". `]` is
85
- # only the class's close when it isn't the first character after `[`
86
- # or `[^` (where it is itself a literal, per POSIX bracket-expression
87
- # rules).
51
+ # Inside `[...]` quantifier characters are literals, and `]` closes the class unless
52
+ # it is the first character after `[` or `[^`.
88
53
  in_class = false
89
54
  class_start = nil
90
55
 
@@ -136,8 +101,45 @@ module Hecks
136
101
  nil
137
102
  end
138
103
 
139
- # Spelled out, not derived from the key : these strings are the refusal
140
- # a caller reads.
104
+ # Rewrites the line anchors of a declared pattern into whole-string anchors.
105
+ #
106
+ # Ruby reads `^` and `$` as line anchors, so `"ok\n../evil"` satisfies `^[a-z]+$`; Rust's
107
+ # `regex` reads them as text anchors. Enforcement matches the rewritten source so both
108
+ # engines refuse the same values. Escaped characters and bracket classes are left alone.
109
+ #
110
+ # @param pattern [String, Symbol, #to_s] the declared `pattern:` regex source
111
+ # @return [String] the source with `^` as `\A` and `$` as `\z` outside classes
112
+ def whole_string(pattern)
113
+ chars = pattern.to_s.chars
114
+ in_class = false
115
+ class_start = nil
116
+ out = +""
117
+ index = 0
118
+ while index < chars.length
119
+ char = chars[index]
120
+ if char == "\\"
121
+ out << char << chars[index + 1].to_s
122
+ index += 2
123
+ next
124
+ end
125
+ if in_class
126
+ in_class = false if char == "]" && index != class_start
127
+ elsif char == "["
128
+ in_class = true
129
+ class_start = index + 1
130
+ class_start += 1 if chars[class_start] == "^"
131
+ elsif char == "^"
132
+ char = "\\A"
133
+ elsif char == "$"
134
+ char = "\\z"
135
+ end
136
+ out << char
137
+ index += 1
138
+ end
139
+ out
140
+ end
141
+
142
+ # Spelled out, not derived from the key: callers read these strings in refusals.
141
143
  CONSTRUCTS = {
142
144
  backreference: "backreference",
143
145
  named_backreference: "named backreference",
@@ -149,17 +151,8 @@ module Hecks
149
151
  possessive: "possessive quantifier"
150
152
  }.freeze
151
153
 
152
- # Builds the rejection for one refused construct.
153
- #
154
- # @param key [Symbol] a key of `CONSTRUCTS`/`REASONS`, such as `:lookahead`
155
- # @return [Rejection] the construct's name and the reason it is refused
156
154
  def refuse(key) = Rejection.new(CONSTRUCTS.fetch(key), REASONS.fetch(key))
157
155
 
158
- # Says whether a POSIX bracket class (`[:digit:]` and friends) starts at `index`.
159
- #
160
- # @param chars [Array<String>] the pattern, split into characters
161
- # @param index [Integer] the position to check
162
- # @return [Boolean] whether a POSIX bracket class starts at `index`
163
156
  def posix_class_at?(chars, index)
164
157
  return false unless chars[index] == "[" && chars[index + 1] == ":"
165
158
 
@@ -168,14 +161,7 @@ module Hecks
168
161
  chars[cursor] == ":" && chars[cursor + 1] == "]"
169
162
  end
170
163
 
171
- # A possessive quantifier is `*+`, `++`, `?+`, or a bounded `{n}`/{n,m}`
172
- # immediately followed by `+` — only checked outside a character class,
173
- # where `*`, `+`, `?`, `{`, `}` are quantifier syntax rather than
174
- # literal characters.
175
- #
176
- # @param chars [Array<String>] the pattern, split into characters
177
- # @param index [Integer] the position to check
178
- # @return [Boolean] whether a possessive quantifier starts at `index`
164
+ # A possessive quantifier is `*+`, `++`, `?+` or a `{n,m}` bound followed by `+`.
179
165
  def possessive_at?(chars, index)
180
166
  return true if %w[* + ?].include?(chars[index]) && chars[index + 1] == "+"
181
167
  return false unless chars[index] == "{"
@@ -184,13 +170,7 @@ module Hecks
184
170
  !len.nil? && chars[index + len] == "+"
185
171
  end
186
172
 
187
- # Length of a `{n}` / `{n,}` / `{n,m}` bound starting at `index`, or nil
188
- # if what's there isn't one.
189
- #
190
- # @param chars [Array<String>] the pattern, split into characters
191
- # @param index [Integer] the position the bound is expected to start at
192
- # @return [Integer, nil] the bound's length in characters, or `nil` if `index`
193
- # does not start a `{n}`/`{n,}`/`{n,m}` bound
173
+ # Length of a `{n}` / `{n,}` / `{n,m}` bound at `index`, or nil if there is none.
194
174
  def bounded_quantifier_length(chars, index)
195
175
  cursor = index + 1
196
176
  digit_seen = false
@@ -3,19 +3,10 @@ require_relative "../ir"
3
3
 
4
4
  module Hecks
5
5
  module Bluebook
6
- # `compensates` — a second `DispatchSpec`, shape-identical to this
7
- # one, naming the command that undoes this dispatch specifically
8
- # (see `ProcessManagerBuilder::HandlerBuilder#dispatch_impl`'s own
9
- # comment). `nil` for a dispatch with nothing to undo (a pure
10
- # bookkeeping mark, or one whose own effect is superseded by a later
11
- # command rather than needing its own compensation). Never nested
12
- # further — a compensation is not itself compensable; no known
13
- # corpus need, and ADR 0025's own "a word earns its place by being
14
- # used" bar would refuse a second level speculatively.
6
+ # `compensates` is a second `DispatchSpec` naming the command that undoes this one, or nil.
7
+ # Never nested; `reverses` stays reserved for `corrects`.
15
8
  DispatchSpec = Struct.new(:command_name, :with_spec, :compensates, keyword_init: true) do
16
- # A Struct already answers to_h; including the mixin puts the
17
- # declared emission ahead of Struct's own in the ancestry, which
18
- # is what makes the shape data rather than a method body.
9
+ # Struct already answers to_h; the mixin puts the declared emission ahead of it.
19
10
  include Hecks::IR
20
11
 
21
12
  emits_ir(
@@ -37,62 +28,19 @@ module Hecks
37
28
  )
38
29
  end
39
30
 
40
- # The compensation half of a procedure, as its own thing.
41
- #
42
- # A process manager coordinates: legs, states, an opinion about who goes
43
- # next. A saga undoes: what makes the world good again when a leg it
44
- # dispatched is refused. Two concepts, and the industry slurs them into one
45
- # word — so here they are two objects, and a procedure either has a saga or
46
- # does not.
47
- #
48
- # `undoes` is the ordered list of commands the compensation sends — a
49
- # static preview, declaration order (`Behaviour::ProcessManager#saga`),
50
- # not one instance's own runtime history. Per-dispatch compensation
51
- # (`compensates`, on the step it compensates for) moved most of what
52
- # a saga undoes off this leg's own hand-written body and onto
53
- # whichever forward dispatch each one undoes — this reads every
54
- # declared `compensates` across the whole saga first, then whatever
55
- # this leg's own hand-written body still lists, for compensation
56
- # that isn't expressible as "undo command X." which of a declared
57
- # `compensates` actually fires for one instance, and in what order
58
- # (newest-first, completed-legs-only), is `SagaInterpreter`'s own
59
- # dynamic `completed_compensations` — a per-instance runtime fact
60
- # this declaration-only object could never hold.
61
- #
62
- # **Naming collision, once flagged, now resolved** — `command`'s own
63
- # `corrects event, reverses: true` (docs/implemented/decisions/0036-
64
- # corrects-is-an-appended-fact-not-a-rewrite.md) already claimed
65
- # `reverses` for a different meaning: auto-deriving a command's own
66
- # corrective mutation from a past event, not a saga's own
67
- # compensating leg from a past dispatch. This feature keeps
68
- # `reverses` reserved for `corrects` and uses `compensates` for
69
- # per-dispatch saga compensation instead — a deliberate choice, not
70
- # an accidental collision.
31
+ # The compensation half of a procedure: the commands sent to undo a refused leg.
32
+ # `undoes` is a static declaration-order preview; per-instance order is the runtime's.
71
33
  Saga = Struct.new(:trigger, :from_state, :to_state, :compensations, keyword_init: true) do
72
- # Lists the commands this saga sends to undo a refused leg.
73
- #
74
- # @return [Array<String>] the name of each compensating command, in the order
75
- # `compensations` lists them
76
34
  def undoes = compensations.map(&:command_name)
77
35
 
78
36
  def to_s = "#{trigger} → #{to_state} (#{undoes.join(', ')})"
79
37
  end
80
38
 
81
- # The built form of a `process_manager "Name" do ... end` block,
82
- # produced by `DSL::ProcessManagerBuilder` — its start/end events,
83
- # correlation field, derived states, and handler rows. Its
84
- # compensation half (`saga`, `Behaviour::ProcessManager#saga`) is
85
- # derived from the handler answering `REFUSED`, below, not declared as
86
- # its own construct.
39
+ # The built form of a `process_manager "Name" do ... end` block, made by
40
+ # `DSL::ProcessManagerBuilder`.
87
41
  class ProcessManager
88
- # The bluebook's name for this construct, asked the same way of a class
89
- # that has crossed over and of an IR object that has not. Collapses into
90
- # Construct when this one crosses.
91
- # The trigger of a compensating leg. Not an event name — no aggregate
92
- # announces that a leg the procedure dispatched was declined — so it lives
93
- # here beside the thing it triggers rather than in the runtime that
94
- # notices it. Declared in the language's Trigger vocabulary, which
95
- # spec/vocabulary_conformance_spec holds to this constant.
42
+ # The trigger of a compensating leg. Not an event name: no aggregate announces a declined
43
+ # leg. Held to the language's Trigger vocabulary by spec/vocabulary_conformance_spec.
96
44
  REFUSED = Hecks::Vocabulary.fetch("Trigger").first
97
45
 
98
46
  include Hecks::IR
@@ -100,21 +48,8 @@ module Hecks
100
48
 
101
49
  emits_ir(
102
50
  name: :name,
103
- # M11 — `&.`, not `.`: a DSL-built process manager always carries
104
- # a real `correlates_by` (`ProcessManagerBuilder#build` refuses to
105
- # mint one without it), but the IR class itself defaults it to
106
- # `nil` and is what `Assembly::Build`'s `:identity` reader
107
- # (`value&.to_sym`) round-trips against. A bare `.to_s` mapped
108
- # that absent case to `""`, indistinguishable on the wire from a
109
- # real empty name and read back as the wrong, non-nil `:""`
110
- # instead of `nil` — the same nil-erasure S1 fixed for
111
- # `render_value`, one field over. `correlates_by` is always a
112
- # bare Symbol (`SagaInterpreter` hash-looks-up a payload by it),
113
- # never a `Literal`-encoded polymorphic value, so this stays a
114
- # local `&.` rather than routing through `Literal.render` — that
115
- # would wrap a real value in a leading `:` and break both the
116
- # `:identity` reader's plain `to_sym` and the pinned golden IR
117
- # fixtures' bare-string spelling (`"reference.value"`).
51
+ # `&.` because the IR class defaults `correlates_by` to nil; `.to_s` reads back as `""`.
52
+ # A bare Symbol string, not `Literal.render`, to match the golden IR fixtures.
118
53
  correlates_by: -> { correlates_by&.to_s },
119
54
  starts_on: :starts_on,
120
55
  ends_on: :ends_on,
@@ -124,15 +59,10 @@ module Hecks
124
59
 
125
60
  attr_reader :name, :correlates_by, :starts_on, :ends_on, :states, :handlers
126
61
 
127
- # @param name [String, Symbol] the process manager's declared name
128
- # @param correlates_by [Symbol, nil] the payload field a triggering event's
129
- # instances are correlated by
62
+ # @param correlates_by [Symbol, nil] the payload field that correlates a triggering
63
+ # event to an instance
130
64
  # @param starts_on [String, nil] the event that starts a new instance
131
65
  # @param ends_on [String, nil] the event that ends an instance
132
- # @param states [Array<String>] the declared states this procedure's instances pass
133
- # through
134
- # @param handlers [Array<Bluebook::ProcessManagerHandler>] the declared handler rows,
135
- # one per (event, state) leg
136
66
  def initialize(name:, correlates_by: nil, starts_on: nil, ends_on: nil,
137
67
  states: [], handlers: [])
138
68
  @name = name.to_s
@@ -3,9 +3,8 @@ require_relative "project_register"
3
3
 
4
4
  module Hecks
5
5
  module Bluebook
6
- # Boots each discovered directory and feeds its declarations into the
7
- # deterministic project register. Discovery and FQN registration live in
8
- # their own objects so either can be used without executing domains.
6
+ # Boots each discovered directory and feeds its declarations into the project register.
7
+ # Discovery and FQN registration are separate objects so either works without booting domains.
9
8
  class ProjectLoader
10
9
  Entry = ProjectRegister::Entry
11
10
  DuplicateFqn = ProjectRegister::DuplicateFqn
@@ -14,31 +13,15 @@ module Hecks
14
13
 
15
14
  attr_reader :root, :discovery, :register
16
15
 
17
- # Discovers and loads every domain under `root` in one call.
18
- #
19
- # @param root [String] the directory to search under
20
- # @return [Bluebook::ProjectLoader] the loader, with every discovered domain
21
- # booted and registered
22
16
  def self.load(root) = new(root).load
23
17
 
24
- # @param root [String] the directory to search under
25
- # @param discovery [Bluebook::ProjectDiscovery] the discovery this loader walks
26
- # `root` with
27
- # @param register [Bluebook::ProjectRegister] the register booted domains are
28
- # fed into
29
18
  def initialize(root, discovery: ProjectDiscovery.new(root), register: ProjectRegister.new)
30
19
  @root = File.expand_path(root)
31
20
  @discovery = discovery
32
21
  @register = register
33
22
  end
34
23
 
35
- # Boots every domain `discovery` finds under `root` and registers its declarations.
36
- #
37
- # @return [Bluebook::ProjectLoader] self
38
- # @raise [Bluebook::ProjectRegister::MissingRealm] see `ProjectRegister#register`
39
- # @raise [Bluebook::ProjectRegister::LatestMismatch] see `ProjectRegister#register`
40
- # @raise [Bluebook::ProjectRegister::DuplicateFqn] see `ProjectRegister#register`
41
- # @raise [Runtime::WiringError] see `ProjectRegister#register`
24
+ # Errors raised by `ProjectRegister#register` propagate.
42
25
  def load
43
26
  discovery.bluebook_directories.each do |directory|
44
27
  runtime = Runtime.boot(directory)
@@ -47,33 +30,14 @@ module Hecks
47
30
  self
48
31
  end
49
32
 
50
- # Lists every registered entry.
51
- #
52
- # @return [Hash{String => Bluebook::ProjectRegister::Entry}] every registered
53
- # entry, keyed by its FQN
54
33
  def entries = register.entries
55
34
 
56
- # Finds a registered entry by its fully-qualified verb.
57
- #
58
- # @param address [String, #to_s] the FQN to look up
59
- # @return [Bluebook::ProjectRegister::Entry] the entry registered under `address`
60
- # @raise [KeyError] if no entry is registered under `address`
61
35
  def fetch(address) = register.fetch(address)
62
36
 
63
- # Says whether an entry is registered under an address.
64
- #
65
- # @param address [String, #to_s] the FQN to check
66
- # @return [Boolean] whether an entry is registered under `address`
67
37
  def include?(address) = register.include?(address)
68
38
 
69
- # Lists every registered command entry.
70
- #
71
- # @return [Array<Bluebook::ProjectRegister::Entry>] every registered command entry
72
39
  def commands = register.commands
73
40
 
74
- # Lists every registered query entry.
75
- #
76
- # @return [Array<Bluebook::ProjectRegister::Entry>] every registered query entry
77
41
  def queries = register.queries
78
42
  end
79
43
  end
@@ -4,14 +4,8 @@ module Hecks
4
4
  # declarations become public FQNs, but never searches or boots folders.
5
5
  class ProjectRegister
6
6
  Entry = Struct.new(:fqn, :source_directory, :dispatcher, :declared_verb, :domain_version, keyword_init: true) do
7
- # Says whether this entry addresses a command.
8
- #
9
- # @return [Boolean] whether this entry's `fqn` addresses a command
10
7
  def command? = fqn.command?
11
8
 
12
- # Says whether this entry addresses a query.
13
- #
14
- # @return [Boolean] whether this entry's `fqn` addresses a query
15
9
  def query? = fqn.query?
16
10
  end
17
11
 
@@ -21,53 +15,31 @@ module Hecks
21
15
 
22
16
  attr_reader :entries
23
17
 
24
- # Starts an empty register, with no domains loaded yet.
25
18
  def initialize
26
19
  @entries = {}
27
20
  @tenant_directories = Hash.new { |hash, key| hash[key] = [] }
28
21
  end
29
22
 
30
- # Finds a registered entry by its fully-qualified verb.
23
+ # Finds an entry by FQN, such as `"Pizzas.Pizza.Order"`.
31
24
  #
32
- # @param address [String, #to_s] the FQN to look up, such as `"Pizzas.Pizza.Order"`
33
- # @return [Bluebook::ProjectRegister::Entry] the entry registered under `address`
34
25
  # @raise [KeyError] if no entry is registered under `address`
35
26
  def fetch(address) = entries.fetch(address.to_s)
36
27
 
37
- # Says whether an entry is registered under an address.
38
- #
39
- # @param address [String, #to_s] the FQN to check
40
- # @return [Boolean] whether an entry is registered under `address`
41
28
  def include?(address) = entries.key?(address.to_s)
42
29
 
43
- # Lists every registered command entry.
44
- #
45
- # @return [Array<Bluebook::ProjectRegister::Entry>] every registered command entry
46
30
  def commands = entries.values.select(&:command?)
47
31
 
48
- # Lists every registered query entry.
49
- #
50
- # @return [Array<Bluebook::ProjectRegister::Entry>] every registered query entry
51
- def queries = entries.values.select(&:query?)
32
+ def queries = entries.values.select(&:query?)
52
33
 
53
- # Registers every aggregate command/query and read model query a booted chapter
54
- # declares, under its versioned and (if current) unversioned FQNs.
34
+ # Registers every aggregate command/query and read model query of each chapter, under
35
+ # its versioned and (if current) unversioned FQNs.
55
36
  #
56
- # @param bluebooks [Array<Bluebook::Chapter>] the booted chapters to register
57
- # @param registry [Runtime::Registry] the registry `bluebooks` booted into
58
- # @param dispatcher [Runtime::Dispatcher, Runtime::RemoteDispatcher] the booted
59
- # dispatcher entries dispatch through
60
- # @param directory [String] the source directory `bluebooks` was discovered under
61
37
  # @return [Bluebook::ProjectRegister] self
62
- # @raise [Bluebook::ProjectRegister::MissingRealm] if a bluebook's world declares no
63
- # realm
64
- # @raise [Bluebook::ProjectRegister::LatestMismatch] if a world's `latest` disagrees
65
- # with its bluebook's own version
66
- # @raise [Bluebook::ProjectRegister::DuplicateFqn] if an FQN this call would register
67
- # is already registered
68
- # @raise [Runtime::WiringError] if a second tenant registers the same on-disk
69
- # directory while any of its aggregates binds to an adapter that is not
70
- # `tenant_capable?`
38
+ # @raise [MissingRealm] if a bluebook's world declares no realm
39
+ # @raise [LatestMismatch] if a world's `latest` disagrees with its bluebook's version
40
+ # @raise [DuplicateFqn] if an FQN this call would register is already registered
41
+ # @raise [Runtime::WiringError] if a second tenant registers the same directory while
42
+ # an aggregate binds to an adapter that is not `tenant_capable?`
71
43
  def register(bluebooks, registry, dispatcher, directory)
72
44
  bluebooks.each do |bluebook|
73
45
  refuse_unless_safe_for_second_tenant!(bluebook, registry, directory)
@@ -87,10 +59,6 @@ module Hecks
87
59
 
88
60
  private
89
61
 
90
- # Split out of `register` per-aggregate: same versioned-then-current
91
- # registration shape as `register_read_model!`, just applied to a
92
- # command/query pair instead of a single report. No state threads
93
- # back to `register` — each `add` call is independent.
94
62
  def register_aggregate!(aggregate, bluebook, world, realm, directory, dispatcher)
95
63
  aggregate.commands.each do |command|
96
64
  if bluebook.version
@@ -116,9 +84,6 @@ module Hecks
116
84
  end
117
85
  end
118
86
 
119
- # Split out of `register` per-read-model: registers the versioned FQN
120
- # (if this bluebook declares a version) and the current/unversioned
121
- # FQN (if this bluebook is the world's latest) for one report.
122
87
  def register_read_model!(model, bluebook, world, realm, directory, dispatcher)
123
88
  if bluebook.version
124
89
  add(Fqn.query(realm: realm, domain: bluebook.name, version: bluebook.version,
@@ -130,22 +95,9 @@ module Hecks
130
95
  end
131
96
  end
132
97
 
133
- # The actual "more than one tenant" moment — Runtime::TenantCheck's
134
- # own header names this table as the one place real multitenancy
135
- # happens: the same on-disk directory (one domain, one
136
- # `persisted_by` binding) registering a second time, under a
137
- # different realm, into this same shared route table. A directory's
138
- # first registration is never refused here — nothing shares its
139
- # data yet, so a plain single-tenant deployment on an ordinary
140
- # adapter (Postgres, no schema story) still boots exactly as
141
- # before. Only the second (and any later) registration of that
142
- # same directory is refused, and refused before this call adds its
143
- # routes to the table — so a leaking tenant's requests never
144
- # become reachable through `Router#resolve` in the first place.
145
- #
146
- # Keyed on `directory` + `bluebook.name` only, not realm or
147
- # `dispatcher` — two tenants share the identical on-disk domain,
148
- # differing only by which realm/environment overlay booted it.
98
+ # A directory's first registration is never refused; only a second one (another tenant
99
+ # sharing the on-disk domain) is, before its routes reach the table. Keyed on
100
+ # `directory` + name, not realm or dispatcher.
149
101
  def refuse_unless_safe_for_second_tenant!(bluebook, registry, directory)
150
102
  key = [directory, bluebook.name]
151
103
  seen_before = @tenant_directories.key?(key) && @tenant_directories[key].any?
@@ -1,33 +1,15 @@
1
1
  require_relative "behaviour/query"
2
2
 
3
3
  module Hecks
4
- # Reopened here only to add `render_value` below — the pinned
5
- # wire-literal rendering (`Literal.render`) the `emits_ir` Procs
6
- # throughout this chapter reach for. See lib/hecks/bluebook.rb's own
7
- # header for what `Bluebook` is as a whole.
4
+ # Reopened to add `render_value`, the wire-literal rendering `emits_ir` procs use.
8
5
  module Bluebook
9
- # Renders a captured Ruby value to its self-describing wire spelling.
10
- #
11
- # @param value [Object] any value an `emits_ir` field carries, such as a Symbol,
12
- # String, Hash, Array, or literal
13
- # @return [String] the value rendered through `Hecks::Literal.render`
6
+ # Renders a captured value to its wire spelling through `Hecks::Literal.render`.
14
7
  def self.render_value(value) = Literal.render(value)
15
8
 
16
9
  # A query — an ask, declared on an aggregate or on one of its entities.
17
10
  #
18
- # It crosses over as an instance rather than a class, and the reason is worth
19
- # stating because it is the boundary of the pattern. A query inherits its
20
- # whole body from `QuerySpecification::Common::Options` — `wheres`,
21
- # `order_by`, `limit`, `offset`, `cursor`,
22
- # `authorization`, `null_semantics`, `inspection` — and those
23
- # are instance methods that the runtime and the SQLite adapter both read.
24
- # Hoisting the declaration onto a metaclass would put the identity and the
25
- # specification on opposite sides of the object.
26
- #
27
- # And nothing is lost, because `Class#name` was the only reason a construct
28
- # ever needed a second word for its own name. An instance answers `name`
29
- # truthfully. So a query gains an owner and an identity — which is what the
30
- # graph is for — and keeps the name it always had.
11
+ # It crosses over as an instance, not a class: its body comes from
12
+ # `QuerySpecification::Common::Options`, whose instance methods the runtime reads.
31
13
  class Query < QuerySpecification::Common::Options
32
14
  include Construct
33
15
 
@@ -43,31 +25,14 @@ module Hecks
43
25
  limit: one(:limit)
44
26
  )
45
27
 
46
- attr_reader :name, :description, :attributes
28
+ attr_reader :name, :description, :attributes, :returns
47
29
 
48
- # @param name [String, Symbol] the query's declared name
49
- # @param description [String, nil] the query's declared prose description
50
- # @param attributes [Array<Bluebook::Attribute>] the query's declared result fields
51
- # @param wheres [Array<QuerySpecification::Common::WhereClause>] the declared filter
52
- # conditions
53
- # @param order_by [QuerySpecification::Common::OrderBy, nil] the declared sort field
54
- # and direction, or `nil` for no explicit ordering
55
- # @param limit [QuerySpecification::Common::LimitSpec, nil] the declared row limit,
56
- # or `nil` for none
57
- # @param offset [QuerySpecification::Common::OffsetSpec, nil] the declared row offset,
58
- # or `nil` for none
59
- # @param cursor [QuerySpecification::Common::CursorSpec, nil] the declared pagination
60
- # cursor, or `nil` for none
61
- # @param authorization [QuerySpecification::Common::AuthorizationSpec, nil] the declared
62
- # authorization policy, or `nil` for none
63
- # @param null_semantics [QuerySpecification::Common::NullSemantics, nil] how this query
64
- # orders `nil` values; defaults to `NullSemantics.default` when omitted
65
- # @param inspection [QuerySpecification::Common::InspectionSpec, nil] the declared
66
- # inspection mode, or `nil` for none
30
+ # @param null_semantics [QuerySpecification::Common::NullSemantics, nil] defaults to
31
+ # `NullSemantics.default`
67
32
  def initialize(name:, description: nil, attributes: [], wheres: [],
68
33
  order_by: nil, limit: nil, offset: nil, cursor: nil,
69
34
  authorization: nil, null_semantics: nil,
70
- inspection: nil)
35
+ inspection: nil, returns: nil)
71
36
  null_semantics ||= QuerySpecification::Common::NullSemantics.default
72
37
  super(wheres: wheres, order_by: order_by, limit: limit, offset: offset, cursor: cursor,
73
38
  authorization: authorization,
@@ -76,17 +41,28 @@ module Hecks
76
41
  @hecks_name = @name
77
42
  @description = description
78
43
  @attributes = attributes
44
+ @returns = returns&.to_s
79
45
  end
80
46
 
81
- # A query's shape is not fixed — `extra_options_to_h` carries
82
- # whatever options the specification layer grew (count, median,
83
- # group_by, scope_to). Declared emission covers the settled part
84
- # and `super` hands it over; the tail stays dynamic, which is the
85
- # honest description of it.
47
+ # The value object a `returns` names, without the `list_of(...)` wrapper.
48
+ #
49
+ # @return [String, nil] the value object's name, or `nil` when the query returns nothing
50
+ def returns_name = @returns&.sub(/\Alist_of\((.*)\)\z/, '\1')
51
+
52
+ # Says whether the answer is many rows of the returned value object.
86
53
  #
87
- # @return [Hash] the declared emission, merged with whatever `extra_options_to_h`
88
- # the specification layer currently carries
89
- def to_h = super.merge(extra_options_to_h)
54
+ # @return [Boolean] true for `returns list_of(Name)`
55
+ def returns_list? = !@returns.nil? && @returns.start_with?("list_of(")
56
+
57
+ # `extra_options_to_h` (count, median, group_by, scope_to) stays dynamic; `super` covers the
58
+ # declared emission. `returns` follows, only when the query declares one, so a query that
59
+ # returns nothing keeps its wire shape.
60
+ #
61
+ # @return [Hash] the declared emission merged with `extra_options_to_h`, then `returns`
62
+ def to_h
63
+ shape = super.merge(extra_options_to_h)
64
+ @returns ? shape.merge(returns: @returns) : shape
65
+ end
90
66
  end
91
67
  end
92
68
  end