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
@@ -2,14 +2,8 @@ require_relative "word_gate"
2
2
  module Hecks
3
3
  module Bluebook
4
4
  module DSL
5
- # Parses an `entity "Name" do ... end` block nested inside an aggregate
6
- # (or another entity, ADR 0026 — "a piece nested inside a piece") into
7
- # an `Entity` — attributes, relationships (`has_many`/`has_one`/
8
- # `belongs_to`), its own nested commands/queries/lifecycle, and
9
- # preconditions shared across them. Threads the owning aggregate's
10
- # value-object and cross-entity `given` pools through unchanged, so a
11
- # nested piece resolves identity and shared rules against the same
12
- # aggregate-wide state a top-level piece does.
5
+ # Parses an `entity "Name" do ... end` block into an `Entity` — attributes, relationships,
6
+ # nested commands/queries/lifecycle, and preconditions shared across them (ADR 0026).
13
7
  class EntityBuilder
14
8
  GRAMMAR_CONTEXT = "Entity".freeze
15
9
 
@@ -18,22 +12,8 @@ module Hecks
18
12
  include RuleReference
19
13
  include WordGate
20
14
 
21
- # @param name [String] the entity's name, as written after `entity`
22
- # @param owner_value_objects [Array<Bluebook::ValueObject>] the owning aggregate's value
23
- # objects, threaded through unchanged for this piece's `identified_by` to resolve
24
- # against
25
- # @param owner_named_givens [Hash{String => Bluebook::Given}] the aggregate-wide,
26
- # cross-entity given pool, shared and written through by `given_impl`
27
- # @param identity_name_prefix [String, nil] the prefix a synthesized identity value
28
- # object's name takes; nil derives it from `name`
29
- # @param identity_value_object_installer [#call, nil] called with a synthesized value
30
- # object to install it onto the owning aggregate; nil when there is none
31
- # @param aggregate_name [String, nil] the root aggregate's name, for chapter-wide given
32
- # keys; nil derives it from `name`
33
- # @param chapter_entity_named_givens [Hash{String => Hash{String => Bluebook::Given}}]
34
- # the chapter-wide, entity-scoped given pool, shared and written through
35
- # @param chapter_entity_pending_givens [Array<Hash>] unresolved chapter-wide bare given
36
- # references, appended to when this piece's own reference cannot resolve yet
15
+ # Builds a piece nested under an aggregate (or another piece), threading the owner's
16
+ # value-object and given pools through unchanged so nested pieces share the same state.
37
17
  def initialize(name, owner_value_objects: [], owner_named_givens: {},
38
18
  identity_name_prefix: nil, identity_value_object_installer: nil,
39
19
  aggregate_name: nil, chapter_entity_named_givens: {}, chapter_entity_pending_givens: [])
@@ -46,85 +26,36 @@ module Hecks
46
26
  @owner_value_objects = owner_value_objects
47
27
  @identity_name_prefix = identity_name_prefix || Naming.demodulise(name)
48
28
  @identity_value_object_installer = identity_value_object_installer
49
- # The aggregate-wide cross-entity given pool — one hash, the
50
- # same object, threaded unchanged through every piece nested
51
- # under one aggregate however deep (the identical shape
52
- # `@owner_value_objects` already threads — see this class'
53
- # own `entity` comment). `given`'s own block form writes
54
- # through to it; a sibling piece's bare command-level
55
- # reference reads from it via `CommandBuilder#
56
- # reference_named_given`.
29
+ # Threaded unchanged through every nested piece so a sibling's bare given
30
+ # reference can read the same aggregate-wide pool `given_impl` writes to.
57
31
  @owner_named_givens = owner_named_givens
58
- # **One level wider still** — the chapter-wide, entity-scoped pool
59
- # (the piece analogue of `AggregateBuilder#@chapter_named_givens`,
60
- # one level down). `@aggregate_name` names this piece's own
61
- # root, so the write-through below can key itself
62
- # "AggregateName.EntityName" — the same dotted addressing
63
- # convention `declared_by:` already uses chapter-wide, one
64
- # level up. See `#given_impl`'s own comment for what this
65
- # closes and `docs/implemented/resolution-rules/
66
- # chapter-entity-given.md` for the full algorithm.
32
+ # One level wider than `@owner_named_givens`: the chapter-wide, entity-scoped
33
+ # pool, keyed "Aggregate.Entity" so `#given_impl` can resolve across aggregates.
67
34
  @aggregate_name = aggregate_name || Naming.demodulise(name)
68
35
  @chapter_entity_named_givens = chapter_entity_named_givens
69
36
  @chapter_entity_pending_givens = chapter_entity_pending_givens
70
- # **Deferred construction** — see `AggregateBuilder#drain_pending!`'s
71
- # own comment; the identical mechanism, one level down, so a
72
- # nested piece's own commands (Dispatch inside Handler) see
73
- # every sibling entity/command/query this piece goes on to
74
- # declare, not just whatever came before it textually.
37
+ # Deferred: built once every sibling in this block has been seen, so a nested
38
+ # command can resolve a sibling entity/command/query declared later in the block.
75
39
  @pending_entities = []
76
40
  @pending_commands = []
77
41
  @pending_queries = []
78
42
  end
79
43
 
80
44
  # Sets the human-readable description shown for this entity.
81
- #
82
- # @param value [String] the description text
83
- # @return [String] the description as stored
84
45
  def description(value) = @description = value
85
46
 
86
- # Declares a reference from this piece to another aggregate's identity.
87
- #
88
- # The same field AggregateBuilder's own reference_to builds — a
89
- # piece can hold a reference to another root exactly the way its
90
- # own head can (Card.assignee_id, a Team's own id), just never
91
- # to another piece, since there's no cross-piece addressing
92
- # anywhere in this language to resolve one against.
93
- #
94
- # Answers the `reference_to` word through the table's `calls:`
95
- # column — item #13's full metaprogrammed
96
- # dispatch (slice 4b). Bootstrap-reachable, in
97
- # `GenericDispatch::BOOTSTRAP_CALLS_FALLBACK`.
98
- #
99
- # @param type [Module, Symbol, String] the referenced aggregate, written as a bare
100
- # constant
101
- # @param as [Symbol, nil] the attribute's name; nil derives it from `type`
102
- # @param optional [Boolean] whether the reference may be absent
103
- # @return [void]
104
- # @raise [Bluebook::DSL::Malformed] if `as` (or the derived name) is already declared
47
+ # Declares a reference from this piece to another aggregate's identity — never to
48
+ # another piece, since this language has no cross-piece addressing to resolve one against.
105
49
  def reference_to_impl(type, as: nil, optional: false)
106
50
  target = Naming.demodulise(type)
107
51
  relationship_attribute(target, :reference_to,
108
52
  as || default_reference_name(target), optional: optional)
109
53
  end
110
54
 
111
- # has_many_impl/has_one_impl are DSL declaration keywords a domain
112
- # author writes as bare has_many/has_one (matching belongs_to_impl
113
- # alongside them) — not real predicates, so renaming to many?/one?
114
- # per Naming/PredicatePrefix would break every bluebook that
115
- # declares one. New on Entity (Wave 6, identity-and-relationships
116
- # arc) — pieces never had relationship words before; named
117
- # `*_impl` to match AggregateBuilder's own siblings, item #13's
118
- # full metaprogrammed dispatch convention.
55
+ # `has_many_impl`/`has_one_impl` are DSL keywords (`has_many`/`has_one` in a bluebook),
56
+ # not real predicates, so Naming/PredicatePrefix does not apply here.
119
57
  # rubocop:disable Naming/PredicatePrefix
120
58
  # Declares a list-typed relationship to another entity, referenced by its plural name.
121
- #
122
- # @param type [Module, Symbol, String] the related entity's plural name, a bare constant
123
- # @param as [Symbol, nil] the attribute's name; nil derives it from `type`
124
- # @param options [Hash] must be empty; kept only to name which unsupported keyword was
125
- # given in the refusal message
126
- # @return [void]
127
- # @raise [Bluebook::DSL::Malformed] if any keyword argument is given
128
59
  def has_many_impl(type, as: nil, **options)
129
60
  unless options.empty?
130
61
  raise Malformed,
@@ -137,11 +68,6 @@ module Hecks
137
68
  end
138
69
 
139
70
  # Declares a single-valued relationship to another entity.
140
- #
141
- # @param type [Module, Symbol, String] the related entity, a bare constant
142
- # @param as [Symbol, nil] the attribute's name; nil derives it from `type`
143
- # @param optional [Boolean] whether the relationship may be absent
144
- # @return [void]
145
71
  def has_one_impl(type, as: nil, optional: false)
146
72
  target = Naming.demodulise(type)
147
73
  relationship_attribute(target, :has_one, as || Naming.snake(target).to_sym, optional: optional)
@@ -149,204 +75,59 @@ module Hecks
149
75
  # rubocop:enable Naming/PredicatePrefix
150
76
 
151
77
  # Declares a single-valued relationship to the entity that owns this one.
152
- #
153
- # @param type [Module, Symbol, String] the owning entity, a bare constant
154
- # @param as [Symbol, nil] the attribute's name; nil derives it from `type`
155
- # @param optional [Boolean] whether the relationship may be absent
156
- # @return [void]
157
78
  def belongs_to_impl(type, as: nil, optional: false)
158
79
  target = Naming.demodulise(type)
159
80
  relationship_attribute(target, :belongs_to, as || Naming.snake(target).to_sym, optional: optional)
160
81
  end
161
82
 
162
- # A piece is known by a field, not by a whole value object.
163
- # `identified_by :sequence` names the scalar inside it, which is
164
- # what an id actually is — a LedgerEntry is entry 3, not entry
165
- # {"value":3}. `identified_by` itself is AttributeCollector's own
166
- # shared method (S9) — the two constructs cannot drift apart in
167
- # how they spell an identity, including composite
168
- # (`identified_by :branch_code, :box_number`), which a piece may
169
- # declare for the same reason a head may.
83
+ # `identified_by` (from AttributeCollector) names the scalar field that is this
84
+ # piece's identity, including composite identity, the same as an aggregate's own.
170
85
 
171
86
  # Queues a command declared on this piece, built later once every sibling has been seen.
172
- #
173
- # `from:` — see `AggregateBuilder#command`'s own comment; the
174
- # same guard, checked against this piece's own lifecycle field
175
- # (S10, ADR 0025 — a piece's own state machine is checkable the
176
- # same way a head's is).
177
- #
178
- # Answers the `command` word through the table's `calls:` column,
179
- # along with its siblings `query`/`entity`/`lifecycle` below —
180
- # item #13's full metaprogrammed dispatch (slice 4c), same
181
- # reasoning as AggregateBuilder's own siblings: bootstrap-
182
- # reachable, in `GenericDispatch::BOOTSTRAP_CALLS_FALLBACK`.
183
- #
184
- # @param name [String] the command's name
185
- # @param from [String, Symbol, Array<String, Symbol>, nil] the lifecycle state(s) this
186
- # command guards from; nil admits from any state
187
- # @yield the command body, evaluated against a `CommandBuilder` once drained
188
- # @return [Array<Array>] every pending command queued so far, this one last
189
87
  def command_impl(name, from: nil, &block)
190
88
  @pending_commands << [name, from, block]
191
89
  end
192
90
 
193
91
  # Queues a query declared on this piece, built later once every sibling has been seen.
194
- #
195
- # @param name [String] the query's name
196
- # @yield the query body, evaluated against a `QueryBuilder` once drained
197
- # @return [Array<Array>] every pending query queued so far, this one last
198
92
  def query_impl(name, &block)
199
93
  @pending_queries << [name, block]
200
94
  end
201
95
 
202
96
  # Queues a piece nested inside this one, built later once every sibling has been seen.
203
- #
204
- # S17, ADR 0026 — a piece nested inside a piece. "A `Dispatch`
205
- # [has] no life outside its `Handler`" (the ADR's own words) —
206
- # the same reason `Member` nests inside `ValueObject`, one level
207
- # further in. `owner_value_objects` passes straight through
208
- # unchanged, not re-derived from this entity's own attributes —
209
- # a piece mints no value objects of its own at any depth, so a
210
- # nested piece's bare `identified_by :field` still resolves
211
- # against the same root aggregate's value objects an outer
212
- # piece's already does (`AggregateBuilder#entity`'s own comment
213
- # names this pool ; there is exactly one of them, however deep
214
- # the nesting goes).
215
- # @param name [String] the nested piece's name
216
- # @yield the piece body, evaluated against an `EntityBuilder` once drained
217
- # @return [Array<Array>] every pending piece queued so far, this one last
97
+ # `owner_value_objects` passes through unchanged since a piece mints none of its own.
218
98
  def entity_impl(name, &block)
219
99
  @pending_entities << [name, block]
220
100
  end
221
101
 
222
102
  # Declares this piece's own state machine.
223
- #
224
- # @param field [Symbol, String] the attribute the state machine lives on
225
- # @param default [String, Symbol] the state a new record starts in
226
- # @yield the lifecycle body of `transition` rows, evaluated against a `LifecycleBuilder`
227
- # @return [Bluebook::Lifecycle] the built state machine
228
- # @raise [Bluebook::DSL::Malformed] if two transitions for one command overlap
229
103
  def lifecycle_impl(field, default:, &)
230
104
  @lifecycle = LifecycleBuilder.build(field, default: default, &)
231
105
  end
232
106
 
233
- # A precondition shared across this piece's own commands, declared
234
- # once — the same move `AggregateBuilder#given` already makes,
235
- # one level down. Real, live redundancy this closes: banking's
236
- # own `LedgerEntry.Amend`/`LedgerEntry.Reverse` each repeated
237
- # `given("customer is active") { parent.customer.status ==
238
- # "active" }` and `given("account is open") { parent.status ==
239
- # "open" }`, byte for byte, because a piece had no way to declare
240
- # either once and reference it back — only the aggregate could.
241
- # Declare before the commands that reference it, the same
242
- # ordering `AggregateBuilder#given`'s own comment names — though
243
- # since ADR 0028, `command` only queues a descriptor and actually
244
- # builds at `#drain_pending!` time, well after this whole block
245
- # (including every `given` in it) has already run, so textual
246
- # order within the block does not actually matter here; named
247
- # for the reader anyway, since `given`'s own resolution logic
248
- # (`CommandBuilder#reference_named_given`) still reads whatever
249
- # `@named_givens` holds at the command's own build time, not by
250
- # magic.
251
107
  # Declares a rule this piece's own commands must satisfy, or references one a sibling
252
108
  # piece anywhere in the chapter already declared.
253
109
  #
254
- # Answers the `given` word through the table's `calls:` column —
255
- # item #13's full metaprogrammed dispatch
256
- # (slice 4b), same reasoning as `reference_to_impl` above.
257
- #
258
- # Bare — no block — references another piece's own declaration,
259
- # anywhere in the chapter, not just a sibling under this same
260
- # aggregate — one level wider than round 4's own cross-entity
261
- # sharing, mirroring `AggregateBuilder#given_impl`'s own
262
- # chapter-wide shape exactly one level down. Real, live corpus
263
- # this closes: `Account::LedgerEntry` and `SafeDepositBox::Visit`
264
- # — two pieces under two different aggregates — independently
265
- # typed `given("customer is active") { parent.customer.status ==
266
- # "active" }` byte for byte; neither the aggregate-level chapter
267
- # pool (a different canonical — bare `customer.status`, the
268
- # wrong scope for a piece's own command) nor the existing
269
- # same-aggregate cross-entity pool (`@owner_named_givens`, scoped
270
- # to one aggregate's own entity tree) could reach across the
271
- # aggregate boundary. Resolved against `@chapter_entity_named_
272
- # givens`, keyed "AggregateName.EntityName" — see
273
- # `#reference_named_chapter_entity_given`'s own comment for the
274
- # algorithm and `docs/implemented/resolution-rules/
275
- # chapter-entity-given.md` for the full write-up.
276
- #
277
- # `declared_by:` is a plain string ("Account.LedgerEntry"), not a
278
- # constant — unlike `AggregateBuilder#given_impl`'s own
279
- # `declared_by:`, which names a real aggregate constant. A piece
280
- # has no first-class, independently-addressable reference
281
- # anywhere in this language (only its owning aggregate does);
282
- # inventing one to make this one argument spelling symmetrical
283
- # with the aggregate-level word is a real, separate, unscoped
284
- # feature this fix does not need — ships textual now, the same
285
- # way `admits:` shipped textual before its own constant-bridge
286
- # existed, revisited only if a genuine, separate need for
287
- # constant-addressed pieces shows up later.
288
- #
289
- # @param description [String] the rule's description; also the name a sibling piece
290
- # references it by when no block is given
291
- # @param declared_by [String, nil] disambiguates which piece's own rule to reference,
292
- # as `"Aggregate.Entity"`, when more than one shares `description`; only meaningful
293
- # with no block
294
- # @yield the predicate body; evaluated for its extracted source, never called directly
295
- # @return [void]
296
- # @raise [Bluebook::DSL::Malformed] if given a block whose source cannot be extracted;
297
- # given no block, the description is immediately ambiguous between more than one
298
- # already-loaded piece with no `declared_by` to disambiguate; an unresolved reference
299
- # defers instead, and may still raise once the whole chapter has loaded, if it then
300
- # resolves to none or more than one candidate
110
+ # Order doesn't matter: `command` only queues a descriptor here and builds for real at
111
+ # `#drain_pending!` time, after every `given` in this block has already run.
301
112
  def given_impl(description, declared_by: nil, &predicate)
302
113
  return reference_named_chapter_entity_given(description, declared_by: declared_by) unless predicate
303
114
 
304
115
  named = build_rule(Given, description, predicate, owner_name: @name, word: "given",
305
116
  extraction_failure: "its source could not be read, so no other runtime could ever evaluate it")
306
117
  @named_givens[description] = named
307
- # Write-through, first-declared-wins (`||=`) — a second piece
308
- # under the same aggregate independently declaring the exact
309
- # same description stays purely local to itself (no silent
310
- # overwrite of whatever the first piece already shared;
311
- # real, live case a fuzzer or a future codemod could easily
312
- # surface: two pieces phrasing an unrelated rule identically
313
- # by coincidence, same as an aggregate-level given already
314
- # tolerates today).
118
+ # First-declared-wins (`||=`): a second piece under the same aggregate declaring
119
+ # the exact same description independently stays local, never silently overwritten.
315
120
  @owner_named_givens[description] ||= named
316
- # **Write-through, per owner** — the chapter-wide analogue of the
317
- # line above, keyed by [description, this piece's own dotted
318
- # "Aggregate.Entity" name] rather than description alone, the
319
- # identical reasoning `AggregateBuilder#given_impl`'s own
320
- # chapter write-through gives: two different pieces (anywhere
321
- # in the chapter) independently declaring the same description
322
- # are two distinct candidates a later bare reference chooses
323
- # between (via `declared_by:` once there is more than one),
324
- # never silently merged into one slot.
121
+ # Chapter-wide analogue of the line above, keyed by "Aggregate.Entity" rather than
122
+ # description alone, so two different pieces sharing a description stay distinct
123
+ # candidates a later bare reference chooses between via `declared_by:`.
325
124
  @chapter_entity_named_givens[description] ||= {}
326
125
  @chapter_entity_named_givens[description]["#{@aggregate_name}.#{@name}"] ||= named
327
126
  end
328
127
 
329
- # A piece's own shape rule (S10, ADR 0025's own "Rules" shape,
330
- # one level down from `ValueObjectBuilder#invariant`, whose
331
- # extraction/error pattern this mirrors) — checked against
332
- # every instance of this piece the aggregate holds, not once
333
- # against the aggregate's own flat state
334
- # (`Admissibility#enforce_invariants`'s own recursive walk).
335
- # No reference-by-name form (unlike `given`) — no known corpus
336
- # need for a piece's own invariant to be shared with a sibling
337
- # piece yet; if that need shows up, it is `given`'s own
338
- # cross-entity write-through pattern to extend, not a reason to
339
- # invent a second one here speculatively.
340
- # Declares a rule every instance of this piece must satisfy.
341
- #
342
- # Answers the `invariant` word through the table's `calls:`
343
- # column — item #13's full metaprogrammed
344
- # dispatch (slice 4b), same reasoning as `given_impl` above.
345
- #
346
- # @param description [String] the rule's description
347
- # @yield the predicate body; evaluated for its extracted source, never called directly
348
- # @return [void]
349
- # @raise [Bluebook::DSL::Malformed] if the block's source could not be extracted
128
+ # Declares a rule every instance of this piece must satisfy — checked per instance,
129
+ # not once against the aggregate's own flat state. No reference-by-name form (unlike
130
+ # `given`); extend that pattern here if cross-piece sharing is ever needed.
350
131
  def invariant_impl(description, &predicate)
351
132
  @invariants << build_rule(Invariant, description, predicate, owner_name: @name, word: "invariant",
352
133
  extraction_failure: "it would be a rule the IR cannot carry")
@@ -354,11 +135,6 @@ module Hecks
354
135
 
355
136
  # Assembles the declared attributes, relationships, nested constructs and rules into an
356
137
  # `Entity`.
357
- #
358
- # @return [Bluebook::Entity] the built piece
359
- # @raise [Bluebook::DSL::Malformed] if identity resolution, a lifecycle guard on a
360
- # command with no lifecycle, a lifecycle-field mutation outside a transition, or a
361
- # synthesized closed set colliding with one the aggregate already holds fails
362
138
  def build
363
139
  drain_pending!
364
140
  resolve_pending_identity!
@@ -379,25 +155,6 @@ module Hecks
379
155
  end
380
156
 
381
157
  # Evaluates an `entity` block against a fresh builder and returns what it built.
382
- #
383
- # @param name [String] the entity's name
384
- # @param owner_value_objects [Array<Bluebook::ValueObject>] the owning aggregate's value
385
- # objects, for `identified_by` to resolve against
386
- # @param owner_named_givens [Hash{String => Bluebook::Given}] the aggregate-wide,
387
- # cross-entity given pool
388
- # @param identity_name_prefix [String, nil] the prefix a synthesized identity value
389
- # object's name takes
390
- # @param identity_value_object_installer [#call, nil] called to install a synthesized
391
- # value object onto the owning aggregate
392
- # @param aggregate_name [String, nil] the root aggregate's name, for chapter-wide given
393
- # keys
394
- # @param chapter_entity_named_givens [Hash{String => Hash{String => Bluebook::Given}}]
395
- # the chapter-wide, entity-scoped given pool
396
- # @param chapter_entity_pending_givens [Array<Hash>] unresolved chapter-wide bare given
397
- # references
398
- # @yield the entity body, evaluated with the builder as `self`; may be omitted
399
- # @return [Bluebook::Entity] the built piece
400
- # @raise [Bluebook::DSL::Malformed] if the body fails any check `#build` raises
401
158
  def self.build(name, owner_value_objects: [], owner_named_givens: {},
402
159
  identity_name_prefix: nil, identity_value_object_installer: nil,
403
160
  aggregate_name: nil, chapter_entity_named_givens: {}, chapter_entity_pending_givens: [], &block)
@@ -413,28 +170,9 @@ module Hecks
413
170
 
414
171
  private
415
172
 
416
- # Primitive 2 (RuleReference#resolve_owner_keyed) — the chapter-
417
- # wide, entity-scoped analogue of `AggregateBuilder#
418
- # reference_named_chapter_given`; the three branches below are
419
- # this construct's own refusal wording, not shared, matching that
420
- # method's own precedent (`declared_by:` only exists on `given`
421
- # so far, at either scope). Unresolved is deferred, not raised
422
- # here — see `#pending_chapter_entity_given`, below.
423
- #
424
- # **Writes through to `@owner_named_givens` too** — not just
425
- # `@named_givens` — or this piece resolving a description via the
426
- # wider, chapter pool would leave the narrower, same-aggregate
427
- # pool (`EntityBuilder#given_impl`'s own block-form write-through)
428
- # never populated for this description, breaking any sibling
429
- # piece's existing command-level bare reference
430
- # (`CommandBuilder#reference_named_given`) that depends on it —
431
- # real, live corpus: `SafeDepositBox::KeyIssuance.Return`'s own
432
- # bare `given("customer is active")` resolves through
433
- # `@owner_named_givens`, populated by `Visit`'s declaration
434
- # whether `Visit` types the predicate itself or (now) references
435
- # `Account::LedgerEntry`'s instead — this write keeps that
436
- # working unchanged either way, `||=` so nothing here overrides
437
- # an actual local declaration if one is ever added later.
173
+ # Resolves a bare `given` reference against the chapter-wide, entity-scoped pool.
174
+ # Also writes through to `@owner_named_givens`, not just `@named_givens` — otherwise a
175
+ # sibling piece's own same-aggregate bare reference would never see this resolution.
438
176
  def reference_named_chapter_entity_given(description, declared_by:)
439
177
  verify_resolves_via!("given", "Entity", "owner_keyed")
440
178
  candidates = resolve_owner_keyed(@chapter_entity_named_givens, description)
@@ -459,14 +197,9 @@ module Hecks
459
197
  @owner_named_givens[description] ||= named
460
198
  end
461
199
 
462
- # A chapter may be split across files — the identical reason
463
- # `AggregateBuilder#pending_chapter_given` defers rather than
464
- # raising the moment a bare reference outruns what's loaded so
465
- # far. Hands back a placeholder `Given`, embedded by Ruby object
466
- # reference in this piece's own `preconditions`, and queues the
467
- # request in `@chapter_entity_pending_givens` —
468
- # `BluebookBuilder#resolve_pending_chapter_entity_givens!`
469
- # mutates it in place once every file in the chapter has loaded.
200
+ # A chapter may be split across files, so an unresolved bare reference defers rather
201
+ # than raising immediately; `BluebookBuilder#resolve_pending_chapter_entity_givens!`
202
+ # fills in the placeholder once every file in the chapter has loaded.
470
203
  def pending_chapter_entity_given(description, declared_by:)
471
204
  placeholder = Given.new(description: description, canonical: nil, predicate: nil)
472
205
  @chapter_entity_pending_givens << { entity: "#{@aggregate_name}.#{@name}", description: description,
@@ -474,23 +207,10 @@ module Hecks
474
207
  placeholder
475
208
  end
476
209
 
477
- # A piece's own `one_of` lands on its aggregate. A type-position
478
- # `one_of("never_moved", "moved")` on an entity attribute
479
- # synthesizes a closed-set value object — and until this, that
480
- # object was built and then dropped: `Entity.declare` carries no
481
- # value objects, so the synthesized set existed nowhere in the
482
- # finished graph. The attribute stayed typed "Moved" with nothing
483
- # to resolve it: runtime admission had no closed set to enforce
484
- # (the one_of was decorative), and the fuzzer's ValueGenerator
485
- # crashed every run on the first domain to declare one — a chess
486
- # King/Rook's own castling flag — with `does not know primitive
487
- # type "Moved"`. Installed through the same hook an entity's own
488
- # identity value object already rides to the aggregate
489
- # (`identity_value_object_installer`, threaded unchanged through
490
- # nested pieces). Two sibling pieces synthesizing the same set
491
- # (King's and Rook's own `moved`) install it once; the same name
492
- # with a different member list is refused as the collision it is,
493
- # never first-wins silently.
210
+ # A piece's own `one_of` synthesizes a closed-set value object, installed onto the
211
+ # owning aggregate so the runtime has it to admit against — not just on the attribute.
212
+ # Two sibling pieces synthesizing the same name install it once; a name collision with
213
+ # a different member list is refused rather than silently kept.
494
214
  def install_closed_sets!
495
215
  return unless @identity_value_object_installer
496
216
 
@@ -508,10 +228,8 @@ module Hecks
508
228
  end
509
229
  end
510
230
 
511
- # See `AggregateBuilder#drain_pending!`'s own comment — the
512
- # identical mechanism, one level down. Entities first and fully
513
- # built (so a nested command's own `append:` resolution can read
514
- # a sibling piece's `.attributes`), then commands, then queries.
231
+ # Entities are built first, fully, so a nested command's own `append:` can read a
232
+ # sibling piece's `.attributes`; then commands, then queries.
515
233
  def drain_pending!
516
234
  @entities = @pending_entities.map do |name, block|
517
235
  EntityBuilder.build(name, owner_value_objects: @owner_value_objects,
@@ -536,14 +254,12 @@ module Hecks
536
254
  end
537
255
  end
538
256
 
539
- # See `AggregateBuilder#seal_lifecycle_guards`'s own comment —
540
- # the identical check, one level down.
257
+ # Refuses a command that sets the lifecycle field directly, or guards `from:` with no
258
+ # lifecycle declared — a lifecycle field only moves by transition.
541
259
  def seal_lifecycle_guards
542
260
  @commands.each do |command|
543
261
  if @lifecycle && !MetaValidator.shadow_parsing?
544
- # C5.3 — the same refusal `AggregateBuilder::Sealing` gives
545
- # an aggregate: a `sets` on the lifecycle field (frozen era
546
- # text excepted, as there).
262
+ # `delegate`/`corrects` are exempt — the frozen-era-text case, not a live mutation.
547
263
  command.mutations.each do |mutation|
548
264
  next if [:delegate, :corrects].include?(mutation.op)
549
265
  next unless mutation.target.to_sym == @lifecycle.field.to_sym
@@ -563,10 +279,8 @@ module Hecks
563
279
  end
564
280
  end
565
281
 
566
- # `identified_by`'s own resolution pool (AttributeCollector#resolve_
567
- # pending_identity!'s hook, S9) — a piece mints no value objects of
568
- # its own, so a bare field's own type resolves against its owner
569
- # aggregate's, passed in at declaration (`AggregateBuilder#entity`).
282
+ # A piece mints no value objects of its own, so `identified_by` resolves a bare field's
283
+ # type against the owner aggregate's pool, passed in at declaration.
570
284
  def identity_pool = @owner_value_objects
571
285
 
572
286
  def identity_value_object_name = "#{@identity_name_prefix}Identity"