hecks 1.3.0 → 1.4.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 (355) hide show
  1. checksums.yaml +4 -4
  2. data/lib/hecks/adapters/driven/claude_code.rb +7 -7
  3. data/lib/hecks/adapters/driven/d1.rb +187 -23
  4. data/lib/hecks/adapters/driven/folder.rb +10 -10
  5. data/lib/hecks/adapters/driven/google_authentication.rb +8 -8
  6. data/lib/hecks/adapters/driven/governance_authorization.rb +31 -13
  7. data/lib/hecks/adapters/driven/heki/journal.rb +5 -4
  8. data/lib/hecks/adapters/driven/heki/saga_store.rb +5 -5
  9. data/lib/hecks/adapters/driven/heki.rb +13 -7
  10. data/lib/hecks/adapters/driven/identity_registry.rb +2 -2
  11. data/lib/hecks/adapters/driven/in_memory_ordering.rb +3 -3
  12. data/lib/hecks/adapters/driven/lambda/client.rb +34 -9
  13. data/lib/hecks/adapters/driven/lambda.rb +39 -33
  14. data/lib/hecks/adapters/driven/local_storage.rb +17 -10
  15. data/lib/hecks/adapters/driven/memory.rb +205 -9
  16. data/lib/hecks/adapters/driven/mock_stripe_adapter.rb +1 -1
  17. data/lib/hecks/adapters/driven/postgres/codec.rb +27 -11
  18. data/lib/hecks/adapters/driven/postgres/outbox.rb +40 -2
  19. data/lib/hecks/adapters/driven/postgres/reconnect.rb +23 -7
  20. data/lib/hecks/adapters/driven/postgres/schema_builder.rb +14 -14
  21. data/lib/hecks/adapters/driven/postgres.rb +175 -28
  22. data/lib/hecks/adapters/driven/prism.rb +4 -4
  23. data/lib/hecks/adapters/driven/sql_query_builder.rb +34 -22
  24. data/lib/hecks/adapters/driven/sqlite/codec.rb +38 -10
  25. data/lib/hecks/adapters/driven/sqlite/projection.rb +60 -32
  26. data/lib/hecks/adapters/driven/sqlite/schema_builder.rb +12 -12
  27. data/lib/hecks/adapters/driven/sqlite.rb +181 -21
  28. data/lib/hecks/adapters/driven.rb +4 -4
  29. data/lib/hecks/adapters/driving/github_webhook.rb +18 -18
  30. data/lib/hecks/behaviors/dsl.rb +2 -2
  31. data/lib/hecks/behaviors/expectations.rb +23 -23
  32. data/lib/hecks/behaviors/ir.rb +1 -1
  33. data/lib/hecks/behaviors/rspec.rb +1 -1
  34. data/lib/hecks/behaviors/runner.rb +2 -2
  35. data/lib/hecks/behaviors.rb +1 -1
  36. data/lib/hecks/bluebook/aggregate.rb +13 -13
  37. data/lib/hecks/bluebook/assembly/aggregate_assembly.rb +10 -10
  38. data/lib/hecks/bluebook/assembly/build.rb +1 -1
  39. data/lib/hecks/bluebook/assembly/contract.rb +39 -16
  40. data/lib/hecks/bluebook/assembly/contracts.rb +40 -38
  41. data/lib/hecks/bluebook/assembly/marks.rb +18 -18
  42. data/lib/hecks/bluebook/assembly/specializer.rb +19 -21
  43. data/lib/hecks/bluebook/assembly.rb +9 -9
  44. data/lib/hecks/bluebook/attribute.rb +9 -9
  45. data/lib/hecks/bluebook/behaviour/aggregate.rb +11 -11
  46. data/lib/hecks/bluebook/behaviour/attribute.rb +5 -5
  47. data/lib/hecks/bluebook/behaviour/chapter.rb +23 -5
  48. data/lib/hecks/bluebook/behaviour/command.rb +23 -23
  49. data/lib/hecks/bluebook/behaviour/domain_port.rb +7 -7
  50. data/lib/hecks/bluebook/behaviour/entity.rb +8 -8
  51. data/lib/hecks/bluebook/behaviour/hexagon.rb +4 -4
  52. data/lib/hecks/bluebook/behaviour/lifecycle.rb +5 -5
  53. data/lib/hecks/bluebook/behaviour/policy.rb +12 -12
  54. data/lib/hecks/bluebook/behaviour/process_manager.rb +7 -7
  55. data/lib/hecks/bluebook/behaviour/query.rb +1 -1
  56. data/lib/hecks/bluebook/behaviour/read_model.rb +8 -8
  57. data/lib/hecks/bluebook/behaviour/traits.rb +12 -12
  58. data/lib/hecks/bluebook/behaviour/value_object.rb +6 -6
  59. data/lib/hecks/bluebook/capabilities.rb +27 -0
  60. data/lib/hecks/bluebook/chapter.rb +28 -9
  61. data/lib/hecks/bluebook/command.rb +12 -12
  62. data/lib/hecks/bluebook/domain_port.rb +9 -9
  63. data/lib/hecks/bluebook/dsl/adapter_builder.rb +24 -0
  64. data/lib/hecks/bluebook/dsl/aggregate_builder/sealing.rb +49 -49
  65. data/lib/hecks/bluebook/dsl/aggregate_builder.rb +96 -96
  66. data/lib/hecks/bluebook/dsl/attribute_collector.rb +41 -41
  67. data/lib/hecks/bluebook/dsl/binding_proxy.rb +22 -2
  68. data/lib/hecks/bluebook/dsl/bluebook_builder/validation.rb +111 -74
  69. data/lib/hecks/bluebook/dsl/bluebook_builder.rb +48 -30
  70. data/lib/hecks/bluebook/dsl/bootstrap_table.rb +116 -0
  71. data/lib/hecks/bluebook/dsl/command_builder.rb +103 -103
  72. data/lib/hecks/bluebook/dsl/const_shim.rb +46 -15
  73. data/lib/hecks/bluebook/dsl/domain_port_builder.rb +90 -25
  74. data/lib/hecks/bluebook/dsl/entity_builder.rb +56 -56
  75. data/lib/hecks/bluebook/dsl/generic_dispatch.rb +148 -132
  76. data/lib/hecks/bluebook/dsl/hecksagon_builder.rb +89 -30
  77. data/lib/hecks/bluebook/dsl/identity_declaration.rb +17 -17
  78. data/lib/hecks/bluebook/dsl/lifecycle_builder.rb +27 -4
  79. data/lib/hecks/bluebook/dsl/policy_builder.rb +30 -21
  80. data/lib/hecks/bluebook/dsl/port_builder.rb +38 -7
  81. data/lib/hecks/bluebook/dsl/port_operation_builder.rb +56 -22
  82. data/lib/hecks/bluebook/dsl/process_manager_builder.rb +35 -35
  83. data/lib/hecks/bluebook/dsl/query_builder.rb +5 -5
  84. data/lib/hecks/bluebook/dsl/read_model_builder.rb +34 -34
  85. data/lib/hecks/bluebook/dsl/rule_reference.rb +41 -39
  86. data/lib/hecks/bluebook/dsl/translation_builder.rb +9 -9
  87. data/lib/hecks/bluebook/dsl/value_object_builder.rb +16 -16
  88. data/lib/hecks/bluebook/dsl/word_gate.rb +59 -53
  89. data/lib/hecks/bluebook/dsl/world_builder.rb +51 -8
  90. data/lib/hecks/bluebook/entity.rb +11 -11
  91. data/lib/hecks/bluebook/expression/ast_json.rb +20 -20
  92. data/lib/hecks/bluebook/expression/ast_reader.rb +3 -3
  93. data/lib/hecks/bluebook/expression/canonical_form.rb +9 -9
  94. data/lib/hecks/bluebook/expression/evaluator.rb +18 -18
  95. data/lib/hecks/bluebook/expression/resolver/block_predicates.rb +18 -18
  96. data/lib/hecks/bluebook/expression/resolver.rb +60 -62
  97. data/lib/hecks/bluebook/hexagon.rb +1 -1
  98. data/lib/hecks/bluebook/lifecycle.rb +1 -1
  99. data/lib/hecks/bluebook/meta_validator/adapter_judge.rb +1 -1
  100. data/lib/hecks/bluebook/meta_validator/judge.rb +101 -87
  101. data/lib/hecks/bluebook/meta_validator/plan.rb +39 -39
  102. data/lib/hecks/bluebook/meta_validator/port_judge.rb +2 -2
  103. data/lib/hecks/bluebook/meta_validator/readings.rb +43 -43
  104. data/lib/hecks/bluebook/meta_validator/reconstruction.rb +44 -37
  105. data/lib/hecks/bluebook/meta_validator/shapes.rb +25 -21
  106. data/lib/hecks/bluebook/meta_validator/syntax_boot.rb +145 -31
  107. data/lib/hecks/bluebook/meta_validator/translation_judge.rb +6 -6
  108. data/lib/hecks/bluebook/meta_validator/world_judge.rb +5 -5
  109. data/lib/hecks/bluebook/meta_validator.rb +70 -70
  110. data/lib/hecks/bluebook/model_check.rb +170 -84
  111. data/lib/hecks/bluebook/pattern_subset.rb +9 -9
  112. data/lib/hecks/bluebook/policy.rb +15 -13
  113. data/lib/hecks/bluebook/process_manager.rb +14 -14
  114. data/lib/hecks/bluebook/project_register.rb +6 -6
  115. data/lib/hecks/bluebook/query.rb +4 -4
  116. data/lib/hecks/bluebook/read_model.rb +14 -14
  117. data/lib/hecks/bluebook/reference.rb +8 -8
  118. data/lib/hecks/bluebook/smoke_test.rb +19 -19
  119. data/lib/hecks/bluebook/synthesizer.rb +12 -12
  120. data/lib/hecks/bluebook/translation.rb +4 -4
  121. data/lib/hecks/bluebook/value_object.rb +6 -6
  122. data/lib/hecks/bluebook.rb +2 -2
  123. data/lib/hecks/codemod/legacy_dispatch_args.rb +299 -0
  124. data/lib/hecks/codemod/legacy_dispatch_recorder.rb +186 -0
  125. data/lib/hecks/codemod.rb +36 -35
  126. data/lib/hecks/construct.rb +6 -6
  127. data/lib/hecks/corpus.rb +317 -0
  128. data/lib/hecks/deprecation.rb +95 -0
  129. data/lib/hecks/doc/reference.rb +19 -19
  130. data/lib/hecks/embryonaut_bluebook.rb +11 -11
  131. data/lib/hecks/facade/cli_door.rb +69 -10
  132. data/lib/hecks/facade/cli_runner.rb +105 -24
  133. data/lib/hecks/facade/command_request.rb +23 -0
  134. data/lib/hecks/facade/handle.rb +79 -32
  135. data/lib/hecks/facade/json_door.rb +106 -25
  136. data/lib/hecks/facade/surface/aggregate_door.rb +42 -27
  137. data/lib/hecks/facade/surface/chapter.rb +26 -17
  138. data/lib/hecks/facade/surface.rb +16 -3
  139. data/lib/hecks/facade.rb +15 -4
  140. data/lib/hecks/forms/app.rb +46 -30
  141. data/lib/hecks/forms/command_form_renderer.rb +70 -9
  142. data/lib/hecks/forms/field_renderer.rb +142 -6
  143. data/lib/hecks/forms/field_shape.rb +180 -19
  144. data/lib/hecks/forms/html.rb +51 -7
  145. data/lib/hecks/forms/index_renderer.rb +14 -2
  146. data/lib/hecks/forms/params.rb +120 -23
  147. data/lib/hecks/forms/port_argument.rb +2 -2
  148. data/lib/hecks/forms/query_form_renderer.rb +2 -2
  149. data/lib/hecks/forms/record_renderer.rb +2 -2
  150. data/lib/hecks/forms/record_table.rb +1 -1
  151. data/lib/hecks/forms/value_object_shape.rb +3 -3
  152. data/lib/hecks/forms.rb +24 -4
  153. data/lib/hecks/fqn.rb +1 -1
  154. data/lib/hecks/framework/bluebook/governance.bluebook +9 -0
  155. data/lib/hecks/framework.rb +48 -17
  156. data/lib/hecks/freezer.rb +11 -11
  157. data/lib/hecks/fuzzing/bounded_exhaustive_expressions.rb +90 -90
  158. data/lib/hecks/fuzzing/combination_miner.rb +119 -0
  159. data/lib/hecks/fuzzing/concurrent_dispatch.rb +140 -45
  160. data/lib/hecks/fuzzing/coverage_campaign.rb +118 -0
  161. data/lib/hecks/fuzzing/differential.rb +158 -0
  162. data/lib/hecks/fuzzing/domain_generator.rb +694 -0
  163. data/lib/hecks/fuzzing/era_boundary.rb +37 -18
  164. data/lib/hecks/fuzzing/form_census.rb +35 -20
  165. data/lib/hecks/fuzzing/generated_domain_check.rb +95 -0
  166. data/lib/hecks/fuzzing/invalid_value_generator.rb +6 -6
  167. data/lib/hecks/fuzzing/isolated_boot.rb +62 -62
  168. data/lib/hecks/fuzzing/nondeterministic.rb +67 -0
  169. data/lib/hecks/fuzzing/persistence_parity.rb +19 -21
  170. data/lib/hecks/fuzzing/properties/corrections.rb +9 -9
  171. data/lib/hecks/fuzzing/properties/dispatch_and_mutations.rb +154 -49
  172. data/lib/hecks/fuzzing/properties/guards.rb +42 -42
  173. data/lib/hecks/fuzzing/properties/invariants_and_aggregation.rb +32 -32
  174. data/lib/hecks/fuzzing/properties/lifecycle_and_replay.rb +22 -35
  175. data/lib/hecks/fuzzing/properties/outbox.rb +24 -24
  176. data/lib/hecks/fuzzing/properties/querying.rb +17 -17
  177. data/lib/hecks/fuzzing/properties.rb +64 -40
  178. data/lib/hecks/fuzzing/qa_settings.rb +152 -0
  179. data/lib/hecks/fuzzing/replay.rb +114 -114
  180. data/lib/hecks/fuzzing/rotation_priority.rb +10 -10
  181. data/lib/hecks/fuzzing/rust_gap_manifest.rb +113 -0
  182. data/lib/hecks/fuzzing/self_consistency.rb +141 -112
  183. data/lib/hecks/fuzzing/sequence_generator/adversary.rb +35 -35
  184. data/lib/hecks/fuzzing/sequence_generator/catalog.rb +18 -11
  185. data/lib/hecks/fuzzing/sequence_generator/outcome_tracker.rb +13 -12
  186. data/lib/hecks/fuzzing/sequence_generator/picker.rb +21 -12
  187. data/lib/hecks/fuzzing/sequence_generator/step_builder.rb +58 -31
  188. data/lib/hecks/fuzzing/sequence_generator.rb +111 -23
  189. data/lib/hecks/fuzzing/shrinker.rb +197 -0
  190. data/lib/hecks/fuzzing/structural_skips.rb +23 -130
  191. data/lib/hecks/fuzzing/sweep_depth.rb +4 -4
  192. data/lib/hecks/fuzzing/target_capabilities.rb +49 -18
  193. data/lib/hecks/fuzzing/value_generator.rb +14 -14
  194. data/lib/hecks/fuzzing.rb +5 -0
  195. data/lib/hecks/grammar/evolve.rb +10 -10
  196. data/lib/hecks/grammar.rb +7 -7
  197. data/lib/hecks/ir.rb +13 -13
  198. data/lib/hecks/language/bluebook/bluebook.bluebook +41 -0
  199. data/lib/hecks/language/bluebook/policy.bluebook +11 -1
  200. data/lib/hecks/language/bluebook/vocabulary.bluebook +348 -13
  201. data/lib/hecks/language/oidc.json +5 -0
  202. data/lib/hecks/literal.rb +9 -9
  203. data/lib/hecks/naming.rb +25 -25
  204. data/lib/hecks/ports/access_control.rb +58 -2
  205. data/lib/hecks/ports/agent/answers.rb +83 -6
  206. data/lib/hecks/ports/agent.rb +119 -35
  207. data/lib/hecks/ports/authentication.rb +44 -4
  208. data/lib/hecks/ports/authorization.rb +53 -11
  209. data/lib/hecks/ports/clock.rb +42 -23
  210. data/lib/hecks/ports/extraction.rb +16 -0
  211. data/lib/hecks/ports/identity_assignment.rb +24 -2
  212. data/lib/hecks/ports/identity_generation.rb +17 -3
  213. data/lib/hecks/ports/identity_resolution.rb +18 -1
  214. data/lib/hecks/ports/loading.rb +4 -0
  215. data/lib/hecks/ports/persistence/append_only.rb +172 -8
  216. data/lib/hecks/ports/persistence/binding_policy.rb +34 -0
  217. data/lib/hecks/ports/persistence/codec_boundary.rb +178 -0
  218. data/lib/hecks/ports/persistence/execution.rb +4 -0
  219. data/lib/hecks/ports/persistence/null_saga_store.rb +12 -1
  220. data/lib/hecks/ports/persistence/plugin.rb +42 -4
  221. data/lib/hecks/ports/persistence/plugins/era/era_check.rb +218 -25
  222. data/lib/hecks/ports/persistence/plugins/era/era_guard/shape_diff.rb +77 -9
  223. data/lib/hecks/ports/persistence/plugins/era/era_guard.rb +81 -24
  224. data/lib/hecks/ports/persistence/plugins/era/era_tamper.rb +29 -18
  225. data/lib/hecks/ports/persistence/plugins/era/lineage.rb +144 -60
  226. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/era_store.rb +103 -8
  227. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/field_cache.rb +98 -23
  228. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/head_compiler.rb +282 -109
  229. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/mint_transaction.rb +63 -25
  230. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/provisioning.rb +118 -66
  231. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/resumable_backfill.rb +51 -28
  232. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/tail_merge.rb +28 -5
  233. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage/transform_installer.rb +25 -12
  234. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage.rb +129 -34
  235. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/coverage_check.rb +51 -6
  236. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/era_resolver.rb +33 -9
  237. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/merge_coordinator.rb +16 -0
  238. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager/minter.rb +57 -4
  239. data/lib/hecks/ports/persistence/plugins/era/postgres_era/lineage_manager.rb +25 -2
  240. data/lib/hecks/ports/persistence/plugins/era/postgres_era.rb +314 -90
  241. data/lib/hecks/ports/persistence/plugins/era/storage_shape.rb +68 -10
  242. data/lib/hecks/ports/persistence/plugins/era/translation/audit/approval_digest.rb +9 -3
  243. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_one.rb +9 -2
  244. data/lib/hecks/ports/persistence/plugins/era/translation/audit/layer_two.rb +42 -8
  245. data/lib/hecks/ports/persistence/plugins/era/translation/audit/unfed_report.rb +16 -1
  246. data/lib/hecks/ports/persistence/plugins/era/translation/audit.rb +36 -5
  247. data/lib/hecks/ports/persistence/plugins/era/translation/reattest.rb +23 -3
  248. data/lib/hecks/ports/persistence/plugins/era/translation/rule_compiler.rb +18 -19
  249. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/differ.rb +5 -5
  250. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold/writer.rb +1 -1
  251. data/lib/hecks/ports/persistence/plugins/era/translation/scaffold.rb +2 -2
  252. data/lib/hecks/ports/persistence/plugins/era.rb +12 -2
  253. data/lib/hecks/ports/persistence/remote_runtime.rb +9 -2
  254. data/lib/hecks/ports/persistence/repository_factory.rb +23 -3
  255. data/lib/hecks/ports/persistence/state_codec.rb +319 -0
  256. data/lib/hecks/ports/persistence.rb +36 -1
  257. data/lib/hecks/ports/projection.rb +61 -7
  258. data/lib/hecks/ports/query/in_memory.rb +3 -3
  259. data/lib/hecks/ports/query/ordering.rb +6 -6
  260. data/lib/hecks/ports/query.rb +35 -0
  261. data/lib/hecks/projections/bootstrap_table.rb +112 -0
  262. data/lib/hecks/projections/diagrams.rb +75 -75
  263. data/lib/hecks/projections/glossary/html.rb +3 -3
  264. data/lib/hecks/projections/glossary/markdown.rb +3 -3
  265. data/lib/hecks/projections/glossary/mermaid.rb +1 -1
  266. data/lib/hecks/projections/glossary/sections.rb +1 -1
  267. data/lib/hecks/projections/glossary/sentences.rb +5 -5
  268. data/lib/hecks/projections/glossary.rb +15 -15
  269. data/lib/hecks/projections/ir.rb +1 -1
  270. data/lib/hecks/projections/model/deviations.rb +18 -17
  271. data/lib/hecks/projections/model.rb +25 -21
  272. data/lib/hecks/projections/oidc.rb +7 -7
  273. data/lib/hecks/projections/parser_table.rb +5 -5
  274. data/lib/hecks/projections/reference.rb +3 -3
  275. data/lib/hecks/projections/rust_vocabulary.rb +443 -0
  276. data/lib/hecks/projections/shape.rb +2 -2
  277. data/lib/hecks/projections/statements.rb +11 -11
  278. data/lib/hecks/projections/vocabulary.rb +9 -9
  279. data/lib/hecks/projections.rb +5 -3
  280. data/lib/hecks/projector/cli_projector.rb +29 -29
  281. data/lib/hecks/projector/docs_projector.rb +13 -13
  282. data/lib/hecks/projector/exporter.rb +42 -21
  283. data/lib/hecks/projector/ir_projector.rb +1 -1
  284. data/lib/hecks/projector/narrate_projector.rb +11 -11
  285. data/lib/hecks/projector/target.rb +13 -13
  286. data/lib/hecks/projector.rb +15 -15
  287. data/lib/hecks/query_ir.rb +47 -47
  288. data/lib/hecks/query_specification/common/comparators.rb +19 -3
  289. data/lib/hecks/query_specification/common/comparison.rb +109 -27
  290. data/lib/hecks/query_specification/common/dsl.rb +65 -9
  291. data/lib/hecks/query_specification/common/null_policy.rb +57 -13
  292. data/lib/hecks/query_specification/common/null_semantics.rb +4 -0
  293. data/lib/hecks/query_specification/common/options.rb +25 -0
  294. data/lib/hecks/query_specification/field_path.rb +69 -15
  295. data/lib/hecks/query_specification/hop_path.rb +57 -20
  296. data/lib/hecks/query_specification/read_model/specification.rb +4 -0
  297. data/lib/hecks/rendering.rb +3 -3
  298. data/lib/hecks/router/namespace_installer.rb +3 -3
  299. data/lib/hecks/router.rb +1 -1
  300. data/lib/hecks/runtime/aggregate_lock.rb +11 -11
  301. data/lib/hecks/runtime/boot_gates.rb +3 -3
  302. data/lib/hecks/runtime/caller.rb +8 -8
  303. data/lib/hecks/runtime/capability_graph.rb +2 -2
  304. data/lib/hecks/runtime/command_interpreter/argument_gate.rb +22 -25
  305. data/lib/hecks/runtime/command_interpreter/mutation_applier.rb +42 -63
  306. data/lib/hecks/runtime/command_interpreter.rb +159 -102
  307. data/lib/hecks/runtime/command_rules/admissibility.rb +69 -69
  308. data/lib/hecks/runtime/command_rules/arithmetic.rb +137 -91
  309. data/lib/hecks/runtime/command_rules/authorization.rb +38 -17
  310. data/lib/hecks/runtime/command_rules/emission.rb +18 -1
  311. data/lib/hecks/runtime/command_rules/references.rb +35 -35
  312. data/lib/hecks/runtime/command_rules.rb +3 -0
  313. data/lib/hecks/runtime/dependency_planning.rb +11 -11
  314. data/lib/hecks/runtime/dispatcher.rb +283 -90
  315. data/lib/hecks/runtime/entity_element.rb +151 -67
  316. data/lib/hecks/runtime/entity_interpreter.rb +108 -82
  317. data/lib/hecks/runtime/errors.rb +19 -19
  318. data/lib/hecks/runtime/event.rb +6 -6
  319. data/lib/hecks/runtime/identity.rb +22 -22
  320. data/lib/hecks/runtime/instance.rb +39 -14
  321. data/lib/hecks/runtime/interpreting.rb +12 -12
  322. data/lib/hecks/runtime/invocation.rb +276 -0
  323. data/lib/hecks/runtime/loader.rb +14 -14
  324. data/lib/hecks/runtime/outbox.rb +23 -23
  325. data/lib/hecks/runtime/policy_interpreter.rb +54 -54
  326. data/lib/hecks/runtime/port_operation_interpreter.rb +22 -19
  327. data/lib/hecks/runtime/query_interpreter.rb +55 -64
  328. data/lib/hecks/runtime/reaction_invocation.rb +20 -20
  329. data/lib/hecks/runtime/read_model_interpreter.rb +40 -40
  330. data/lib/hecks/runtime/rebuild_sweep.rb +4 -4
  331. data/lib/hecks/runtime/reference_hop.rb +6 -6
  332. data/lib/hecks/runtime/refusal_wording.rb +92 -115
  333. data/lib/hecks/runtime/registry/saga_persistence.rb +21 -21
  334. data/lib/hecks/runtime/registry/verification.rb +36 -26
  335. data/lib/hecks/runtime/registry.rb +45 -28
  336. data/lib/hecks/runtime/remote_dispatcher.rb +38 -23
  337. data/lib/hecks/runtime/routing.rb +10 -153
  338. data/lib/hecks/runtime/saga_interpreter/correlation.rb +17 -17
  339. data/lib/hecks/runtime/saga_interpreter.rb +64 -64
  340. data/lib/hecks/runtime/saga_pending_dispatch.rb +12 -12
  341. data/lib/hecks/runtime/tenant_check.rb +9 -9
  342. data/lib/hecks/runtime/tenant_scope.rb +5 -5
  343. data/lib/hecks/runtime/value/admission.rb +75 -30
  344. data/lib/hecks/runtime/value/coercion.rb +318 -127
  345. data/lib/hecks/runtime/value/entity_list_coercion.rb +34 -34
  346. data/lib/hecks/runtime/value.rb +21 -21
  347. data/lib/hecks/runtime.rb +7 -7
  348. data/lib/hecks/storehouse.rb +64 -64
  349. data/lib/hecks/version.rb +3 -3
  350. data/lib/hecks/vocabulary.rb +205 -4
  351. data/lib/hecks.rb +13 -11
  352. data/lib/rubocop/cop/hecks/fallback_hash_lookup.rb +11 -11
  353. data/lib/rubocop/cop/hecks/sequential_hash_rename_in_loop.rb +14 -12
  354. data/lib/rubocop/cop/hecks/thread_shared_ivar_mutation.rb +11 -11
  355. metadata +22 -2
@@ -1,35 +1,37 @@
1
+ require_relative "bootstrap_table"
2
+
1
3
  module Hecks
2
4
  module Bluebook
3
5
  module DSL
4
- # THE THREE RESOLUTION PRIMITIVES the S10 given/invariant family's
6
+ # The three resolution primitives the S10 given/invariant family's
5
7
  # own "declared once, referenced by name" mechanism (ADR 0025)
6
8
  # reduces to, at every scope this language has grown one so far
7
9
  # (a command referencing its owner or a sibling piece's entity-wide
8
10
  # pool; an aggregate referencing another aggregate chapter-wide; a
9
11
  # value object referencing a sibling value object on the same
10
- # aggregate) — extracted here, once, so the NEXT scope this family
12
+ # aggregate) — extracted here, once, so the next scope this family
11
13
  # widens to (there will be one — see docs/resolution-rules/
12
14
  # chapter-given.md's own "Known limitations" for two already named)
13
15
  # reuses one of these three shapes instead of a fourth hand-written
14
16
  # near-duplicate resolver.
15
17
  #
16
- # NOT ONE UNIFIED ALGORITHM — a real design question this file
17
- # answers directly: the THREE existing resolvers are not
18
- # superficially different, they are STRUCTURALLY different (a
19
- # multi-pool fallback CHAIN; ONE pool keyed by declaring OWNER,
20
- # needing disambiguation; a LIVE SCAN over already-built sibling
18
+ # **Not one unified algorithm** — a real design question this file
19
+ # answers directly: the three existing resolvers are not
20
+ # superficially different, they are structurally different (a
21
+ # multi-pool fallback chain; one pool keyed by declaring owner,
22
+ # needing disambiguation; a live scan over already-built sibling
21
23
  # objects with no separate pool at all) — forcing them into one
22
24
  # shape would be a real behavior change (see `#lookup`, below, for
23
25
  # which construct uses which), not the pure internal refactor this
24
- # module is. `build_rule` is the one piece that WAS genuinely
26
+ # module is. `build_rule` is the one piece that was genuinely
25
27
  # identical across all 7 declaring methods (`given`×3,
26
28
  # `invariant`×3, `ensures`×1) before this file existed — extract
27
29
  # predicate source, refuse if extraction failed, build the struct.
28
30
  #
29
- # `#lookup`/`#verify_resolves_via!` read WHICH construct uses which
31
+ # `#lookup`/`#verify_resolves_via!` read which construct uses which
30
32
  # primitive off the self-hosted grammar table itself
31
33
  # (`Keyword#resolves_via`, `syntax.bluebook`) — not a Ruby-only
32
- # Hash cross-checked afterward (this file's OWN earlier shape, one
34
+ # Hash cross-checked afterward (this file's own earlier shape, one
33
35
  # round ago) — so a real domain's own boot, not just `bundle exec
34
36
  # rspec`, fails loudly the moment the table and this file's own
35
37
  # hand-written resolution methods disagree.
@@ -39,14 +41,14 @@ module Hecks
39
41
  # `struct_class` is `Given` or `Invariant` (both `Struct.new(
40
42
  # :description, :canonical, :predicate, keyword_init: true)` —
41
43
  # `Given` lives in command.rb, `Invariant` in value_object.rb).
42
- # `owner_name`/`word` are ONLY for the refusal message's own
44
+ # `owner_name`/`word` are only for the refusal message's own
43
45
  # wording. `extraction_failure` is the tail of that same
44
- # message, and stays a REQUIRED parameter rather than one
46
+ # message, and stays a required parameter rather than one
45
47
  # hardcoded string on purpose — `given` ("its source could not
46
48
  # be read, so no other runtime could ever evaluate it"),
47
49
  # `invariant` ("it would be a rule the IR cannot carry"), and
48
50
  # `ensures` ("a postcondition is carried as text, and this one
49
- # has none") each already had their OWN exact wording before
51
+ # has none") each already had their own exact wording before
50
52
  # this method existed; unifying them into one generic sentence
51
53
  # would be a real (if small) behavior change this refactor is
52
54
  # not making.
@@ -64,9 +66,9 @@ module Hecks
64
66
  struct_class.new(description: description, canonical: canonical, predicate: predicate, ast: ast)
65
67
  end
66
68
 
67
- # PRIMITIVE 1 — an ORDERED CHAIN of flat `Hash[description] =>
69
+ # Primitive 1 — an ordered chain of flat `Hash[description] =>
68
70
  # Rule` pools, first match wins. `CommandBuilder#given`'s own
69
- # two-pool shape (its OWN owner's `named_givens`, then a sibling
71
+ # two-pool shape (its own owner's `named_givens`, then a sibling
70
72
  # piece's entity-wide pool) is this with a 2-element chain — a
71
73
  # future single-pool bare reference is the same primitive with a
72
74
  # 1-element chain, not a separate "just look in one hash" method.
@@ -75,12 +77,12 @@ module Hecks
75
77
  nil
76
78
  end
77
79
 
78
- # PRIMITIVE 2 — ONE pool keyed BY DECLARING OWNER,
80
+ # Primitive 2 — one pool keyed by declaring owner,
79
81
  # `Hash[description][owner] => Rule` — `AggregateBuilder#given`'s
80
82
  # own chapter-wide shape, the only construct so far where the
81
- # SAME description can mean two genuinely different predicates
83
+ # same description can mean two genuinely different predicates
82
84
  # (docs/implemented/resolution-rules/chapter-given.md). Returns the full
83
- # candidates Hash (0, 1, or many entries) — deliberately NOT
85
+ # candidates Hash (0, 1, or many entries) — deliberately not
84
86
  # raising here, so each caller keeps its own exact refusal
85
87
  # wording for "none," "ambiguous," and "declared_by: named the
86
88
  # wrong owner" rather than one generic message papering over all
@@ -89,10 +91,10 @@ module Hecks
89
91
  pool[description] || {}
90
92
  end
91
93
 
92
- # PRIMITIVE 3 — a LIVE SCAN over already-built SIBLING OBJECTS'
94
+ # Primitive 3 — a live scan over already-built sibling objects'
93
95
  # own collections, not a separately-maintained pool at all —
94
96
  # `ValueObjectBuilder#invariant`'s own shape: every sibling value
95
- # object on the same aggregate has ALREADY been built by the time
97
+ # object on the same aggregate has already been built by the time
96
98
  # a later one references back (declaration order, the same
97
99
  # constraint every scope in this family carries), so there is
98
100
  # nothing to write through — just read their own already-declared
@@ -105,36 +107,36 @@ module Hecks
105
107
  .find { |rule| rule.description == description }
106
108
  end
107
109
 
108
- # WHICH CONSTRUCT USES WHICH PRIMITIVE — no longer a Ruby-only
109
- # Hash (that WAS this constant's own shape, one round ago): the
110
+ # **Which construct uses which primitive** — no longer a Ruby-only
111
+ # Hash (that was this constant's own shape, one round ago): the
110
112
  # user's own correction — "my goal is that if they read the same
111
113
  # table they behave identically" — means a table only Ruby ever
112
114
  # reads cannot deliver that, no matter how faithfully it is
113
115
  # cross-checked afterward. `Keyword#resolves_via`/`#disambiguator`
114
- # (self-hosted, `syntax.bluebook`) is the REAL table now — the
115
- # SAME generated data `rust/parser/src/keywords.rs` is generated
116
+ # (self-hosted, `syntax.bluebook`) is the real table now — the
117
+ # same generated data `rust/parser/src/keywords.rs` is generated
116
118
  # from (`bin/project_parser_table`). `#lookup` reads it live.
117
119
  #
118
- # THE ONE UNAVOIDABLE EXCEPTION: the meta-domain's own bootstrap
120
+ # **The one unavoidable exception**: the meta-domain's own bootstrap
119
121
  # (`MetaValidator.load_grammar_into`) dispatches `given`/
120
- # `invariant` on ITSELF 61 times while building the very grammar
122
+ # `invariant` on itself 61 times while building the very grammar
121
123
  # table that would answer "how does given/Aggregate resolve" —
122
124
  # `MetaValidator.grammar_registry`/`SyntaxBoot.call` are not
123
- # ready yet, and cannot be made ready without ALREADY having
125
+ # ready yet, and cannot be made ready without already having
124
126
  # resolved a `given` somewhere upstream. `MetaValidator.
125
- # bootstrapping?` is the SAME guard `MetaValidator.call` (the
127
+ # bootstrapping?` is the same guard `MetaValidator.call` (the
126
128
  # judge) already uses to skip self-judging during this exact
127
129
  # window — `#lookup` uses it too, falling back to
128
- # `BOOTSTRAP_FALLBACK` (below) ONLY while it's true. Every REAL
130
+ # `BOOTSTRAP_FALLBACK` (below) only while it's true. Every real
129
131
  # domain (banking, pizzas, compliance, any future one) boots
130
- # AFTER `grammar_registry` is fully built and memoized, so reads
132
+ # after `grammar_registry` is fully built and memoized, so reads
131
133
  # the real table, every time, no exception.
132
- BOOTSTRAP_FALLBACK = {
133
- %w[given Aggregate] => { resolves_via: "owner_keyed", disambiguator: "declared_by" },
134
- %w[given Entity] => { resolves_via: "owner_keyed", disambiguator: "declared_by" },
135
- %w[given Command] => { resolves_via: "hash_chain" },
136
- %w[invariant ValueObject] => { resolves_via: "sibling_scan" }
137
- }.freeze
134
+ #
135
+ # No longer kept in sync by hand — the same `resolves_via`/
136
+ # `disambiguator` columns, projected ahead of time into the
137
+ # committed lib/hecks/bluebook/dsl/bootstrap_table.rb
138
+ # (bin/project_bootstrap_table, pinned by spec/bootstrap_table_spec.rb).
139
+ BOOTSTRAP_FALLBACK = BootstrapTable::RESOLVES
138
140
 
139
141
  def lookup(word, context)
140
142
  if MetaValidator.bootstrapping?
@@ -149,16 +151,16 @@ module Hecks
149
151
  end
150
152
  end
151
153
 
152
- # A LIVE CROSS-CHECK, not a spec-only one — every REAL domain's
154
+ # A live cross-check, not a spec-only one — every real domain's
153
155
  # own boot (not just `bundle exec rspec`) now genuinely fails
154
156
  # loudly if a construct's own hand-written resolution method
155
157
  # ever disagrees with what the self-hosted grammar table claims
156
158
  # for it. Each of the three `reference_named_*` methods below
157
- # calls this FIRST, naming the primitive it is ABOUT to use —
159
+ # calls this first, naming the primitive it is about to use —
158
160
  # if `syntax.bluebook`'s own `resolves_via` for this exact
159
161
  # (word, context) pair ever names something else, this is a
160
162
  # real drift between the language's own self-description and
161
- # its own implementation, caught at the next boot of ANYTHING,
163
+ # its own implementation, caught at the next boot of anything,
162
164
  # not just the next `rspec` run.
163
165
  def verify_resolves_via!(word, context, expected_primitive)
164
166
  actual = lookup(word, context)[:resolves_via]
@@ -28,10 +28,10 @@ module Hecks
28
28
  @backfills = []
29
29
  end
30
30
 
31
- # RENAMED FROM `rename`/`move`/`convert`/`retype`/`compute`/
31
+ # Renamed from `rename`/`move`/`convert`/`retype`/`compute`/
32
32
  # `rekey`/`backfill` (all seven below) — item #13's full
33
33
  # metaprogrammed dispatch (slice 4c). Not bootstrap-reachable
34
- # (translation.bluebook describes ITS OWN structure with
34
+ # (translation.bluebook describes its own structure with
35
35
  # aggregate/entity/attribute, never with these — they're
36
36
  # words for real, user-authored `.translation` files only,
37
37
  # loaded after the grammar table exists), so none need a
@@ -93,7 +93,7 @@ module Hecks
93
93
  @computes << TranslationCompute.new(old_path.to_s, to.to_s, sql.to_s)
94
94
  end
95
95
 
96
- # THE AGGREGATE'S OWN IDENTITY, changing what it's computed from —
96
+ # The aggregate's own identity, changing what it's computed from —
97
97
  # not a field crossing a boundary (`move`), not a value's own
98
98
  # transform (`compute`): the record's key. No path arguments,
99
99
  # unlike every rule above — nothing is consumed from or moved into
@@ -107,8 +107,8 @@ module Hecks
107
107
  @rekeys << TranslationRekey.new(sql.to_s)
108
108
  end
109
109
 
110
- # A NEWLY ADDED, required attribute — the addition-side sibling of
111
- # `drop`. Nothing to rename, move, or convert FROM, since old data
110
+ # A newly added, required attribute — the addition-side sibling of
111
+ # `drop`. Nothing to rename, move, or convert from, since old data
112
112
  # never held this field at all; `default` is what an existing
113
113
  # record reads until the next command against it writes a real
114
114
  # value. Adapter-agnostic, unlike `compute` — applied the same
@@ -128,11 +128,11 @@ module Hecks
128
128
  # The scaffold writes this where it cannot decide; a file carrying
129
129
  # one can only boot into this refusal — never a guess.
130
130
  #
131
- # RENAMED FROM `unresolved` — item #13's full metaprogrammed
131
+ # Renamed from `unresolved` — item #13's full metaprogrammed
132
132
  # dispatch (slice 4). Builds its own message with real branching
133
133
  # (empty vs. named candidates, a special :identity case), not a
134
134
  # fixed string a boolean `refuses:` flag could express — reached
135
- # through `calls:` instead, like `attribute`/`role`. NOT
135
+ # through `calls:` instead, like `attribute`/`role`. Not
136
136
  # bootstrap-reachable: translation.bluebook (loaded during
137
137
  # bootstrap, to describe the translation DSL itself) never
138
138
  # writes `unresolved` — that word is only ever used by real,
@@ -178,7 +178,7 @@ module Hecks
178
178
  path.to_s.include?(".") ? path.to_s.inspect : ":#{path}"
179
179
  end
180
180
 
181
- # THE SCAFFOLD'S OWN HINT for the one drift it can detect but never
181
+ # The scaffold's own hint for the one drift it can detect but never
182
182
  # resolve on its own — an aggregate's `identified_by` changed. Not
183
183
  # a field to rename/move/drop, so none of the ordinary hints fit;
184
184
  # `coverage_check.rb#check_identity_unchanged!` is the real gate,
@@ -211,7 +211,7 @@ module Hecks
211
211
  @retired = []
212
212
  end
213
213
 
214
- # RENAMED FROM `aggregate` — item #13's full metaprogrammed
214
+ # Renamed from `aggregate` — item #13's full metaprogrammed
215
215
  # dispatch (slice 4c). Not bootstrap-reachable — this "Translation"
216
216
  # -context `aggregate` (opens a TranslationAggregateBuilder) is a
217
217
  # different (context, word) pair than "Bluebook"-context
@@ -23,7 +23,7 @@ module Hecks
23
23
  @owner_value_objects = owner_value_objects
24
24
  end
25
25
 
26
- # THE WRAPPER BLOCK IS GONE (ADR 0025, "Attributes" — "closed sets
26
+ # The wrapper block is gone (ADR 0025, "Attributes" — "closed sets
27
27
  # lose the wrapper block"). `member` lines are bare now, written
28
28
  # directly in the `value_object` body with no `one_of do ... end`
29
29
  # around them — `build`'s own `closed_set: @closed_set ||
@@ -39,24 +39,24 @@ module Hecks
39
39
  # use the inline form on one of its own attributes. One `one_of`
40
40
  # method now, not two.
41
41
  #
42
- # LEGACY UNDER SHADOW-PARSING (S0a's own bridge) — frozen era text
42
+ # Legacy under shadow-parsing (S0a's own bridge) — frozen era text
43
43
  # still writes the block form (2 locations in
44
44
  # `examples/banking/data/eras/banking/1.bluebook`, duplicated once
45
45
  # more in that era's own archive copy), so `EraGuard.shadow_parse`
46
46
  # still needs to read it. `block_given?` is what tells the two
47
47
  # calling shapes apart: the type-position form
48
48
  # (`one_of("a", "b")`) never passes a block, only the wrapper does.
49
- # RENAMED FROM `one_of` — item #13's full metaprogrammed dispatch
50
- # (slice 5). SAME NAME as `AttributeCollector#one_of_impl`'s own
49
+ # Renamed from `one_of` — item #13's full metaprogrammed dispatch
50
+ # (slice 5). Same name as `AttributeCollector#one_of_impl`'s own
51
51
  # — required for the `super(*values)` call below to keep
52
52
  # resolving; see that method's own comment. Reached directly
53
53
  # through its own "ValueObject"-context Keyword row (the
54
54
  # block-wrapper form has its own row, distinct from "Type"'s),
55
- # not through the Type-position fallback this word's OTHER
55
+ # not through the Type-position fallback this word's other
56
56
  # context uses.
57
57
  def one_of_impl(*values, &block)
58
58
  unless block
59
- # NO VALUES, NO BLOCK is the SCALAR spelling — nonsensical, not
59
+ # No values, no block is the scalar spelling — nonsensical, not
60
60
  # merely inert: it names a closed set with nothing in it. The
61
61
  # original block form caught this by a side effect (`@closed_set
62
62
  # = true` ran unconditionally, before the `if block`), and this
@@ -83,7 +83,7 @@ module Hecks
83
83
  instance_eval(&block)
84
84
  end
85
85
 
86
- # RENAMED FROM `member` — item #13's full metaprogrammed dispatch
86
+ # Renamed from `member` — item #13's full metaprogrammed dispatch
87
87
  # (slice 4c). Bootstrap-reachable, in
88
88
  # GenericDispatch::BOOTSTRAP_CALLS_FALLBACK.
89
89
  def member_impl(**fields)
@@ -92,11 +92,11 @@ module Hecks
92
92
  @members << fields
93
93
  end
94
94
 
95
- # NO BLOCK is a REFERENCE, not a fresh declaration — the same
95
+ # No block is a reference, not a fresh declaration — the same
96
96
  # move S10 already made for `CommandBuilder#given` (ADR 0025,
97
97
  # "a precondition shared across commands is declared once... a
98
98
  # command references it by name"), one level over: a rule
99
- # shared across SIBLING value objects on the same aggregate,
99
+ # shared across sibling value objects on the same aggregate,
100
100
  # declared once, on the first one to need it. Real, live
101
101
  # redundancy this closes: `Account`'s own `Money`/`PositiveMoney`
102
102
  # both declared `invariant("a currency is a three-letter code")
@@ -105,7 +105,7 @@ module Hecks
105
105
  # the referencing value object's own build time, against
106
106
  # whatever sibling value objects the aggregate has already
107
107
  # built, the same ordering rule `given` carries.
108
- # RENAMED FROM `invariant` — item #13's full metaprogrammed
108
+ # Renamed from `invariant` — item #13's full metaprogrammed
109
109
  # dispatch (slice 4b). Bootstrap-reachable, in
110
110
  # GenericDispatch::BOOTSTRAP_CALLS_FALLBACK.
111
111
  def invariant_impl(description, &predicate)
@@ -119,7 +119,7 @@ module Hecks
119
119
 
120
120
  private
121
121
 
122
- # PRIMITIVE 3 (RuleReference#resolve_sibling_scan) — see that
122
+ # Primitive 3 (RuleReference#resolve_sibling_scan) — see that
123
123
  # method's own comment for why this is a live scan, not a pool.
124
124
  def reference_named_invariant(description)
125
125
  verify_resolves_via!("invariant", "ValueObject", "sibling_scan")
@@ -157,15 +157,15 @@ module Hecks
157
157
 
158
158
  private
159
159
 
160
- # THE NEW SPELLING — `attribute :name, String, one_of: %w[...]`,
161
- # overriding `AttributeCollector`'s own refusal (every OTHER
162
- # includer has no meaningful use for this). PRIVATE, like the
160
+ # **The new spelling** — `attribute :name, String, one_of: %w[...]`,
161
+ # overriding `AttributeCollector`'s own refusal (every other
162
+ # includer has no meaningful use for this). Private, like the
163
163
  # module's own version it overrides — it is a callback `attribute`
164
164
  # invokes on itself, never a word a bluebook author calls by name.
165
- # Refuses a SECOND attribute naming one_of: on the same value
165
+ # Refuses a second attribute naming one_of: on the same value
166
166
  # object outright — a single-field set names exactly one field, by
167
167
  # construction; two would be structurally ambiguous about which
168
- # field each member line belongs to. `build` refuses the OTHER
168
+ # field each member line belongs to. `build` refuses the other
169
169
  # half of that same rule (this attribute coexisting with unrelated
170
170
  # ones on a multi-field object).
171
171
  def install_inline_closed_set(field, values)
@@ -2,46 +2,49 @@ require_relative "generic_dispatch"
2
2
  module Hecks
3
3
  module Bluebook
4
4
  module DSL
5
- # THE RUBY-SIDE `word_gate` (`rust/parser/src/parse/mod.rs`'s own,
5
+ # The Ruby-side `word_gate` (`rust/parser/src/parse/mod.rs`'s own,
6
6
  # read there first — this is the same job, one level up: Rust's own
7
- # gate refuses a mistyped/inadmissible WORD directly, at the
8
- # moment it reads a line of `.bluebook` SOURCE TEXT, before any
7
+ # gate refuses a mistyped/inadmissible word directly, at the
8
+ # moment it reads a line of `.bluebook` source text, before any
9
9
  # per-construct parsing runs. Ruby never lexes source text — a
10
- # `.bluebook` file IS Ruby, so `given("x")` is ALREADY a real
10
+ # `.bluebook` file is Ruby, so `given("x")` is already a real
11
11
  # method call by the time any of this code runs, and Ruby's own
12
- # method dispatch already refuses an ARITY mismatch on an
13
- # EXISTING method for free. What Ruby's own dispatch does NOT do
14
- # is consult the self-hosted grammar table AT ALL — a mistyped
12
+ # method dispatch already refuses an arity mismatch on an
13
+ # existing method for free. What Ruby's own dispatch does not do
14
+ # is consult the self-hosted grammar table at all — a mistyped
15
15
  # word (`giv3n("x")`) or a word used in the wrong context
16
16
  # (`identified_by` inside a `command` block) just raises Ruby's
17
17
  # own generic `NoMethodError`, naming nothing about what the
18
18
  # language actually admits. This module closes that gap.
19
19
  #
20
- # `method_missing`/`respond_to_missing?` ONLY a word this
20
+ # ## What reaches this module
21
+ #
22
+ # `method_missing`/`respond_to_missing?` only — a word this
21
23
  # builder class already answers with an ordinary `def` (or a
22
- # shared mixin method like `AttributeCollector#attribute`) never
24
+ # method a shared mixin such as `AttributeCollector` defines) never
23
25
  # reaches this module at all; Ruby's own method lookup finds it
24
- # first, and item #13's later slices haven't removed every one of
25
- # those yet. This WAS "zero behavior change for every currently-
26
- # valid line in the entire corpus" in its own first slice — since
27
- # item #13's full metaprogrammed dispatch (slice 1, whole-project
28
- # table-unification survey) started REMOVING the hand-written
29
- # methods this module's own admissibility check used to defer to,
30
- # some words now execute for real here too, via `GenericDispatch`
31
- # see that module's own header for exactly which ones, and the
32
- # full account of what was verified before each was migrated. A
33
- # mistyped or wrongly-contexted word still gets the same real,
34
- # helpful, table-driven refusal Rust's own `word_gate` already
35
- # gives, instead of Ruby's own generic `NoMethodError` — that half
36
- # is genuinely unchanged.
26
+ # first, and not every word has had its hand-written method
27
+ # removed. A word the grammar admits whose builder has no
28
+ # hand-written method executes for real here, via `GenericDispatch`
29
+ # (item #13's full metaprogrammed dispatch, whole-project
30
+ # table-unification survey) see that module's own header for
31
+ # exactly which ones, and the full account of what was verified
32
+ # before each was migrated. A mistyped or wrongly-contexted word
33
+ # gets the same real, helpful, table-driven refusal Rust's own
34
+ # `word_gate` already gives, instead of Ruby's own generic
35
+ # `NoMethodError`.
36
+ #
37
+ # ## `GRAMMAR_CONTEXT`
37
38
  #
38
39
  # `self.class::GRAMMAR_CONTEXT` — each including class names which
39
40
  # row of the self-hosted `Context` closed set it corresponds to
40
41
  # (`AggregateBuilder::GRAMMAR_CONTEXT = "Aggregate"`, etc.) — the
41
- # SAME string `word_gate`'s own `context` parameter already is on
42
+ # same string `word_gate`'s own `context` parameter already is on
42
43
  # the Rust side, read off the identical table.
43
44
  #
44
- # BOOTSTRAPPING GATED, the same reason `RuleReference#lookup`
45
+ # ## Bootstrapping
46
+ #
47
+ # Bootstrapping gated, the same reason `RuleReference#lookup`
45
48
  # already is (`rule_reference.rb`'s own comment has the full
46
49
  # story) — the meta-domain's own bootstrap calls dozens of
47
50
  # keywords on itself before its own grammar table exists to
@@ -52,28 +55,31 @@ module Hecks
52
55
  # is deliberately no fallback covering the whole ~200-row table —
53
56
  # that would defeat the entire point.
54
57
  #
55
- # ONE NARROW EXCEPTION, added in item #13's full metaprogrammed
56
- # dispatch (slice 3, whole-project table-unification survey):
57
- # `GenericDispatch::BOOTSTRAP_CALLS_FALLBACK`, a SMALL, EXPLICIT
58
- # table naming the same (context, word) -> method pairs the real
59
- # `calls:` column would say once it exists used ONLY for words
60
- # BOTH migrated to the `calls:` shape AND bootstrap-reachable
61
- # (`attribute`, today). This is the one place in this whole arc a
58
+ # One narrow exception (item #13's full metaprogrammed dispatch,
59
+ # slice 3, whole-project table-unification survey):
60
+ # `GenericDispatch::BOOTSTRAP_CALLS_FALLBACK`, an explicit table
61
+ # naming the same (context, word) -> method pairs the real
62
+ # `calls:` column carries, projected ahead of time into the
63
+ # committed `bootstrap_table.rb` it matters only for words both
64
+ # migrated to the `calls:` shape and bootstrap-reachable
65
+ # (`attribute`, for one). This is the one place in this whole arc a
62
66
  # bootstrap fallback was worth building despite `RuleReference`'s
63
- # own precedent against it: it duplicates NO logic, only a METHOD
64
- # NAME — `attribute_impl`'s own real, hand-written body is called
67
+ # own precedent against it: it duplicates no logic, only a method
68
+ # name — `attribute_impl`'s own real, hand-written body is called
65
69
  # either way, bootstrap or not, so there is nothing here that can
66
70
  # drift the way a full behavioral duplicate could.
67
71
  #
68
- # TWO FURTHER PIECES, both slice 5:
72
+ # ## `word_gate_dispatch` and the type-position fallback
73
+ #
74
+ # Two further pieces, both slice 5:
69
75
  # - `word_gate_dispatch` is the same admission+dispatch logic
70
76
  # `method_missing` below runs, factored out so a class with
71
- # its OWN class-level `method_missing` (`HecksagonBuilder`'s/
77
+ # its own class-level `method_missing` (`HecksagonBuilder`'s/
72
78
  # `WorldBuilder`'s genuinely open-ended verb vocabulary) can
73
79
  # call it directly and fall back to its own open-verb handling
74
80
  # only when this returns `NOT_ADMITTED` — a class-level `def`
75
81
  # always wins over an included module's in Ruby's own method
76
- # resolution, so their OWN `method_missing` is the only one
82
+ # resolution, so their own `method_missing` is the only one
77
83
  # that ever runs for them, and this is what lets a real,
78
84
  # closed-set word (`port`/`realm`/`latest`) still reach
79
85
  # `GenericDispatch` despite that.
@@ -84,7 +90,7 @@ module Hecks
84
90
  # "Type" builder `self.class::GRAMMAR_CONTEXT` could ever
85
91
  # name. See that method's own comment.
86
92
  module WordGate
87
- # A caller with its OWN class-level `method_missing`
93
+ # A caller with its own class-level `method_missing`
88
94
  # (`HecksagonBuilder`/`WorldBuilder` — see `word_gate_dispatch`'s
89
95
  # own header) checks for this to tell "not a word the grammar
90
96
  # admits at all" apart from every other outcome below (a real
@@ -92,7 +98,7 @@ module Hecks
92
98
  # caller can fall through to its own open-ended handling instead.
93
99
  NOT_ADMITTED = Object.new.freeze
94
100
 
95
- # PRIVATE, matching Ruby's own convention for both (`Object`
101
+ # Private, matching Ruby's own convention for both (`Object`
96
102
  # defines them private too) — and load-bearing here, not just
97
103
  # style: `spec/syntax_conformance_spec.rb`'s "declares every
98
104
  # word X answers" check walks `public_instance_methods`, and a
@@ -129,23 +135,23 @@ module Hecks
129
135
  result
130
136
  end
131
137
 
132
- # THE CORE ADMISSION+DISPATCH LOGIC, factored out of
138
+ # The core admission+dispatch logic, factored out of
133
139
  # `method_missing` — item #13's full metaprogrammed dispatch
134
140
  # (slice 5, whole-project table-unification survey) — so a
135
- # class with its OWN class-level `method_missing`
141
+ # class with its own class-level `method_missing`
136
142
  # (`HecksagonBuilder`'s/`WorldBuilder`'s genuinely open-ended
137
143
  # verb vocabulary, `persisted_by "Heki"`/`posted_by "Carrier"`,
138
- # can never BE a closed table) can still route a word THE
139
- # GRAMMAR ADMITS through here first, falling back to its own
144
+ # can never be a closed table) can still route a word the
145
+ # grammar admits through here first, falling back to its own
140
146
  # open-verb handling only for what this doesn't recognize at
141
147
  # all — unblocking `Hecksagon#port`/`World#realm`/`World#latest`,
142
148
  # each a real, closed-set word that happened to sit on a class
143
149
  # whose own `method_missing` a class-level `def` always wins
144
150
  # over Ruby's own module-inclusion order.
145
151
  #
146
- # NEVER RAISES "not admitted" — returns `NOT_ADMITTED` instead,
152
+ # Never raises "not admitted" — returns `NOT_ADMITTED` instead,
147
153
  # so the caller (this module's own `method_missing`, or one of
148
- # the two above) decides what that means for it. DOES still
154
+ # the two above) decides what that means for it. Does still
149
155
  # raise the richer, table-driven refusals below once a word is
150
156
  # admitted-but-unimplemented, or admitted-somewhere-else-only —
151
157
  # those are real, useful refusals regardless of which
@@ -161,16 +167,16 @@ module Hecks
161
167
  keywords = rows[:keywords]
162
168
  admitted = keywords.select { |row| row[:context] == context && (row[:word] == word.to_s || row[:was] == word.to_s) }
163
169
 
164
- # THE TYPE-POSITION FALLBACK — item #13's full metaprogrammed
170
+ # **The type-position fallback** — item #13's full metaprogrammed
165
171
  # dispatch (slice 5). `one_of`/`list_of`, called inside an
166
172
  # attribute's own type argument (`attribute :x,
167
173
  # one_of("a","b")`), run with `self` as whatever builder is
168
- # CURRENTLY instance_eval'ing — there is no dedicated "Type"
174
+ # currently instance_eval'ing — there is no dedicated "Type"
169
175
  # builder of its own; every attribute()-taking builder answers
170
176
  # these identically, through the shared `AttributeCollector`
171
- # mixin. `self.class::GRAMMAR_CONTEXT` can never actually BE
177
+ # mixin. `self.class::GRAMMAR_CONTEXT` can never actually be
172
178
  # "Type", so a word admitted only there would otherwise look
173
- # inadmissible everywhere. Checked only once THIS context has
179
+ # inadmissible everywhere. Checked only once this context has
174
180
  # already come up empty, so a context with its own same-named
175
181
  # row (`ValueObject`'s own `one_of`, the block-wrapper form)
176
182
  # keeps using that instead, unaffected.
@@ -190,11 +196,11 @@ module Hecks
190
196
  "'#{word}' is not a word #{context} admits — legal words here: #{legal.join(', ')}"
191
197
  end
192
198
 
193
- # ITEM #13's FULL METAPROGRAMMED DISPATCH — the word IS
199
+ # Item #13's full metaprogrammed dispatch — the word is
194
200
  # admitted here, and this builder has no hand-written method
195
201
  # left for it; before falling through to the "not yet
196
202
  # implemented" refusal every word without one still gets,
197
- # offer it to GenericDispatch — the SAFE, verified subset of
203
+ # offer it to GenericDispatch — the safe, verified subset of
198
204
  # words whose whole behavior is now executed off this same
199
205
  # table, not just checked against it.
200
206
  dispatched = GenericDispatch.try(self, context, word.to_s, args, kwargs, block, rows)
@@ -215,13 +221,13 @@ module Hecks
215
221
  super
216
222
  end
217
223
 
218
- # A word admitted SOMEWHERE, just not in THIS context, still
224
+ # A word admitted somewhere, just not in this context, still
219
225
  # falls through to Ruby's own `NoMethodError` rather than this
220
226
  # module's own richer refusal — `method_missing` fires for
221
227
  # every typo in the whole codebase (this class's own genuinely
222
228
  # private helper methods included), not just DSL keyword calls;
223
- # only raise the RICH, table-driven message when the word is at
224
- # least SOMETHING the grammar knows about, anywhere, so an
229
+ # only raise the rich, table-driven message when the word is at
230
+ # least something the grammar knows about, anywhere, so an
225
231
  # unrelated Ruby-level typo inside a builder's own private code
226
232
  # keeps its own ordinary, unconfusing `NoMethodError`.
227
233
  def admitted_anywhere?(rows, word)